diff --git a/.gitignore b/.gitignore index 40b6436..73adcb8 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ next-env.d.ts # intellij .idea/ + +schema.graphql diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1568b35..bef1b1e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,4 @@ stages: - - lint - build .node: @@ -7,13 +6,6 @@ stages: before_script: - npm ci -lint: - extends: - - .node - stage: lint - script: - - npm run lint - build: extends: - .node diff --git a/README.md b/README.md index e215bc4..e0e51ff 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ bun dev Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. +You can start editing the page by modifying `app/page.ts`. The page auto-updates as you edit the file. This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. diff --git a/graphql-imports.d.ts b/graphql-imports.d.ts new file mode 100644 index 0000000..58aebd5 --- /dev/null +++ b/graphql-imports.d.ts @@ -0,0 +1 @@ +declare module '*.graphql' \ No newline at end of file diff --git a/graphql.config.yml b/graphql.config.yml new file mode 100644 index 0000000..dab2828 --- /dev/null +++ b/graphql.config.yml @@ -0,0 +1,6 @@ +schema: schema.graphql +documents: '**/*.graphql' +extensions: + endpoints: + Default GraphQL Endpoint: + url: http://localhost:3001/graphql diff --git a/next.config.ts b/next.config.ts index 3779390..93e0657 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,13 +1,63 @@ -import type { NextConfig } from "next"; +import type {NextConfig} from "next"; import path from "node:path"; + const EDITION = process.env.EDITION ?? "ce"; +const cspHeader = ` + default-src 'self'; + script-src 'self' 'unsafe-eval' 'unsafe-inline'; + style-src 'self' 'unsafe-inline'; + img-src 'self' blob: data:; + font-src 'self'; + object-src 'none'; + base-uri 'self'; + form-action 'self'; + frame-ancestors 'none'; +` + const nextConfig: NextConfig = { + async headers() { + return [ + { + source: '/(.*)', + headers: [ + { + key: 'Content-Security-Policy', + value: cspHeader.replace(/\n/g, ''), + }, + { + key: "X-Frame-Options", + value: "DENY" + } + ], + }, + ] + }, + env: { + NEXT_PUBLIC_edition: EDITION, + NEXT_PUBLIC_pictorVersion: "11" + }, + reactStrictMode: true, + reactCompiler: true, turbopack: { resolveAlias: { "@edition": path.resolve(__dirname, `src/packages/${EDITION}/src`), "@core": path.resolve(__dirname, "src/packages/core/src"), }, + rules: { + "*.graphql": { + loaders: ["graphql-tag/loader"], + as: "*.js" + }, + }, + }, + rewrites: () => { + return [ + { + source: '/graphql', + destination: 'http://localhost:3001/graphql' // Proxy to Backend + } + ]; } }; diff --git a/package-lock.json b/package-lock.json index c086284..66c1e11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,19 +8,203 @@ "name": "my-app", "version": "0.1.0", "dependencies": { + "@apollo/client": "^4.0.9", + "@code0-tech/pictor": "^0.0.0-mvp.14", + "graphql": "^16.12.0", + "graphql-tag": "^2.12.6", "next": "16.0.1", "react": "19.2.0", - "react-dom": "19.2.0" + "react-dom": "19.2.0", + "rxjs": "^7.8.2", + "sass": "^1.93.3" }, "devDependencies": { "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "babel-plugin-react-compiler": "^1.0.0", "eslint": "^9", "eslint-config-next": "16.0.1", "typescript": "^5" } }, + "../pictor": { + "name": "@code0-tech/pictor", + "version": "0.0.0", + "extraneous": true, + "dependencies": { + "@code0-tech/definition-reader": "^0.0.16" + }, + "devDependencies": { + "@ariakit/react": "^0.4.17", + "@babel/plugin-proposal-decorators": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@code0-tech/sagittarius-graphql-types": "^0.0.0-65144a9920c6a8de3bcf24acdcb8eec4158cef73", + "@dagrejs/dagre": "^1.1.5", + "@mdx-js/react": "^3.1.1", + "@radix-ui/react-checkbox": "^1.3.3", + "@radix-ui/react-dialog": "^1.1.15", + "@radix-ui/react-dropdown-menu": "^2.1.16", + "@radix-ui/react-one-time-password-field": "^0.1.8", + "@radix-ui/react-radio-group": "^1.3.8", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-tabs": "^1.1.13", + "@radix-ui/react-toggle-group": "^1.1.11", + "@radix-ui/react-tooltip": "^1.2.8", + "@rollup/plugin-commonjs": "^28.0.9", + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^0.4.4", + "@rollup/plugin-typescript": "^12.3.0", + "@storybook/addon-a11y": "^10.0.4", + "@storybook/addon-links": "^10.0.4", + "@storybook/addon-onboarding": "^10.0.4", + "@storybook/builder-vite": "^10.0.4", + "@storybook/cli": "^10.0.4", + "@storybook/react": "^10.0.4", + "@storybook/react-vite": "^10.0.4", + "@storybook/test-runner": "^0.24.1", + "@storybook/testing-library": "^0.2.2", + "@tabler/icons-react": "3.35.0", + "@types/jest-image-snapshot": "^6.4.0", + "@types/react": "^19.2.2", + "@vitejs/plugin-react": "^5.1.0", + "@xyflow/react": "^12.9.2", + "axe-playwright": "^2.2.2", + "babel-loader": "^10.0.0", + "babel-plugin-react-compiler": "^19.1.0-rc.3", + "cmdk": "^1.1.1", + "concurrently": "^9.2.1", + "css-loader": "^7.1.2", + "html-webpack-plugin": "^5.6.4", + "identity-obj-proxy": "^3.0.0", + "jest-image-snapshot": "^6.5.1", + "js-md5": "^0.8.3", + "merge-props": "^6.0.0", + "overlap-area": "^1.1.0", + "playwright": "1.55.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "react-resizable-panels": "^3.0.6", + "react-zoom-pan-pinch": "^3.7.0", + "rimraf": "^6.1.0", + "sass": "^1.93.3", + "sass-loader": "^16.0.6", + "storybook": "^10.0.4", + "style-loader": "^4.0.0", + "ts-jest": "^29.4.5", + "ts-node": "^10.9.2", + "typescript": "^5.9.3", + "vite": "^7.2.1", + "vite-plugin-dts": "^4.5.4", + "vite-plugin-lib-inject-css": "^2.2.2" + }, + "peerDependencies": { + "@ariakit/react": "^0.4.5", + "@code0-tech/sagittarius-graphql-types": "^0.0.0-65144a9920c6a8de3bcf24acdcb8eec4158cef73", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-one-time-password-field": "^0.1.7", + "@radix-ui/react-radio-group": "^1.3.7", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-tabs": "^1.1.12", + "@radix-ui/react-toggle-group": "^1.1.10", + "@radix-ui/react-tooltip": "^1.2.8", + "@tabler/icons-react": "^3.5.0", + "@xyflow/react": "^12.8.2", + "cmdk": "^1.1.1", + "js-md5": "^0.8.3", + "merge-props": "^6.0.0", + "overlap-area": "^1.1.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0", + "react-resizable-panels": "^3.0.3", + "react-zoom-pan-pinch": "^3.6.1" + } + }, + "node_modules/@apollo/client": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-4.0.9.tgz", + "integrity": "sha512-Lh2drMzFE9x5jVS8RKmlGL5SORkvpyUJIT+wTErxDUR2HpWePiBfhhcHHRSlZFiCR866ewCv4euTc4IDF0GWxw==", + "license": "MIT", + "workspaces": [ + "dist", + "codegen", + "scripts/codemods/ac3-to-ac4" + ], + "dependencies": { + "@graphql-typed-document-node/core": "^3.1.1", + "@wry/caches": "^1.0.0", + "@wry/equality": "^0.5.6", + "@wry/trie": "^0.5.0", + "graphql-tag": "^2.12.6", + "optimism": "^0.18.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "graphql": "^16.0.0", + "graphql-ws": "^5.5.5 || ^6.0.3", + "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc", + "react-dom": "^17.0.0 || ^18.0.0 || >=19.0.0-rc", + "rxjs": "^7.3.0", + "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" + }, + "peerDependenciesMeta": { + "graphql-ws": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "subscriptions-transport-ws": { + "optional": true + } + } + }, + "node_modules/@ariakit/core": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@ariakit/core/-/core-0.4.16.tgz", + "integrity": "sha512-nPJ0Be8d5ZvRApYGqdLMuYUjP7ktkPmTPOXyZFw+0Illk8LKgF3Q74ctVGuoQurJNDsANXcewzlyXK4vyIAGTA==", + "license": "MIT", + "peer": true + }, + "node_modules/@ariakit/react": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/@ariakit/react/-/react-0.4.19.tgz", + "integrity": "sha512-n6q8leSQWXMk4vhcZlpnj8cIlAY0n+1bvVTwHvaVfmec4LjW49MFKkJRZd1AiV+SE73nkxPwSL3IbaS4p1aRxQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ariakit/react-core": "0.4.19" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ariakit" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@ariakit/react-core": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/@ariakit/react-core/-/react-core-0.4.19.tgz", + "integrity": "sha512-Aj+fu4pMyPXtlBghI+E7KSWItqJkbAqEhut3DlsFAjK9fQdHE+e1tQJG1PtnoEdD9BExkJWQ6R4M5a9HkEhqPA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@ariakit/core": "0.4.16", + "@floating-ui/dom": "^1.0.0", + "use-sync-external-store": "^1.2.0" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", @@ -52,7 +236,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -158,7 +341,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -168,7 +351,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -252,7 +435,7 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -262,6 +445,48 @@ "node": ">=6.9.0" } }, + "node_modules/@code0-tech/pictor": { + "version": "0.0.0-mvp.14", + "resolved": "https://registry.npmjs.org/@code0-tech/pictor/-/pictor-0.0.0-mvp.14.tgz", + "integrity": "sha512-dTTFv2qm2sAiZw4axWJWZyJfUbzi4h8ZwHDnrflOKZ/JVlztkF2ONRpXsOwEAXnGSohhNBaU5MJWUjtGRw3Vww==", + "peerDependencies": { + "@ariakit/react": "^0.4.5", + "@code0-tech/sagittarius-graphql-types": "^0.0.0-65144a9920c6a8de3bcf24acdcb8eec4158cef73", + "@radix-ui/react-checkbox": "^1.3.2", + "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dropdown-menu": "^2.1.15", + "@radix-ui/react-one-time-password-field": "^0.1.7", + "@radix-ui/react-radio-group": "^1.3.7", + "@radix-ui/react-scroll-area": "^1.2.10", + "@radix-ui/react-tabs": "^1.1.12", + "@radix-ui/react-toggle-group": "^1.1.10", + "@radix-ui/react-tooltip": "^1.2.8", + "@tabler/icons-react": "^3.5.0", + "@xyflow/react": "^12.8.2", + "cmdk": "^1.1.1", + "js-md5": "^0.8.3", + "merge-props": "^6.0.0", + "overlap-area": "^1.1.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0", + "react-resizable-panels": "^3.0.3", + "react-zoom-pan-pinch": "^3.6.1", + "sonner": "^2.0.7" + } + }, + "node_modules/@code0-tech/sagittarius-graphql-types": { + "version": "0.0.0-65144a9920c6a8de3bcf24acdcb8eec4158cef73", + "resolved": "https://registry.npmjs.org/@code0-tech/sagittarius-graphql-types/-/sagittarius-graphql-types-0.0.0-65144a9920c6a8de3bcf24acdcb8eec4158cef73.tgz", + "integrity": "sha512-MZZHi02S0Q3qmNkbigN9aq7j1KcEc62aoSKrjWVUoUYoaLMLa60lHda3cb0/D4Fes+zvNyLnAogdaO7Mjos8Vg==", + "peer": true + }, + "node_modules/@daybrush/utils": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@daybrush/utils/-/utils-1.13.0.tgz", + "integrity": "sha512-ALK12C6SQNNHw1enXK+UO8bdyQ+jaWNQ1Af7Z3FNxeAwjYhQT7do+TRE4RASAJ3ObaS2+TJ7TXR3oz2Gzbw0PQ==", + "license": "MIT", + "peer": true + }, "node_modules/@emnapi/core": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.0.tgz", @@ -439,6 +664,57 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", + "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@floating-ui/dom": "^1.7.4" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT", + "peer": true + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1174,192 +1450,1497 @@ "node": ">=12.4.0" } }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.8.0" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.19.24", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz", - "integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/react": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", - "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.2", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", - "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz", - "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.46.3", - "@typescript-eslint/type-utils": "8.46.3", - "@typescript-eslint/utils": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 10.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/parcel" }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.46.3", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">= 4" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@typescript-eslint/parser": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz", - "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", - "dev": true, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "8.46.3", - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/typescript-estree": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3", - "debug": "^4.3.4" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 10.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "url": "https://opencollective.com/parcel" } }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", - "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", - "dev": true, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.46.3", - "@typescript-eslint/types": "^8.46.3", - "debug": "^4.3.4" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 10.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "url": "https://opencollective.com/parcel" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", - "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", - "dev": true, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 10.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/parcel" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", + "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", + "license": "MIT", + "peer": true + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT", + "peer": true + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", + "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-checkbox": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", + "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", + "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.16.tgz", + "integrity": "sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-menu": "2.1.16", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", + "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.16.tgz", + "integrity": "sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", + "@radix-ui/react-focus-scope": "1.1.7", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "aria-hidden": "^1.2.4", + "react-remove-scroll": "^2.6.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-one-time-password-field": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.1.8.tgz", + "integrity": "sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-is-hydrated": "0.1.0", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", + "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", + "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-slot": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-radio-group": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", + "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-use-previous": "1.1.1", + "@radix-ui/react-use-size": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", + "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-collection": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.10.tgz", + "integrity": "sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/number": "1.1.1", + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", + "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", + "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", + "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", + "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-direction": "1.1.1", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-roving-focus": "1.1.11", + "@radix-ui/react-toggle": "1.1.10", + "@radix-ui/react-use-controllable-state": "1.2.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-id": "1.1.1", + "@radix-ui/react-popper": "1.2.8", + "@radix-ui/react-portal": "1.1.9", + "@radix-ui/react-presence": "1.1.5", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-slot": "1.2.3", + "@radix-ui/react-use-controllable-state": "1.2.2", + "@radix-ui/react-visually-hidden": "1.2.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-use-effect-event": "0.0.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.0.tgz", + "integrity": "sha512-U+UORVEq+cTnRIaostJv9AGdV3G6Y+zbVd+12e18jQ5A3c0xL03IhnHuiU4UV69wolOQp5GfR58NW/EgdQhwOA==", + "license": "MIT", + "peer": true, + "dependencies": { + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", + "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-primitive": "2.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", + "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", + "license": "MIT", + "peer": true + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tabler/icons": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.35.0.tgz", + "integrity": "sha512-yYXe+gJ56xlZFiXwV9zVoe3FWCGuZ/D7/G4ZIlDtGxSx5CGQK110wrnT29gUj52kEZoxqF7oURTk97GQxELOFQ==", + "license": "MIT", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.35.0.tgz", + "integrity": "sha512-XG7t2DYf3DyHT5jxFNp5xyLVbL4hMJYJhiSdHADzAjLRYfL7AnjlRfiHDHeXxkb2N103rEIvTsBRazxXtAUz2g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@tabler/icons": "3.35.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz", + "integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz", + "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/type-utils": "8.46.3", + "@typescript-eslint/utils": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.3", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz", + "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", + "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.3", + "@typescript-eslint/types": "^8.46.3", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", + "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.46.3", "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", @@ -1824,13 +3405,94 @@ "win32" ] }, + "node_modules/@wry/caches": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz", + "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/context": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz", + "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/equality": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz", + "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wry/trie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz", + "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@xyflow/react": { + "version": "12.9.2", + "resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.9.2.tgz", + "integrity": "sha512-Xr+LFcysHCCoc5KRHaw+FwbqbWYxp9tWtk1mshNcqy25OAPuaKzXSdqIMNOA82TIXF/gFKo0Wgpa6PU7wUUVqw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@xyflow/system": "0.0.72", + "classcat": "^5.0.3", + "zustand": "^4.4.0" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.72", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.72.tgz", + "integrity": "sha512-WBI5Aau0fXTXwxHPzceLNS6QdXggSWnGjDtj/gG669crApN8+SCmEtkBth1m7r6pStNo/5fI9McEi7Dk0ymCLA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/d3-drag": "^3.0.7", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-selection": "^3.0.10", + "@types/d3-transition": "^3.0.8", + "@types/d3-zoom": "^3.0.8", + "d3-drag": "^3.0.0", + "d3-interpolate": "^3.0.1", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1888,6 +3550,19 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/aria-hidden": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", + "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/aria-query": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", @@ -2111,6 +3786,16 @@ "node": ">= 0.4" } }, + "node_modules/babel-plugin-react-compiler": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz", + "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2143,7 +3828,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -2172,7 +3857,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -2284,12 +3968,51 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT", + "peer": true + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, + "node_modules/cmdk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", + "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", + "license": "MIT", + "peer": true, + "dependencies": { + "@radix-ui/react-compose-refs": "^1.1.1", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-id": "^1.1.0", + "@radix-ui/react-primitive": "^2.0.2" + }, + "peerDependencies": { + "react": "^18 || ^19 || ^19.0.0-rc", + "react-dom": "^18 || ^19 || ^19.0.0-rc" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2297,54 +4020,168 @@ "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "peer": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "peer": true, + "dependencies": { + "d3-color": "1 - 3" }, "engines": { - "node": ">=7.0.0" + "node": ">=12" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "peer": true, + "engines": { + "node": ">=12" + } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "peer": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": ">= 8" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true, - "license": "MIT" + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "peer": true, + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } }, "node_modules/damerau-levenshtein": { "version": "1.0.8", @@ -2478,6 +4315,13 @@ "node": ">=8" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT", + "peer": true + }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -2726,7 +4570,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2912,7 +4755,6 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -3224,7 +5066,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -3373,6 +5215,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -3481,6 +5333,30 @@ "dev": true, "license": "MIT" }, + "node_modules/graphql": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz", + "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/graphql-tag": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz", + "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -3602,6 +5478,12 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -3806,7 +5688,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3852,7 +5734,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -3891,7 +5773,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -4091,6 +5973,13 @@ "node": ">= 0.4" } }, + "node_modules/js-md5": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.8.3.tgz", + "integrity": "sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==", + "license": "MIT", + "peer": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4274,6 +6163,13 @@ "node": ">= 0.4" } }, + "node_modules/merge-props": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/merge-props/-/merge-props-6.0.0.tgz", + "integrity": "sha512-ORZFZMGKE5PuAi7YfVCfPz3jiS9V0t2XXE2AGYiwMrcudRuj0hkXKEzsl17pUF07r+Digf9YlTzteX2LFE6vAQ==", + "license": "MIT", + "peer": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4288,7 +6184,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -4421,6 +6317,13 @@ } } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, "node_modules/node-releases": { "version": "2.0.27", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", @@ -4551,6 +6454,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/optimism": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz", + "integrity": "sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==", + "license": "MIT", + "dependencies": { + "@wry/caches": "^1.0.0", + "@wry/context": "^0.7.0", + "@wry/trie": "^0.5.0", + "tslib": "^2.3.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4569,6 +6484,16 @@ "node": ">= 0.8.0" } }, + "node_modules/overlap-area": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/overlap-area/-/overlap-area-1.1.0.tgz", + "integrity": "sha512-3dlJgJCaVeXH0/eZjYVJvQiLVVrPO4U1ZGqlATtx6QGO3b5eNM6+JgUKa7oStBTdYuGTk7gVoABCW6Tp+dhRdw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@daybrush/utils": "^1.7.1" + } + }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -4669,7 +6594,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -4774,7 +6699,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -4784,7 +6708,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -4799,6 +6722,117 @@ "dev": true, "license": "MIT" }, + "node_modules/react-remove-scroll": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", + "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", + "license": "MIT", + "peer": true, + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.3", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.3" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-resizable-panels": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-3.0.6.tgz", + "integrity": "sha512-b3qKHQ3MLqOgSS+FRYKapNkJZf5EQzuf6+RLiq1/IlTHw99YrZ2NJZLk4hQIzTnnIkRg2LUqyVinu6YWWpUYew==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-zoom-pan-pinch": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.7.0.tgz", + "integrity": "sha512-UmReVZ0TxlKzxSbYiAj+LeGRW8s8LraAFTXRAxzMYnNRgGPsxCudwZKVkjvGmjtx7SW/hZamt69NUmGf4xrkXA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8", + "npm": ">=5" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -4919,6 +6953,15 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -4974,6 +7017,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sass": { + "version": "1.93.3", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.93.3.tgz", + "integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==", + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -5194,6 +7257,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sonner": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", + "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -5450,7 +7524,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -5462,7 +7535,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -5613,7 +7686,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5748,6 +7820,61 @@ "punycode": "^2.1.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5889,7 +8016,6 @@ "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -5906,6 +8032,35 @@ "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } + }, + "node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "peer": true, + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index 7129e21..1ee2153 100644 --- a/package.json +++ b/package.json @@ -14,14 +14,21 @@ "lint": "eslint" }, "dependencies": { + "@apollo/client": "^4.0.9", + "@code0-tech/pictor": "^0.0.0-mvp.14", + "graphql": "^16.12.0", + "graphql-tag": "^2.12.6", "next": "16.0.1", "react": "19.2.0", - "react-dom": "19.2.0" + "react-dom": "19.2.0", + "rxjs": "^7.8.2", + "sass": "^1.93.3" }, "devDependencies": { "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", + "babel-plugin-react-compiler": "^1.0.0", "eslint": "^9", "eslint-config-next": "16.0.1", "typescript": "^5" diff --git a/public/.gitkeep b/public/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/public/CodeZero_App_Background_Colorful.png b/public/CodeZero_App_Background_Colorful.png new file mode 100644 index 0000000..76bbbf9 Binary files /dev/null and b/public/CodeZero_App_Background_Colorful.png differ diff --git a/public/CodeZero_Banner_Transparent.png b/public/CodeZero_Banner_Transparent.png new file mode 100644 index 0000000..47410ef Binary files /dev/null and b/public/CodeZero_Banner_Transparent.png differ diff --git a/public/CodeZero_Rainbow.png b/public/CodeZero_Rainbow.png new file mode 100644 index 0000000..951afda Binary files /dev/null and b/public/CodeZero_Rainbow.png differ diff --git a/relay.config.json b/relay.config.json new file mode 100644 index 0000000..c40bc0f --- /dev/null +++ b/relay.config.json @@ -0,0 +1,5 @@ +{ + "src": "./src", + "schema": "./schema.graphql", + "language": "typescript" +} \ No newline at end of file diff --git a/src/app/(auth)/email/page.tsx b/src/app/(auth)/email/page.tsx new file mode 100644 index 0000000..7e9a6ec --- /dev/null +++ b/src/app/(auth)/email/page.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import {UserEmailVerificationPage} from "@edition/auth/UserEmailVerificationPage"; + +export default function Page() { + return +} \ No newline at end of file diff --git a/src/app/(auth)/layout.tsx b/src/app/(auth)/layout.tsx new file mode 100644 index 0000000..1682571 --- /dev/null +++ b/src/app/(auth)/layout.tsx @@ -0,0 +1,57 @@ +"use client" + +import { + Col, + Container, + ContextStoreProvider, + DFullScreen, + DUserView, + Flex, + Text, + useReactiveArrayService +} from "@code0-tech/pictor"; +import {UserService} from "@core/user/User.service"; +import {useApolloClient} from "@apollo/client/react"; +import {GraphqlClient} from "@core/util/graphql-client"; +import Image from "next/image"; +import React from "react"; + +export default function AuthLayout({children}: Readonly<{ children: React.ReactNode }>) { + + const client = useApolloClient() + const [store, service] = useReactiveArrayService((store) => new UserService(new GraphqlClient(client), store)) + + return ( + +
+ + + + + {children} + + + + +
+ All rights reserved © Code0 UG (haftungsbeschränkt) + {"CodeZero +
+
+
+ ); +} diff --git a/src/app/(auth)/login/page.tsx b/src/app/(auth)/login/page.tsx new file mode 100644 index 0000000..6616692 --- /dev/null +++ b/src/app/(auth)/login/page.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import {UserLoginPage} from "@edition/auth/UserLoginPage"; + +export default function Page() { + return +} \ No newline at end of file diff --git a/src/app/(auth)/password/page.tsx b/src/app/(auth)/password/page.tsx new file mode 100644 index 0000000..35cdb88 --- /dev/null +++ b/src/app/(auth)/password/page.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import {UserForgotPasswordPage} from "@edition/auth/UserForgotPasswordPage"; + +export default function Page() { + return +} \ No newline at end of file diff --git a/src/app/(auth)/password/reset/page.tsx b/src/app/(auth)/password/reset/page.tsx new file mode 100644 index 0000000..1455548 --- /dev/null +++ b/src/app/(auth)/password/reset/page.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import {UserResetPasswordPage} from "@edition/auth/UserResetPasswordPage"; + +export default function Page() { + return +} \ No newline at end of file diff --git a/src/app/(auth)/register/page.tsx b/src/app/(auth)/register/page.tsx new file mode 100644 index 0000000..b63f15c --- /dev/null +++ b/src/app/(auth)/register/page.tsx @@ -0,0 +1,6 @@ +import React from "react"; +import {UserRegistrationPage} from "@edition/auth/UserRegistrationPage"; + +export default function Page() { + return +} \ No newline at end of file diff --git a/src/app/(dashboard)/@bar/default.tsx b/src/app/(dashboard)/@bar/default.tsx new file mode 100644 index 0000000..a0b4bd0 --- /dev/null +++ b/src/app/(dashboard)/@bar/default.tsx @@ -0,0 +1,83 @@ +"use client"; + +import { + Badge, + Breadcrumb, + Button, Container, + Flex, + MenuItem, + MenuSeparator, + Text, + TextInput, useService, + useUserSession +} from "@code0-tech/pictor"; +import DUserMenu from "@code0-tech/pictor/dist/components/d-user/DUserMenu"; +import {IconBuilding, IconInbox, IconLogout, IconSearch, IconSettings} from "@tabler/icons-react"; +import React from "react"; +import Image from "next/image"; +import {UserService} from "@core/user/User.service"; +import {useRouter} from "next/navigation"; + +const Page = () => { + + const currentSession = useUserSession() + const userService = useService(UserService) + const router = useRouter() + const [loading, startTransition] = React.useTransition() + + + const userMenu = React.useMemo(() => { + + if (!currentSession?.token) { + return null + } + + const userLogout = () => { + startTransition(async () => { + await userService.usersLogout({ + userSessionId: currentSession.id!! + }).then(payload => { + window.localStorage.removeItem("ide_code-zero_session") + router.push("/login") + }) + }) + } + + return + + Organizations + + + Settings + + + + Logout + + + }, [currentSession]) + + return + + + + {"CodeZero + + Application + + + + } right={⌘K} rightType={"icon"} + placeholder={"Search..."}/> + + {userMenu} + + + + +} + +export default Page \ No newline at end of file diff --git a/src/app/(dashboard)/@tab/default.ts b/src/app/(dashboard)/@tab/default.ts new file mode 100644 index 0000000..b246057 --- /dev/null +++ b/src/app/(dashboard)/@tab/default.ts @@ -0,0 +1,3 @@ +export default function Page() { + return null +} \ No newline at end of file diff --git a/src/app/(dashboard)/@tab/organizations/default.tsx b/src/app/(dashboard)/@tab/organizations/default.tsx new file mode 100644 index 0000000..fe10384 --- /dev/null +++ b/src/app/(dashboard)/@tab/organizations/default.tsx @@ -0,0 +1,10 @@ +"use client" + +import React from "react"; +import {ApplicationTabView} from "@edition/dashboard/application/ApplicationTabView"; + +const Page: React.FC = () => { + return +} + +export default Page \ No newline at end of file diff --git a/src/app/(dashboard)/@tab/page.tsx b/src/app/(dashboard)/@tab/page.tsx new file mode 100644 index 0000000..fe10384 --- /dev/null +++ b/src/app/(dashboard)/@tab/page.tsx @@ -0,0 +1,10 @@ +"use client" + +import React from "react"; +import {ApplicationTabView} from "@edition/dashboard/application/ApplicationTabView"; + +const Page: React.FC = () => { + return +} + +export default Page \ No newline at end of file diff --git a/src/app/(dashboard)/@tab/settings/page.tsx b/src/app/(dashboard)/@tab/settings/page.tsx new file mode 100644 index 0000000..fe10384 --- /dev/null +++ b/src/app/(dashboard)/@tab/settings/page.tsx @@ -0,0 +1,10 @@ +"use client" + +import React from "react"; +import {ApplicationTabView} from "@edition/dashboard/application/ApplicationTabView"; + +const Page: React.FC = () => { + return +} + +export default Page \ No newline at end of file diff --git a/src/app/(dashboard)/@tab/users/page.tsx b/src/app/(dashboard)/@tab/users/page.tsx new file mode 100644 index 0000000..fe10384 --- /dev/null +++ b/src/app/(dashboard)/@tab/users/page.tsx @@ -0,0 +1,10 @@ +"use client" + +import React from "react"; +import {ApplicationTabView} from "@edition/dashboard/application/ApplicationTabView"; + +const Page: React.FC = () => { + return +} + +export default Page \ No newline at end of file diff --git a/src/app/(dashboard)/layout.tsx b/src/app/(dashboard)/layout.tsx new file mode 100644 index 0000000..2215008 --- /dev/null +++ b/src/app/(dashboard)/layout.tsx @@ -0,0 +1,48 @@ +"use client" + +import React from "react"; +import {useApolloClient} from "@apollo/client/react"; +import { + Container, + ContextStoreProvider, + DLayout, + DUserView, + useReactiveArrayService, + useUserSession +} from "@code0-tech/pictor"; +import {UserService} from "@core/user/User.service"; +import {GraphqlClient} from "@core/util/graphql-client"; +import {useRouter} from "next/navigation"; + +interface ApplicationLayoutProps { + children: React.ReactNode + bar: React.ReactNode + tab: React.ReactNode +} + +const ApplicationLayout: React.FC = ({children, bar, tab}) => { + + const client = useApolloClient() + const [store, service] = useReactiveArrayService((store) => new UserService(new GraphqlClient(client), store)) + const router = useRouter() + const currentSession = useUserSession() + + if (currentSession === null) router.push("/login") + + return + +
+ {bar} + {tab} +
+ + }> + + {children} + +
+
+} + +export default ApplicationLayout diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/default.ts b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/default.ts new file mode 100644 index 0000000..4038c6e --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/default.ts @@ -0,0 +1,3 @@ +export default function DefaultModal() { + return null +} \ No newline at end of file diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/@folders/default.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/@folders/default.tsx new file mode 100644 index 0000000..4038c6e --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/@folders/default.tsx @@ -0,0 +1,3 @@ +export default function DefaultModal() { + return null +} \ No newline at end of file diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/@folders/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/@folders/page.tsx new file mode 100644 index 0000000..4038c6e --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/@folders/page.tsx @@ -0,0 +1,3 @@ +export default function DefaultModal() { + return null +} \ No newline at end of file diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@files/default.ts b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@files/default.ts new file mode 100644 index 0000000..4038c6e --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@files/default.ts @@ -0,0 +1,3 @@ +export default function DefaultModal() { + return null +} \ No newline at end of file diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@files/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@files/page.tsx new file mode 100644 index 0000000..dd66542 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@files/page.tsx @@ -0,0 +1,3 @@ +export default function ProjectPage() { + return <>Files view +} diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@flow/default.ts b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@flow/default.ts new file mode 100644 index 0000000..4038c6e --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@flow/default.ts @@ -0,0 +1,3 @@ +export default function DefaultModal() { + return null +} \ No newline at end of file diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@flow/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@flow/page.tsx new file mode 100644 index 0000000..616e001 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/@flow/page.tsx @@ -0,0 +1,3 @@ +export default function ProjectPage() { + return <>Flow view +} diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/layout.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/layout.tsx new file mode 100644 index 0000000..1e21bd4 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/layout.tsx @@ -0,0 +1,18 @@ +import React from "react"; +import Link from "next/link"; + +interface FlowLayoutProps { + children: React.ReactNode + flow: React.ReactNode + files: React.ReactNode +} + +const FlowLayout: React.FC = ({children, flow, files}) => { + return
+ {flow} + {files} + {children} +
+} + +export default FlowLayout diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/page.tsx new file mode 100644 index 0000000..b3fcf9a --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/[flowId]/page.tsx @@ -0,0 +1,3 @@ +export default function ProjectPage() { + return <>Flow page +} diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/layout.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/layout.tsx new file mode 100644 index 0000000..22f4949 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/layout.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import Link from "next/link"; + +interface FlowsLayoutProps { + children: React.ReactNode + folders: React.ReactNode +} + +const FlowsLayout: React.FC = ({children, folders}) => { + return
+ {folders} + {children} +
+} + +export default FlowsLayout diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/page.tsx new file mode 100644 index 0000000..9fb34c6 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/flow/page.tsx @@ -0,0 +1,3 @@ +export default function ProjectPage() { + return <>Flows page +} diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/layout.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/layout.tsx new file mode 100644 index 0000000..37dd750 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/layout.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import Link from "next/link"; + +interface TabsLayoutProps { + children: React.ReactNode +} + +const TabsLayout: React.FC = ({children}) => { + return
+ {children} +
+} + +export default TabsLayout diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/page.ts b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/page.ts new file mode 100644 index 0000000..eb09c6c --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/@tabs/page.ts @@ -0,0 +1,3 @@ +export default function Modal() { + return null +} diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/layout.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/layout.tsx new file mode 100644 index 0000000..8387fc1 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/layout.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import Link from "next/link"; + +interface ProjectLayoutProps { + children: React.ReactNode + tabs: React.ReactNode +} + +const ProjectLayout: React.FC = ({children, tabs}) => { + return
+ {tabs} + {children} +
+} + +export default ProjectLayout diff --git a/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/page.tsx new file mode 100644 index 0000000..79a82e9 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/[projectId]/page.tsx @@ -0,0 +1,3 @@ +export default function ProjectPage() { + return <>Project page +} diff --git a/src/app/(dashboard)/namespace/[namespaceId]/layout.tsx b/src/app/(dashboard)/namespace/[namespaceId]/layout.tsx new file mode 100644 index 0000000..35cf7b3 --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/layout.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import Link from "next/link"; + +interface NamespaceLayoutProps { + children: React.ReactNode +} + +const NamespaceLayout: React.FC = ({children}) => { + return
+ {children} +
+} + +export default NamespaceLayout diff --git a/src/app/(dashboard)/namespace/[namespaceId]/page.tsx b/src/app/(dashboard)/namespace/[namespaceId]/page.tsx new file mode 100644 index 0000000..886ae7d --- /dev/null +++ b/src/app/(dashboard)/namespace/[namespaceId]/page.tsx @@ -0,0 +1,3 @@ +export default function NamespacePage() { + return <>Namespace page (view all projects) +} diff --git a/src/app/(dashboard)/organizations/new/page.tsx b/src/app/(dashboard)/organizations/new/page.tsx new file mode 100644 index 0000000..d070515 --- /dev/null +++ b/src/app/(dashboard)/organizations/new/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return null +} diff --git a/src/app/(dashboard)/organizations/page.tsx b/src/app/(dashboard)/organizations/page.tsx new file mode 100644 index 0000000..d070515 --- /dev/null +++ b/src/app/(dashboard)/organizations/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return null +} diff --git a/src/app/(dashboard)/page.tsx b/src/app/(dashboard)/page.tsx new file mode 100644 index 0000000..4bbbe14 --- /dev/null +++ b/src/app/(dashboard)/page.tsx @@ -0,0 +1,43 @@ +"use client" + +import {Button, Flex, Text} from "@code0-tech/pictor"; +import {IconChevronDown, IconPlus} from "@tabler/icons-react"; +import React from "react"; + +const Page = () => { + + return + + + Personal projects + + + + + + + + + Organizations you joined + + + + + + + +} + +export default React.memo(Page); diff --git a/src/app/(dashboard)/settings/page.tsx b/src/app/(dashboard)/settings/page.tsx new file mode 100644 index 0000000..974ead1 --- /dev/null +++ b/src/app/(dashboard)/settings/page.tsx @@ -0,0 +1,109 @@ +"use client" + +import {Badge, Button, Card, DLayout, Flex, InputLabel, Spacing, SwitchInput, Text} from "@code0-tech/pictor"; +import {Tab, TabContent, TabList, TabTrigger} from "@code0-tech/pictor/dist/components/tab/Tab"; +import {IconGavel, IconSettings} from "@tabler/icons-react"; +import * as process from "node:process"; +import CardSection from "@code0-tech/pictor/dist/components/card/CardSection"; + +export default function Page() { + + return <> + + + + Application + + + + + + + + + }> + <> + + General + +
+ + + + + + Sculptor version + Version of this application + + v0.0.0-mvp.1 + + + + + + + Pictor version + Version of the UI component + library + + {process.env.NEXT_PUBLIC_pictorVersion ?? "v0.0.0-mvp.10"} + + + + + + Sagittarius version + Version of the backend + + 2134929721-ee + + + + + + Restrictions + +
+ + + + + + Organization creation + Set if organization creation is + restricted + to + administrators. + + + + + + Danger Zone +
+ + + + User registration + Set if user registration is + enabled. + + + + + + + + + + + +} diff --git a/src/app/(dashboard)/users/page.tsx b/src/app/(dashboard)/users/page.tsx new file mode 100644 index 0000000..d070515 --- /dev/null +++ b/src/app/(dashboard)/users/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return null +} diff --git a/src/app/global.scss b/src/app/global.scss new file mode 100644 index 0000000..f7dc1ad --- /dev/null +++ b/src/app/global.scss @@ -0,0 +1,21 @@ +* { + box-sizing: border-box; +} + +html, body { + background: #030014; + overflow-x: hidden; + height: 100%; + width: 100%; + margin: 0 !important; + padding: 0 !important; +} + +a { + text-decoration: none; + text-decoration-color: white !important; + + &:hover { + text-decoration: underline; + } +} \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 2657fa0..8927e2a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,15 +1,213 @@ -import React from "react"; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - - {children} - - - ); +"use client"; + +import { + ApolloClient, + ApolloLink, + CombinedGraphQLErrors, + HttpLink, + InMemoryCache, + Observable, + ServerError, + ServerParseError +} from "@apollo/client"; +import {ApolloProvider} from "@apollo/client/react"; +import React, {Suspense} from "react"; +import "./global.scss" +import {setContext} from "@apollo/client/link/context"; +import {ErrorLink} from "@apollo/client/link/error"; +import {useRouter} from "next/navigation"; +import {Toaster} from "sonner"; +import {Error} from "@code0-tech/sagittarius-graphql-types"; +import {toast} from "@code0-tech/pictor"; +import {Inter} from 'next/font/google' + +/** + * Load the Inter font with Latin subset and swap display strategy + */ +const inter = Inter({ + subsets: ['latin'], + display: "swap", +}) + +/** + * Override console error and warn in development to log to console.log + */ +if (process.env.NODE_ENV === "development" && typeof window !== "undefined") { + const originalError = console.error.bind(console); + const originalWarn = console.warn.bind(console); + + console.error = (...args: unknown[]) => { + console.log(args) + } +} + +/** + * Mapping of error codes to their descriptions + */ +const ErrorCodeDescription: Record = { + CANNOT_DELETE_LAST_ADMIN_ROLE: "Cannot delete the last administrative role", + CANNOT_REMOVE_LAST_ADMINISTRATOR: "Cannot remove the last administrator", + CANNOT_REMOVE_LAST_ADMIN_ABILITY: "Cannot remove the last administrative ability", + EXTERNAL_IDENTITY_DOES_NOT_EXIST: "The external identity does not exist", + FAILED_TO_INVALIDATE_OLD_BACKUP_CODES: "Failed to invalidate old backup codes", + FAILED_TO_SAVE_VALID_BACKUP_CODE: "Failed to save the new backup code", + GENERIC_KEY_NOT_FOUND: "The specified key does not exist in the data type", + IDENTITY_VALIDATION_FAILED: "External identity validation failed", + INCONSISTENT_NAMESPACE: "The resources belong to different namespaces", + INVALID_EXTERNAL_IDENTITY: "The external identity is invalid", + INVALID_LOGIN_DATA: "The provided login data is invalid", + INVALID_SETTING: "The provided setting is invalid", + INVALID_VERIFICATION_CODE: "The verification code is invalid", + MFA_FAILED: "The provided MFA data is invalid", + MFA_REQUIRED: "Multi-factor authentication is required", + MISSING_IDENTITY_DATA: "Required data for the external identity is missing", + MISSING_PARAMETER: "One or more required parameters are missing", + MISSING_PERMISSION: "You do not have permission to perform this action", + NO_FREE_LICENSE_SEATS: "There are no free license seats available", + NO_PRIMARY_RUNTIME: "No primary runtime is configured for this project", + PRIMARY_LEVEL_NOT_FOUND: "The primary level could not be found", + REGISTRATION_DISABLED: "Self-registration is currently disabled", + RUNTIME_MISMATCH: "The resources belong to different runtimes", + SECONDARY_LEVEL_NOT_FOUND: "The secondary level could not be found", + TERTIARY_LEVEL_EXCEEDS_PARAMETERS: "The tertiary level exceeds allowed parameters", + TOTP_SECRET_ALREADY_SET: "TOTP is already configured for this user", + UNMODIFIABLE_FIELD: "This field cannot be modified", + WRONG_TOTP: "The provided TOTP code is incorrect", +} + +/** + * Handles error toasts based on error type + */ +const toastHandler = (error: Error) => { + if (error.__typename === "ErrorCode") { + toast({ + title: ErrorCodeDescription[(error.errorCode as string)], + color: "error", + dismissible: true, + }) + } else { + toast({ + title: "An internal error occurred", + color: "error", + dismissible: true, + }) + } +} + +/** + * Root layout component that sets up Apollo Client and error handling + */ +export default function RootLayout({children}: Readonly<{ children: React.ReactNode }>) { + + const router = useRouter() + + /** + * Apollo Error Link to handle GraphQL and network errors + */ + const errorLink = new ErrorLink(({error, result, operation, forward}) => { + + if (error instanceof CombinedGraphQLErrors) error.errors.forEach((error: Error) => { + toastHandler(error) + }) + + if (error instanceof ServerError) { + const status = error.statusCode; + if (status === 401) { + localStorage.removeItem("ide_code-zero_session") + router.push("/login") + } + } + + if (error instanceof ServerParseError) { + toastHandler(error) + } + }) + + /** + * Apollo Auth Middleware to attach session token to headers + */ + const authMiddleware = setContext((_, {headers}) => { + let token: string | undefined + try { + const raw = localStorage.getItem("ide_code-zero_session") + token = raw ? JSON.parse(raw)?.token : undefined + } catch { + } + + return { + headers: { + ...headers, + ...(token ? {authorization: `Session ${token}`} : {}), + }, + } + }) + + + /** + * Apollo Response Handler Link to process errors in responses + */ + const responseHandlerLink = new ApolloLink((operation, forward) => { + if (!forward) return null as any + return new Observable((observer) => { + const sub = forward(operation).subscribe({ + next: (result) => { + + function findErrors(obj: any): Error[] { + if (obj === null || typeof obj !== "object") return [] + + if ("errors" in obj && Array.isArray(obj.errors)) { + return obj.errors + } + + for (const key of Object.keys(obj)) { + const value = obj[key] + if (value && typeof value === "object") { + const found = findErrors(value) + if (found) return found + } + } + + return [] + } + + findErrors(result).map((error) => toastHandler(error)) + observer.next(result); + }, + complete: () => observer.complete() + }) + return () => sub.unsubscribe() + }) + }) + + /** + * Apollo Client instance with configured links and cache + */ + const client = React.useMemo(() => new ApolloClient({ + cache: new InMemoryCache(), + link: ApolloLink.from([errorLink, authMiddleware, responseHandlerLink, new HttpLink({uri: "/graphql"})]), + defaultOptions: { + watchQuery: { + errorPolicy: "all", + }, + query: { + errorPolicy: "all", + }, + mutate: { + errorPolicy: "all", + }, + }, + }), [authMiddleware]) + + return React.useMemo(() => { + return + + + + + {children} + + + + + }, [client, children]) } diff --git a/src/app/page.tsx b/src/app/page.tsx deleted file mode 100644 index 52a848a..0000000 --- a/src/app/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import {Test} from "@edition/Test"; - -export default function Home() { - return -} diff --git a/src/packages/ce/src/Test.tsx b/src/packages/ce/src/Test.tsx deleted file mode 100644 index 72166e3..0000000 --- a/src/packages/ce/src/Test.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export const Test = () => { - return <>Community Edition -} \ No newline at end of file diff --git a/src/packages/ce/src/auth/UserEmailVerificationPage.tsx b/src/packages/ce/src/auth/UserEmailVerificationPage.tsx new file mode 100644 index 0000000..27f03b3 --- /dev/null +++ b/src/packages/ce/src/auth/UserEmailVerificationPage.tsx @@ -0,0 +1,66 @@ +"use client"; + +import React from "react"; +import {Button, setUserSession, Text, TextInput, useForm, useService} from "@code0-tech/pictor"; +import {UserService} from "@core/user/User.service"; +import Link from "next/link"; +import Image from "next/image"; +import {useRouter} from "next/navigation"; + +export const UserEmailVerificationPage: React.FC = () => { + + const userService = useService(UserService) + const [loading, startTransition] = React.useTransition() + const router = useRouter() + + const [inputs, validate] = useForm({ + initialValues: { + code: null, + }, + validate: { + code: (value) => { + if (!value) return "Code is required" + return null + } + }, + onSubmit: (values) => { + if (!values.code) return + startTransition(async () => { + await userService.usersEmailVerification({ + token: (values.code as unknown as string), + }).then(payload => { + if ((payload?.errors?.length ?? 0) <= 0) { + router.push("/?emailVerified=true") + router.refresh() + } + }) + }) + } + }) + + return <> + {"CodeZero + + Verify your email address + + + Build high-class workflows, endpoints and software without coding + + +
+ + + Don't have an account yet + + + Log in + + + + +} \ No newline at end of file diff --git a/src/packages/ce/src/auth/UserForgotPasswordPage.tsx b/src/packages/ce/src/auth/UserForgotPasswordPage.tsx new file mode 100644 index 0000000..7883fdb --- /dev/null +++ b/src/packages/ce/src/auth/UserForgotPasswordPage.tsx @@ -0,0 +1,66 @@ +"use client"; + +import React from "react"; +import {Button, EmailInput, emailValidation, Text, useForm, useService} from "@code0-tech/pictor"; +import {UserService} from "@core/user/User.service"; +import Link from "next/link"; +import Image from "next/image"; +import {useRouter} from "next/navigation"; + +export const UserForgotPasswordPage: React.FC = () => { + + const userService = useService(UserService) + const [loading, startTransition] = React.useTransition() + const router = useRouter() + + const [inputs, validate] = useForm({ + initialValues: { + email: null, + }, + validate: { + email: (value) => { + if (!value) return "Email is required" + if (!emailValidation(value)) return "Please provide a valid email" + return null + } + }, + onSubmit: (values) => { + if (!values.email) return + startTransition(async () => { + await userService.usersPasswordResetRequest({ + email: (values.email as unknown as string), + }).then(payload => { + if ((payload?.errors?.length ?? 0) <= 0) { + router.push("/password/reset?passwordReset=true") + } + }) + }) + } + }) + + return <> + {"CodeZero + + Forgot your password? + + + Build high-class workflows, endpoints and software without coding + + +
+ + + Didn't forget your password? + + + Log in + + + + +} \ No newline at end of file diff --git a/src/packages/ce/src/auth/UserLoginPage.tsx b/src/packages/ce/src/auth/UserLoginPage.tsx new file mode 100644 index 0000000..761c483 --- /dev/null +++ b/src/packages/ce/src/auth/UserLoginPage.tsx @@ -0,0 +1,100 @@ +"use client"; + +import React from "react"; +import { + Alert, + Button, + EmailInput, + emailValidation, + PasswordInput, + setUserSession, + Spacing, + Text, + useForm, + useService +} from "@code0-tech/pictor"; +import {UserService} from "@core/user/User.service"; +import Image from "next/image"; +import Link from "next/link"; +import {useRouter, useSearchParams} from "next/navigation"; + +export const UserLoginPage: React.FC = () => { + + const query = useSearchParams() //can be passwordReset + const userService = useService(UserService) + const router = useRouter() + const [loading, startTransition] = React.useTransition() + + const [inputs, validate] = useForm({ + initialValues: { + email: null, + password: null + }, + validate: { + email: (value) => { + if (!value) return "Email is required" + if (!emailValidation(value)) return "Please provide a valid email" + return null + }, + password: (value) => { + if (!value) return "Password is required" + return null + } + }, + onSubmit: (values) => { + if (!values.password || !values.email || !emailValidation(values.email)) return + startTransition(async () => { + await userService.usersLogin({ + password: (values.password as unknown as string), + email: (values.email as unknown as string), + }).then(payload => { + if (payload?.userSession) { + setUserSession(payload.userSession) + router.push("/") + router.refresh() + } + }) + }) + } + }) + + return <> + {"CodeZero + + Login to CodeZero + + + Build high-class workflows, endpoints and software without coding + + {query.has("passwordReset") ? ( + <> + Your password was successfully reset. + + + ) : null} + +
+ +
+ + + + Forgot password? + + + + Don't have an account yet + + + Sign up + + + + + +} \ No newline at end of file diff --git a/src/packages/ce/src/auth/UserRegistrationPage.tsx b/src/packages/ce/src/auth/UserRegistrationPage.tsx new file mode 100644 index 0000000..cc531a7 --- /dev/null +++ b/src/packages/ce/src/auth/UserRegistrationPage.tsx @@ -0,0 +1,106 @@ +"use client"; + +import React from "react"; +import { + Button, + EmailInput, emailValidation, + Flex, + PasswordInput, + setUserSession, + Text, + TextInput, + useForm, + useService +} from "@code0-tech/pictor"; +import Image from "next/image"; +import Link from "next/link"; +import {UserService} from "@core/user/User.service"; +import {useRouter} from "next/navigation"; + +export const UserRegistrationPage: React.FC = () => { + + const userService = useService(UserService) + const router = useRouter() + const [loading, startTransition] = React.useTransition() + + const [inputs, validate] = useForm({ + initialValues: { + email: null, + username: null, + password: null, + repeatPassword: null, + }, + validate: { + email: (value) => { + if (!value) return "Email is required" + if (!emailValidation(value)) return "Please provide a valid email" + return null + }, + username: (value) => { + if (!value) return "Username is required" + return null + }, + password: (value) => { + if (!value) return "Password is required" + return null + }, + repeatPassword: (value) => { + if (!value) return "Repeat password is required" + return null + } + }, + onSubmit: (values) => { + if (!values.email || !values.username || !values.password || !values.repeatPassword) return + startTransition(async () => { + await userService.usersRegister({ + passwordRepeat: (values.repeatPassword as unknown as string), + password: (values.password as unknown as string), + email: (values.email as unknown as string), + username: (values.username as unknown as string), + }).then(payload => { + if (payload?.userSession) { + setUserSession(payload.userSession) + router.push("/") + router.refresh() + } + }) + }) + } + }) + + return <> + {"CodeZero + + Sign up to CodeZero + + + Build high-class workflows, endpoints and software without coding + + + {/**@ts-ignore**/} + + {/**@ts-ignore**/} + + +
+ +
+ +
+ + + Have an account + + + Log in + + + + +} \ No newline at end of file diff --git a/src/packages/ce/src/auth/UserResetPasswordPage.tsx b/src/packages/ce/src/auth/UserResetPasswordPage.tsx new file mode 100644 index 0000000..c372dc1 --- /dev/null +++ b/src/packages/ce/src/auth/UserResetPasswordPage.tsx @@ -0,0 +1,88 @@ +"use client"; + +import React from "react"; +import {Alert, Button, PasswordInput, Spacing, Text, TextInput, useForm, useService} from "@code0-tech/pictor"; +import {UserService} from "@core/user/User.service"; +import Link from "next/link"; +import Image from "next/image"; +import {useRouter, useSearchParams} from "next/navigation"; + +export const UserResetPasswordPage: React.FC = () => { + + const query = useSearchParams() //can be passwordReset + const userService = useService(UserService) + const [loading, startTransition] = React.useTransition() + const router = useRouter() + + const [inputs, validate] = useForm({ + initialValues: { + code: null, + password: null, + repeatPassword: null, + }, + validate: { + code: (value) => { + if (!value) return "Code is required" + return null + }, + password: (value) => { + if (!value) return "Password is required" + return null + }, + repeatPassword: (value) => { + if (!value) return "Repeat password is required" + return null + } + }, + onSubmit: (values) => { + if (!values.code || !values.password || !values.repeatPassword) return + startTransition(async () => { + await userService.usersPasswordReset({ + resetToken: (values.code as unknown as string), + newPassword: (values.password as unknown as string), + newPasswordConfirmation: (values.repeatPassword as unknown as string), + }).then(payload => { + if ((payload?.errors?.length ?? 0) <= 0) { + router.push("/login?passwordReset=true") + } + }) + }) + } + }) + + return <> + {"CodeZero + + Reset your password + + + Build high-class workflows, endpoints and software without coding + + {query.has("passwordReset") ? ( + <> + If your email address exists, you received an email with a token to reset your password. + + + ) : null} + +
+ +
+ +
+ + + Don't have an account yet + + + Log in + + + + +} \ No newline at end of file diff --git a/src/packages/ce/src/dashboard/application/ApplicationTabView.tsx b/src/packages/ce/src/dashboard/application/ApplicationTabView.tsx new file mode 100644 index 0000000..9927d38 --- /dev/null +++ b/src/packages/ce/src/dashboard/application/ApplicationTabView.tsx @@ -0,0 +1,89 @@ +"use client" + +import React from "react"; +import {Tab, TabList, TabTrigger} from "@code0-tech/pictor/dist/components/tab/Tab"; +import {Badge, Button, Container, useService, useStore, useUserSession} from "@code0-tech/pictor"; +import {IconBuilding, IconFolder, IconHome, IconServer, IconSettings, IconUser} from "@tabler/icons-react"; +import {usePathname} from "next/navigation"; +import Link from "next/link"; +import {UserService} from "@core/user/User.service"; + +export const ApplicationTabView: React.FC = () => { + + const pathname = usePathname() + const userService = useService(UserService) + const userStore = useStore(UserService) + const currentSession = useUserSession() + const currentUser = React.useMemo(() => userService.getById(currentSession?.user?.id), [userStore, currentSession]) + const defaultValue = pathname.includes("organizations") ? "organizations" + : pathname.includes("users") ? "users" + : pathname.includes("settings") ? "settings" + : "overview" + + const adminLinks = React.useMemo(() => { + return currentUser && currentUser.admin ? ( + <> + + + + + + + + + + + + + + + + + ) : null + }, [currentUser]) + + return + + + + + + + + + + + + + + + + + + {adminLinks} + + + +} \ No newline at end of file diff --git a/src/packages/core/src/identity/fragments/Identity.fragment.graphql b/src/packages/core/src/identity/fragments/Identity.fragment.graphql new file mode 100644 index 0000000..1052c90 --- /dev/null +++ b/src/packages/core/src/identity/fragments/Identity.fragment.graphql @@ -0,0 +1,8 @@ +fragment Identity on UserIdentity { + id + createdAt + updatedAt + identifier + providerId + __typename +} \ No newline at end of file diff --git a/src/packages/core/src/session/fragments/Session.fragment.graphql b/src/packages/core/src/session/fragments/Session.fragment.graphql new file mode 100644 index 0000000..f9c9544 --- /dev/null +++ b/src/packages/core/src/session/fragments/Session.fragment.graphql @@ -0,0 +1,8 @@ +fragment Session on UserSession { + updatedAt + createdAt + id + token + active + __typename +} \ No newline at end of file diff --git a/src/packages/core/src/user/User.service.ts b/src/packages/core/src/user/User.service.ts new file mode 100644 index 0000000..8b52e7b --- /dev/null +++ b/src/packages/core/src/user/User.service.ts @@ -0,0 +1,203 @@ +import {DUserReactiveService, DUserView, ReactiveArrayStore} from "@code0-tech/pictor"; +import { + Mutation, + Query, + User, + UsersEmailVerificationInput, + UsersEmailVerificationPayload, + UsersIdentityLinkInput, + UsersIdentityLinkPayload, + UsersIdentityLoginInput, + UsersIdentityLoginPayload, + UsersIdentityRegisterInput, + UsersIdentityRegisterPayload, + UsersIdentityUnlinkInput, + UsersIdentityUnlinkPayload, + UsersLoginInput, + UsersLoginPayload, + UsersLogoutInput, + UsersLogoutPayload, + UsersMfaBackupCodesRotateInput, + UsersMfaBackupCodesRotatePayload, + UsersMfaTotpGenerateSecretInput, + UsersMfaTotpGenerateSecretPayload, + UsersMfaTotpValidateSecretInput, + UsersMfaTotpValidateSecretPayload, + UsersPasswordResetInput, + UsersPasswordResetPayload, + UsersPasswordResetRequestInput, + UsersPasswordResetRequestPayload, + UsersRegisterInput, + UsersRegisterPayload +} from "@code0-tech/sagittarius-graphql-types"; +import {GraphqlClient} from "@core/util/graphql-client"; +import loginMutation from "../user/mutations/User.login.mutation.graphql"; +import logoutMutation from "../user/mutations/User.logout.mutation.graphql"; +import registerMutation from "../user/mutations/User.register.mutation.graphql"; +import emailVerificationMutation from "../user/mutations/User.emailVerification.mutation.graphql"; +import passwordResetMutation from "../user/mutations/User.passwordReset.mutation.graphql" +import passwordResetRequestMutation from "../user/mutations/User.passwordResetRequest.mutation.graphql" +import userQuery from "../user/queries/User.query.graphql"; + +export class UserService extends DUserReactiveService { + + private readonly client: GraphqlClient + + constructor(client: GraphqlClient, store: ReactiveArrayStore) { + super(store); + this.client = client + } + + values(): DUserView[] { + if (super.values().length > 0) return super.values(); + this.client.query({ + query: userQuery + }).then(result => { + const data = result.data + if (!data) return + + if (data && data.currentUser) this.add(new DUserView(data.currentUser)) + if (data.users && data.users.nodes) { + for (const user of data.users.nodes) { + if (user) this.add(new DUserView(user)) + } + } + }) + + return super.values(); + } + + getById(id: User["id"]): DUserView | undefined { + return super.getById(id); + } + + deleteById(id: User["id"]): void { + const index = this.values().findIndex(user => user.id === id) + this.delete(index) + } + + hasById(id: User["id"]): boolean { + const user = this.getById(id); + return user !== undefined; + } + + async usersEmailVerification(payload: UsersEmailVerificationInput): Promise { + const result = await this.client.mutate({ + mutation: emailVerificationMutation, + variables: { + ...payload + } + }) + + if (result.data && result.data.usersEmailVerification && result.data.usersEmailVerification.user && this.hasById(result.data.usersEmailVerification.user.id)) { + //const existingUser = this.getById(result.data.usersEmailVerification.user.id) + //TODO: existingUser?.emailVerifiedAt = result.data.usersEmailVerification.user.emailVerifiedAt + } + + return result.data?.usersEmailVerification ?? undefined + } + + /** @alpha **/ + usersIdentityLink(payload: UsersIdentityLinkInput): Promise { + return Promise.resolve(undefined); + } + + /** @alpha **/ + usersIdentityLogin(payload: UsersIdentityLoginInput): Promise { + return Promise.resolve(undefined); + } + + /** @alpha **/ + usersIdentityRegister(payload: UsersIdentityRegisterInput): Promise { + return Promise.resolve(undefined); + } + + /** @alpha **/ + usersIdentityUnlink(payload: UsersIdentityUnlinkInput): Promise { + return Promise.resolve(undefined); + } + + async usersLogin(payload: UsersLoginInput): Promise { + const result = await this.client.mutate({ + mutation: loginMutation, + variables: { + ...payload + } + }) + + if (result.data && result.data.usersLogin && result.data.usersLogin.userSession?.user && !this.hasById(result.data.usersLogin.userSession?.user.id)) { + this.add(new DUserView(result.data.usersLogin.userSession.user)) + } + + return result.data?.usersLogin ?? undefined + } + + async usersLogout(payload: UsersLogoutInput): Promise { + const result = await this.client.mutate({ + mutation: logoutMutation, + variables: { + ...payload + } + }) + + if (result.data && result.data.usersLogout && result.data.usersLogout.userSession && result.data.usersLogout.userSession.user) { + this.deleteById(result.data.usersLogout.userSession.user.id) + } + + return result.data?.usersLogout ?? undefined + } + + /** @alpha **/ + usersMfaBackupCodesRotate(payload: UsersMfaBackupCodesRotateInput): Promise { + return Promise.resolve(undefined); + } + + /** @alpha **/ + usersMfaTotpGenerateSecret(payload: UsersMfaTotpGenerateSecretInput): Promise { + return Promise.resolve(undefined); + } + + /** @alpha **/ + usersMfaTotpValidateSecret(payload: UsersMfaTotpValidateSecretInput): Promise { + return Promise.resolve(undefined); + } + + async usersPasswordReset(payload: UsersPasswordResetInput): Promise { + const result = await this.client.mutate({ + mutation: passwordResetMutation, + variables: { + ...payload + } + }) + + return result.data?.usersPasswordReset ?? undefined + } + + async usersPasswordResetRequest(payload: UsersPasswordResetRequestInput): Promise { + const result = await this.client.mutate({ + mutation: passwordResetRequestMutation, + variables: { + ...payload + } + }) + + return result.data?.usersPasswordResetRequest ?? undefined + } + + async usersRegister(payload: UsersRegisterInput): Promise { + + const result = await this.client.mutate({ + mutation: registerMutation, + variables: { + ...payload + } + }) + + if (result.data && result.data.usersRegister && result.data.usersRegister.userSession?.user && !this.hasById(result.data.usersRegister.userSession?.user.id)) { + this.add(new DUserView(result.data.usersRegister.userSession.user)) + } + + return result.data?.usersRegister ?? undefined + } + +} \ No newline at end of file diff --git a/src/packages/core/src/user/fragments/User.basic.fragment.graphql b/src/packages/core/src/user/fragments/User.basic.fragment.graphql new file mode 100644 index 0000000..9e13cee --- /dev/null +++ b/src/packages/core/src/user/fragments/User.basic.fragment.graphql @@ -0,0 +1,15 @@ +fragment UserBasic on User { + admin + avatarPath + createdAt + email + emailVerifiedAt + firstname + id + lastname + namespace { + id + } + updatedAt + username +} \ No newline at end of file diff --git a/src/packages/core/src/user/fragments/User.fragment.graphql b/src/packages/core/src/user/fragments/User.fragment.graphql new file mode 100644 index 0000000..cb15289 --- /dev/null +++ b/src/packages/core/src/user/fragments/User.fragment.graphql @@ -0,0 +1,37 @@ +#import "../../identity/fragments/Identity.fragment.graphql" +#import "../../session/fragments/Session.fragment.graphql" +fragment User on User { + admin + avatarPath + createdAt + email + emailVerifiedAt + firstname + id + lastname + namespace { + id + } + identities (first: $firstIdentity, after: $afterIdentity) { + count + nodes { + ...Identity + } + pageInfo { + endCursor + hasNextPage + } + } + sessions (first: $firstSession, after: $afterSession) { + count + nodes { + ...Session + } + pageInfo { + endCursor + hasNextPage + } + } + updatedAt + username +} \ No newline at end of file diff --git a/src/packages/core/src/user/fragments/User.id.fragment.graphql b/src/packages/core/src/user/fragments/User.id.fragment.graphql new file mode 100644 index 0000000..753807d --- /dev/null +++ b/src/packages/core/src/user/fragments/User.id.fragment.graphql @@ -0,0 +1,3 @@ +fragment UserId on User { + id +} \ No newline at end of file diff --git a/src/packages/core/src/user/mutations/User.emailVerification.mutation.graphql b/src/packages/core/src/user/mutations/User.emailVerification.mutation.graphql new file mode 100644 index 0000000..d1a3f15 --- /dev/null +++ b/src/packages/core/src/user/mutations/User.emailVerification.mutation.graphql @@ -0,0 +1,15 @@ +#import '../fragments/User.basic.fragment.graphql' +mutation emailVerification($token: String!) { + usersEmailVerification(input: { + token: $token + }) { + errors { + ...on ActiveModelError { attribute type } + ...on MessageError { message } + ...on ErrorCode { errorCode } + } + user { + ...UserBasic + } + } +} \ No newline at end of file diff --git a/src/packages/core/src/user/mutations/User.login.mutation.graphql b/src/packages/core/src/user/mutations/User.login.mutation.graphql new file mode 100644 index 0000000..7dd80c4 --- /dev/null +++ b/src/packages/core/src/user/mutations/User.login.mutation.graphql @@ -0,0 +1,24 @@ +#import '../fragments/User.basic.fragment.graphql' +mutation login($email: String!, $password: String!, $username: String) { + usersLogin(input: { + email: $email + password: $password + username: $username + }) { + errors { + ...on ActiveModelError { attribute type } + ...on MessageError { message } + ...on ErrorCode { errorCode } + } + userSession { + updatedAt + token + active + createdAt + id + user { + ...UserBasic + } + } + } +} \ No newline at end of file diff --git a/src/packages/core/src/user/mutations/User.logout.mutation.graphql b/src/packages/core/src/user/mutations/User.logout.mutation.graphql new file mode 100644 index 0000000..d1aa692 --- /dev/null +++ b/src/packages/core/src/user/mutations/User.logout.mutation.graphql @@ -0,0 +1,14 @@ +mutation logout($userSessionId: UserSessionID!) { + usersLogout(input: { + userSessionId: $userSessionId + }) { + errors { + ...on ActiveModelError { attribute type } + ...on MessageError { message } + ...on ErrorCode { errorCode } + } + userSession { + id + } + } +} \ No newline at end of file diff --git a/src/packages/core/src/user/mutations/User.passwordReset.mutation.graphql b/src/packages/core/src/user/mutations/User.passwordReset.mutation.graphql new file mode 100644 index 0000000..959d824 --- /dev/null +++ b/src/packages/core/src/user/mutations/User.passwordReset.mutation.graphql @@ -0,0 +1,14 @@ +mutation userPasswordReset($newPassword: String!, $newPasswordConfirmation: String!, $resetToken: String!) { + usersPasswordReset(input: { + newPassword: $newPassword + newPasswordConfirmation: $newPasswordConfirmation + resetToken: $resetToken + }) { + errors { + ...on ActiveModelError { attribute type } + ...on MessageError { message } + ...on ErrorCode { errorCode } + } + message + } +} \ No newline at end of file diff --git a/src/packages/core/src/user/mutations/User.passwordResetRequest.mutation.graphql b/src/packages/core/src/user/mutations/User.passwordResetRequest.mutation.graphql new file mode 100644 index 0000000..13b5cfe --- /dev/null +++ b/src/packages/core/src/user/mutations/User.passwordResetRequest.mutation.graphql @@ -0,0 +1,12 @@ +mutation userPasswordResetRequest($email: String!) { + usersPasswordResetRequest(input: { + email: $email + }) { + errors { + ...on ActiveModelError { attribute type } + ...on MessageError { message } + ...on ErrorCode { errorCode } + } + message + } +} \ No newline at end of file diff --git a/src/packages/core/src/user/mutations/User.register.mutation.graphql b/src/packages/core/src/user/mutations/User.register.mutation.graphql new file mode 100644 index 0000000..f440d19 --- /dev/null +++ b/src/packages/core/src/user/mutations/User.register.mutation.graphql @@ -0,0 +1,25 @@ +#import '../fragments/User.basic.fragment.graphql' +mutation register($email: String!, $password: String!, $passwordRepeat: String!, $username: String!) { + usersRegister(input: { + email: $email + password: $password + passwordRepeat: $passwordRepeat + username: $username + }) { + errors { + ...on ActiveModelError { attribute type } + ...on MessageError { message } + ...on ErrorCode { errorCode } + } + userSession { + updatedAt + token + active + createdAt + id + user { + ...UserBasic + } + } + } +} \ No newline at end of file diff --git a/src/packages/core/src/user/queries/User.query.graphql b/src/packages/core/src/user/queries/User.query.graphql new file mode 100644 index 0000000..f4e0d61 --- /dev/null +++ b/src/packages/core/src/user/queries/User.query.graphql @@ -0,0 +1,18 @@ +#import '../fragments/User.fragment.graphql' +#import '../fragments/User.basic.fragment.graphql' + +query User($firstUser: Int, $afterUser: String, $firstIdentity: Int, $afterIdentity: String, $firstSession: Int, $afterSession: String) { + currentUser { + ...User + } + users (first: $firstUser, after: $afterUser) { + count + nodes { + ...UserBasic + } + pageInfo { + endCursor + hasNextPage + } + } +} \ No newline at end of file diff --git a/src/packages/core/src/util/graphql-client.ts b/src/packages/core/src/util/graphql-client.ts new file mode 100644 index 0000000..3a88e66 --- /dev/null +++ b/src/packages/core/src/util/graphql-client.ts @@ -0,0 +1,142 @@ +import {ApolloClient, OperationVariables} from "@apollo/client"; +import type {MaybeMasked} from "@apollo/client/masking"; + +export class GraphqlClient { + + private readonly _client: ApolloClient + + constructor(client: ApolloClient) { + this._client = client + } + + async mutate( + options: ApolloClient.MutateOptions + ): Promise>> { + return this._client.mutate(options); + } + + async query( + options: ApolloClient.QueryOptions + ): Promise>> { + // 1) Initial request + const first = await this._client.query(options); + let aggregated: any = structuredClone(first.data ?? null); + if (!aggregated || !options.query) return first; + + // 2) AST analysieren: Connection-Spezifikationen sammeln (Pfad + Variablennamen) + const specs: Array<{ path: string; afterVar?: string; firstVar?: string }> = []; + const doc: any = options.query; + const fragments = new Map(); + + for (const d of doc.definitions ?? []) { + if (d?.kind === "FragmentDefinition") fragments.set(d.name?.value, d); + } + + const visitSelections = (set: any, path: string[]) => { + for (const sel of set?.selections ?? []) { + if (sel.kind === "Field") { + const key = sel.alias?.value ?? sel.name?.value; + const nextPath = [...path, key]; + + // Argumente der Connection erfassen (after/first per Variable) + let afterVar: string | undefined; + let firstVar: string | undefined; + for (const arg of sel.arguments ?? []) { + const argName = arg.name?.value; + if ((argName === "after" || argName === "first") && arg.value?.kind === "Variable") { + if (argName === "after") afterVar = arg.value.name?.value; + if (argName === "first") firstVar = arg.value.name?.value; + } + } + + if (afterVar || firstVar) { + specs.push({ path: nextPath.join("."), afterVar, firstVar }); + } + + if (sel.selectionSet) visitSelections(sel.selectionSet, nextPath); + } else if (sel.kind === "InlineFragment") { + if (sel.selectionSet) visitSelections(sel.selectionSet, path); + } else if (sel.kind === "FragmentSpread") { + const frag = fragments.get(sel.name?.value); + if (frag?.selectionSet) visitSelections(frag.selectionSet, path); + } + } + }; + + const op = doc.definitions?.find((d: any) => d.kind === "OperationDefinition"); + if (op?.selectionSet) visitSelections(op.selectionSet, []); + + // uniq by path + const seen = new Set(); + const uniqSpecs = specs.filter(s => (seen.has(s.path) ? false : (seen.add(s.path), true))); + if (uniqSpecs.length === 0) return first; + + // 3) Inline-Helfer (lokal) + const getAt = (obj: any, p: string) => + p.split(".").filter(Boolean).reduce((o, k) => (o ? o[k] : undefined), obj); + + const setAt = (obj: any, p: string, v: any) => { + const ks = p.split(".").filter(Boolean); + const last = ks.pop(); + if (!last) return; + const parent = ks.reduce((o, k) => (o[k] ??= {}), obj); + parent[last] = v; + }; + + const mergeConn = (t: any, s: any) => { + if (!t || !s) return; + if (Array.isArray(t.nodes) && Array.isArray(s.nodes)) t.nodes = [...t.nodes, ...s.nodes]; + if (Array.isArray(t.edges) && Array.isArray(s.edges)) t.edges = [...t.edges, ...s.edges]; + if (s.pageInfo) { + t.pageInfo = { + ...t.pageInfo, + ...s.pageInfo, + endCursor: s.pageInfo.endCursor + }; + } + if (typeof t.count === "number" && typeof s.count === "number") { + t.count = Math.max(t.count, s.count); + } + }; + + // 4) Sequentiell nachladen, bis keine Connection mehr hasNextPage hat + while (true) { + // Nächste Connection mit restlichen Seiten finden + const next = uniqSpecs.find(s => { + const c = getAt(aggregated, s.path); + return !!c?.pageInfo?.hasNextPage; + }); + if (!next) break; + + // Variablen für die nächste Page + const nextVars: Record = { ...(options.variables as any) }; + if (next.afterVar) { + nextVars[next.afterVar] = getAt(aggregated, next.path)?.pageInfo?.endCursor; + } + if (next.firstVar && nextVars[next.firstVar] == null && (options.variables as any)?.[next.firstVar] != null) { + nextVars[next.firstVar] = (options.variables as any)[next.firstVar]; + } + + // Page-Request (netzwerkbasiert, um sicher zu gehen) + const page = await this._client.query({ + ...options, + variables: nextVars as TVariables, + fetchPolicy: options.fetchPolicy ?? "network-only", + }); + + const pageData: any = page.data ?? null; + if (!pageData) break; + + // Nur die betroffene Connection zusammenführen + const src = getAt(pageData, next.path); + const tgt = getAt(aggregated, next.path); + if (!src || !tgt) break; + + mergeConn(tgt, src); + setAt(aggregated, next.path, tgt); + } + + return { ...first, data: aggregated }; + } + +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index e74b0ad..580b089 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,8 @@ { "compilerOptions": { + "types": [ + "./graphql-imports" + ], "target": "ES2017", "lib": [ "dom",