From 8f7d2fd1e3952fb73fe6e86642b3249a66fec610453537411b89bcc50150b302 Mon Sep 17 00:00:00 2001 From: Philipp Schweizer Date: Fri, 14 Feb 2025 21:11:11 +0100 Subject: [PATCH] feat: first state --- webClient/.gitignore | 26 + webClient/README.md | 50 + webClient/eslint.config.js | 28 + webClient/index.html | 13 + webClient/package-lock.json | 4347 +++++++++++++++++ webClient/package.json | 40 + webClient/public/vite.svg | 1 + webClient/src/App.tsx | 56 + webClient/src/app/apiBaseQuery.ts | 5 + webClient/src/app/store.ts | 14 + webClient/src/components/AppNavbar.tsx | 107 + webClient/src/components/CardAlert.tsx | 24 + webClient/src/components/CustomDatePicker.tsx | 78 + webClient/src/components/Header.tsx | 35 + webClient/src/components/MenuButton.tsx | 22 + webClient/src/components/MenuContent.tsx | 54 + .../src/components/NavbarBreadcrumbs.tsx | 32 + webClient/src/components/OptionsMenu.tsx | 79 + webClient/src/components/Search.tsx | 25 + webClient/src/components/SelectContent.tsx | 102 + webClient/src/components/SideMenu.tsx | 80 + webClient/src/components/SideMenuMobile.tsx | 79 + .../src/features/locations/locationApi.ts | 47 + webClient/src/main.tsx | 9 + webClient/src/models/location.ts | 12 + webClient/src/shared-theme/AppTheme.tsx | 53 + .../shared-theme/ColorModeIconDropdown.tsx | 89 + .../customizations/dataDisplay.tsx | 233 + .../shared-theme/customizations/feedback.tsx | 46 + .../shared-theme/customizations/inputs.tsx | 445 ++ .../customizations/navigation.tsx | 279 ++ .../shared-theme/customizations/surfaces.ts | 113 + webClient/src/shared-theme/themePrimitives.ts | 410 ++ webClient/src/theme/customizations/charts.ts | 76 + .../src/theme/customizations/dataGrid.ts | 138 + .../src/theme/customizations/datePickers.ts | 182 + webClient/src/theme/customizations/index.ts | 4 + .../src/theme/customizations/treeView.ts | 62 + webClient/src/vite-env.d.ts | 1 + webClient/tsconfig.app.json | 26 + webClient/tsconfig.json | 7 + webClient/tsconfig.node.json | 24 + webClient/vite.config.ts | 7 + 43 files changed, 7560 insertions(+) create mode 100644 webClient/.gitignore create mode 100644 webClient/README.md create mode 100644 webClient/eslint.config.js create mode 100644 webClient/index.html create mode 100644 webClient/package-lock.json create mode 100644 webClient/package.json create mode 100644 webClient/public/vite.svg create mode 100644 webClient/src/App.tsx create mode 100644 webClient/src/app/apiBaseQuery.ts create mode 100644 webClient/src/app/store.ts create mode 100644 webClient/src/components/AppNavbar.tsx create mode 100644 webClient/src/components/CardAlert.tsx create mode 100644 webClient/src/components/CustomDatePicker.tsx create mode 100644 webClient/src/components/Header.tsx create mode 100644 webClient/src/components/MenuButton.tsx create mode 100644 webClient/src/components/MenuContent.tsx create mode 100644 webClient/src/components/NavbarBreadcrumbs.tsx create mode 100644 webClient/src/components/OptionsMenu.tsx create mode 100644 webClient/src/components/Search.tsx create mode 100644 webClient/src/components/SelectContent.tsx create mode 100644 webClient/src/components/SideMenu.tsx create mode 100644 webClient/src/components/SideMenuMobile.tsx create mode 100644 webClient/src/features/locations/locationApi.ts create mode 100644 webClient/src/main.tsx create mode 100644 webClient/src/models/location.ts create mode 100644 webClient/src/shared-theme/AppTheme.tsx create mode 100644 webClient/src/shared-theme/ColorModeIconDropdown.tsx create mode 100644 webClient/src/shared-theme/customizations/dataDisplay.tsx create mode 100644 webClient/src/shared-theme/customizations/feedback.tsx create mode 100644 webClient/src/shared-theme/customizations/inputs.tsx create mode 100644 webClient/src/shared-theme/customizations/navigation.tsx create mode 100644 webClient/src/shared-theme/customizations/surfaces.ts create mode 100644 webClient/src/shared-theme/themePrimitives.ts create mode 100644 webClient/src/theme/customizations/charts.ts create mode 100644 webClient/src/theme/customizations/dataGrid.ts create mode 100644 webClient/src/theme/customizations/datePickers.ts create mode 100644 webClient/src/theme/customizations/index.ts create mode 100644 webClient/src/theme/customizations/treeView.ts create mode 100644 webClient/src/vite-env.d.ts create mode 100644 webClient/tsconfig.app.json create mode 100644 webClient/tsconfig.json create mode 100644 webClient/tsconfig.node.json create mode 100644 webClient/vite.config.ts diff --git a/webClient/.gitignore b/webClient/.gitignore new file mode 100644 index 0000000..966bc4b --- /dev/null +++ b/webClient/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.env diff --git a/webClient/README.md b/webClient/README.md new file mode 100644 index 0000000..e164441 --- /dev/null +++ b/webClient/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from 'eslint-plugin-react' + +export default tseslint.config({ + // Set the react version + settings: { react: { version: '18.3' } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + }, +}) +``` diff --git a/webClient/eslint.config.js b/webClient/eslint.config.js new file mode 100644 index 0000000..3667f7f --- /dev/null +++ b/webClient/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/webClient/index.html b/webClient/index.html new file mode 100644 index 0000000..f55ef8a --- /dev/null +++ b/webClient/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/webClient/package-lock.json b/webClient/package-lock.json new file mode 100644 index 0000000..d95d891 --- /dev/null +++ b/webClient/package-lock.json @@ -0,0 +1,4347 @@ +{ + "name": "location_hub_ui", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "location_hub_ui", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mui/icons-material": "^6.4.3", + "@mui/material": "^6.4.3", + "@mui/x-charts": "^7.25.0", + "@mui/x-data-grid": "^7.25.0", + "@mui/x-date-pickers": "^7.25.0", + "@mui/x-tree-view": "^7.25.0", + "@reduxjs/toolkit": "^2.5.0", + "dayjs": "^1.11.13", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-redux": "^9.2.0" + }, + "devDependencies": { + "@eslint/js": "^9.17.0", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^15.14.0", + "typescript": "~5.6.2", + "typescript-eslint": "^8.18.2", + "vite": "^6.0.5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", + "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.5", + "@babel/types": "^7.26.5", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", + "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", + "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", + "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.5", + "@babel/parser": "^7.26.7", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.26.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", + "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", + "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", + "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", + "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.4.3.tgz", + "integrity": "sha512-hlyOzo2ObarllAOeT1ZSAusADE5NZNencUeIvXrdQ1Na+FL1lcznhbxfV5He1KqGiuR8Az3xtCUcYKwMVGFdzg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.4.3.tgz", + "integrity": "sha512-3IY9LpjkwIJVgL/SkZQKKCUcumdHdQEsJaIavvsQze2QEztBt0HJ17naToN0DBBdhKdtwX5xXrfD6ZFUeWWk8g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.4.3", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.4.3.tgz", + "integrity": "sha512-ubtQjplbWneIEU8Y+4b2VA0CDBlyH5I3AmVFGmsLyDe/bf0ubxav5t11c8Afem6rkSFWPlZA2DilxmGka1xiKQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/core-downloads-tracker": "^6.4.3", + "@mui/system": "^6.4.3", + "@mui/types": "^7.2.21", + "@mui/utils": "^6.4.3", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.0.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^6.4.3", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.4.3.tgz", + "integrity": "sha512-7x9HaNwDCeoERc4BoEWLieuzKzXu5ZrhRnEM6AUcRXUScQLvF1NFkTlP59+IJfTbEMgcGg1wWHApyoqcksrBpQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/utils": "^6.4.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.4.3.tgz", + "integrity": "sha512-OC402VfK+ra2+f12Gef8maY7Y9n7B6CZcoQ9u7mIkh/7PKwW/xH81xwX+yW+Ak1zBT3HYcVjh2X82k5cKMFGoQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.4.3.tgz", + "integrity": "sha512-Q0iDwnH3+xoxQ0pqVbt8hFdzhq1g2XzzR4Y5pVcICTNtoCLJmpJS3vI4y/OIM1FHFmpfmiEC2IRIq7YcZ8nsmg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/private-theming": "^6.4.3", + "@mui/styled-engine": "^6.4.3", + "@mui/types": "^7.2.21", + "@mui/utils": "^6.4.3", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.21", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.21.tgz", + "integrity": "sha512-6HstngiUxNqLU+/DPqlUJDIPbzUBxIVHb1MmXP0eTWDIROiCR2viugXpEif0PPe2mLqqakPzzRClWAnK+8UJww==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.4.3.tgz", + "integrity": "sha512-jxHRHh3BqVXE9ABxDm+Tc3wlBooYz/4XPa0+4AI+iF38rV1/+btJmSUgG4shDtSWVs/I97aDn5jBCt6SF2Uq2A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/types": "^7.2.21", + "@types/prop-types": "^15.7.14", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts/-/x-charts-7.25.0.tgz", + "integrity": "sha512-+DhnojHrVTt8RsTgq8AztzdFpW1kzOgiBdo0Pkl0DyxVdaKELC5QaetFwim9nIxT2zmU/RmiBcOU+qbqmQpFNA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-charts-vendor": "7.20.0", + "@mui/x-internals": "7.25.0", + "@react-spring/rafz": "^9.7.5", + "@react-spring/web": "^9.7.5", + "clsx": "^2.1.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-charts-vendor": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@mui/x-charts-vendor/-/x-charts-vendor-7.20.0.tgz", + "integrity": "sha512-pzlh7z/7KKs5o0Kk0oPcB+sY0+Dg7Q7RzqQowDQjpy5Slz6qqGsgOB5YUzn0L+2yRmvASc4Pe0914Ao3tMBogg==", + "license": "MIT AND ISC", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@types/d3-color": "^3.1.3", + "@types/d3-delaunay": "^6.0.4", + "@types/d3-interpolate": "^3.0.4", + "@types/d3-scale": "^4.0.8", + "@types/d3-shape": "^3.1.6", + "@types/d3-time": "^3.0.3", + "d3-color": "^3.1.0", + "d3-delaunay": "^6.0.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.2.0", + "d3-time": "^3.1.0", + "delaunator": "^5.0.1", + "robust-predicates": "^3.0.2" + } + }, + "node_modules/@mui/x-data-grid": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-7.25.0.tgz", + "integrity": "sha512-e9ZLbCgnDiADFiDyXo91ucZFHEMkKBNpwpkaTq5KohzefJfMpMQjTEbJeueSfBG2G1Q1Am2TPeBqrNeReIA7RQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-internals": "7.25.0", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "reselect": "^5.1.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.25.0.tgz", + "integrity": "sha512-t62OSFAKwj7KYQ8KcwTuKj6OgDuLQPSe4QUJcKDzD9rEhRIJVRUw2x27gBSdcls4l0PTrba19TghvDxCZprriw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-internals": "7.25.0", + "@types/react-transition-group": "^4.4.11", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "date-fns": "^2.25.0 || ^3.2.0 || ^4.0.0", + "date-fns-jalali": "^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2 || ^3.0.0", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@mui/x-internals": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.25.0.tgz", + "integrity": "sha512-tBUN54YznAkmtCIRAOl35Kgl0MjFDIjUbzIrbWRgVSIR3QJ8bXnVSkiRBi+P91SZEl9+ZW0rDj+osq7xFJV0kg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@mui/x-tree-view": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@mui/x-tree-view/-/x-tree-view-7.25.0.tgz", + "integrity": "sha512-DWBMWzfMtIBXMvGCb0WdEeo4H8TLleKeMExzX0L3zvo87Ootvmcin9d7x1q1ZABekT6wREVl3+pVTEoBzcFWug==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.7", + "@mui/utils": "^5.16.6 || ^6.0.0", + "@mui/x-internals": "7.25.0", + "@types/react-transition-group": "^4.4.11", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.15.14 || ^6.0.0", + "@mui/system": "^5.15.14 || ^6.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@react-spring/animated": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", + "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", + "license": "MIT", + "dependencies": { + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", + "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", + "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", + "license": "MIT" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", + "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", + "license": "MIT", + "dependencies": { + "@react-spring/rafz": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", + "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", + "license": "MIT" + }, + "node_modules/@react-spring/web": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.5.tgz", + "integrity": "sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/core": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@reduxjs/toolkit": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.5.0.tgz", + "integrity": "sha512-awNe2oTodsZ6LmRqmkFhtb/KH03hUhxOamEQy411m3Njj3BbFvoBovxo4Q1cBWnV1ErprVj9MlF0UPXkng0eyg==", + "license": "MIT", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", + "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", + "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", + "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", + "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", + "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", + "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", + "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", + "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", + "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", + "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", + "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", + "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", + "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", + "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", + "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", + "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", + "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", + "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", + "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@swc/core": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.3.tgz", + "integrity": "sha512-2yjqCcsBx6SNBQZIYNlwxED9aYXW/7QBZyr8LYAxTx5bzmoNhKiClYbsNLe1NJ6ccf5uSbcInw12PjXLduNEdQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.17" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.10.3", + "@swc/core-darwin-x64": "1.10.3", + "@swc/core-linux-arm-gnueabihf": "1.10.3", + "@swc/core-linux-arm64-gnu": "1.10.3", + "@swc/core-linux-arm64-musl": "1.10.3", + "@swc/core-linux-x64-gnu": "1.10.3", + "@swc/core-linux-x64-musl": "1.10.3", + "@swc/core-win32-arm64-msvc": "1.10.3", + "@swc/core-win32-ia32-msvc": "1.10.3", + "@swc/core-win32-x64-msvc": "1.10.3" + }, + "peerDependencies": { + "@swc/helpers": "*" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.3.tgz", + "integrity": "sha512-LFFCxAUKBy69AUE+01rgazQcafIXrYs6tBa9SyKPR51ft6Tp66dAVrWg9MTykaWskuXEe80LPUvUw1ga3bOH3A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.3.tgz", + "integrity": "sha512-yZNv1+yPg0GvYdThsMI8WpaPRAPuw2gQDMdgijLFfRcRlr2l1sTWsDHqGd7QMTx+acYM3uB537gyd31WjUAwlQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.3.tgz", + "integrity": "sha512-Qa6hu5ASoKV4rcYUBGG3y3z+9UT042KAG4A7ivqqYQFcMfkB4NbZb5So2YWOpUc0/5YlSVkgL22h3Mbj5EXy7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.3.tgz", + "integrity": "sha512-BGnoZrmo0nlkXrOxVHk5U3j9u4BuquFviC+LvMe+HrDc5YLVe1gSXMUSBKhIz9MY9uFgxXW977TnB1XjLSKe5Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.3.tgz", + "integrity": "sha512-L07/4zKnIY2S/00bE+Yn3oEHkyGjWmGGE8Ta4luVCL+00s04EIwMoE1Hc8E8xFB5zLew5ViKFc5kNb5YZ/tRFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.3.tgz", + "integrity": "sha512-cvTCekY4u0fBIDNfhv/2UxcOXqH4XJE2iNxKuQejS5KIapFJwrZ+fRQ2lha3+yopI/d2p96BlBEWTAcBzeTntw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.3.tgz", + "integrity": "sha512-h9kUOTrSSpY9JNc41a+NMAwK62USk/pvNE9Fi/Pfoklmlf9j9j8gRCitqvHpmZcEF4PPIsoMdiGetDipTwvWlw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.3.tgz", + "integrity": "sha512-iHOmLYkZYn3r1Ff4rfyczdrYGt/wVIWyY0t8swsO9o1TE+zmucGFZuYZzgj3ng8Kp4sojJrydAGz8TINQZDBzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.3.tgz", + "integrity": "sha512-4SqLSE4Ozh8SxuVuHIZhkSyJQru5+WbQMRs5ggLRqeUy3vkUPHOAFAY3oMwDJUN6BwbAr8+664TmdrMwaWh8Ng==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.3.tgz", + "integrity": "sha512-jTyf/IbNq7NVyqqDIEDzgjALjWu1IMfXKLXXAJArreklIMzkfHU1sV32ZJLOBmRKPyslCoalxIAU+hTx4reUTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@swc/types": { + "version": "0.1.17", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.17.tgz", + "integrity": "sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3" + } + }, + "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" + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "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", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "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/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.14", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz", + "integrity": "sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.18", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.18.tgz", + "integrity": "sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.5", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.5.tgz", + "integrity": "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.2.tgz", + "integrity": "sha512-adig4SzPLjeQ0Tm+jvsozSGiCliI2ajeURDGHjZ2llnA+A67HihCQ+a3amtPhUakd1GlwHxSRvzOZktbEvhPPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.18.2", + "@typescript-eslint/type-utils": "8.18.2", + "@typescript-eslint/utils": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.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.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.18.2.tgz", + "integrity": "sha512-y7tcq4StgxQD4mDr9+Jb26dZ+HTZ/SkfqpXSiqeUXZHxOUyjWDKsmwKhJ0/tApR08DgOhrFAoAhyB80/p3ViuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.18.2", + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/typescript-estree": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2", + "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 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.18.2.tgz", + "integrity": "sha512-YJFSfbd0CJjy14r/EvWapYgV4R5CHzptssoag2M7y3Ra7XNta6GPAJPPP5KGB9j14viYXyrzRO5GkX7CRfo8/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.18.2.tgz", + "integrity": "sha512-AB/Wr1Lz31bzHfGm/jgbFR0VB0SML/hd2P1yxzKDM48YmP7vbyJNHRExUE/wZsQj2wUCvbWH8poNHFuxLqCTnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.18.2", + "@typescript-eslint/utils": "8.18.2", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "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 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.18.2.tgz", + "integrity": "sha512-Z/zblEPp8cIvmEn6+tPDIHUbRu/0z5lqZ+NvolL5SvXWT5rQy7+Nch83M0++XzO0XrWRFWECgOAyE8bsJTl1GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.2.tgz", + "integrity": "sha512-WXAVt595HjpmlfH4crSdM/1bcsqh+1weFRWIa9XMTx/XHZ9TCKMcr725tLYqWOgzKdeDrqVHxFotrvWcEsk2Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/visitor-keys": "8.18.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "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 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.18.2.tgz", + "integrity": "sha512-Cr4A0H7DtVIPkauj4sTSXVl+VBWewE9/o40KcF3TV9aqDEOWoXF3/+oRXNby3DYzZeCATvbdksYsGZzplwnK/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.18.2", + "@typescript-eslint/types": "8.18.2", + "@typescript-eslint/typescript-estree": "8.18.2" + }, + "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 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.2.tgz", + "integrity": "sha512-zORcwn4C3trOWiCqFQP1x6G3xTRyZ1LYydnj51cRnJ6hxBlr/cKPckk+PKPUw/fXmvfKTcw7bwY3w9izgx5jZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.18.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react-swc": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.2.tgz", + "integrity": "sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@swc/core": "^1.7.26" + }, + "peerDependencies": { + "vite": "^4 || ^5 || ^6" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "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": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "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", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "license": "ISC", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "license": "ISC", + "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", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "license": "ISC", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", + "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.17.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.16.tgz", + "integrity": "sha512-slterMlxAhov/DZO8NScf6mEeMBBXodFUolijDvrtTxyezyLoTQaa73FyYus/VbTdftd8wBgBxPMRk3poleXNQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-is": { + "version": "19.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.0.0.tgz", + "integrity": "sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==", + "license": "MIT" + }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", + "license": "Unlicense" + }, + "node_modules/rollup": { + "version": "4.29.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", + "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.29.1", + "@rollup/rollup-android-arm64": "4.29.1", + "@rollup/rollup-darwin-arm64": "4.29.1", + "@rollup/rollup-darwin-x64": "4.29.1", + "@rollup/rollup-freebsd-arm64": "4.29.1", + "@rollup/rollup-freebsd-x64": "4.29.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", + "@rollup/rollup-linux-arm-musleabihf": "4.29.1", + "@rollup/rollup-linux-arm64-gnu": "4.29.1", + "@rollup/rollup-linux-arm64-musl": "4.29.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", + "@rollup/rollup-linux-riscv64-gnu": "4.29.1", + "@rollup/rollup-linux-s390x-gnu": "4.29.1", + "@rollup/rollup-linux-x64-gnu": "4.29.1", + "@rollup/rollup-linux-x64-musl": "4.29.1", + "@rollup/rollup-win32-arm64-msvc": "4.29.1", + "@rollup/rollup-win32-ia32-msvc": "4.29.1", + "@rollup/rollup-win32-x64-msvc": "4.29.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/to-regex-range": { + "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, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.18.2.tgz", + "integrity": "sha512-KuXezG6jHkvC3MvizeXgupZzaG5wjhU3yE8E7e6viOvAvD9xAWYp8/vy0WULTGe9DYDWcQu7aW03YIV3mSitrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.18.2", + "@typescript-eslint/parser": "8.18.2", + "@typescript-eslint/utils": "8.18.2" + }, + "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 <5.8.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vite": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.6.tgz", + "integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/webClient/package.json b/webClient/package.json new file mode 100644 index 0000000..cab972b --- /dev/null +++ b/webClient/package.json @@ -0,0 +1,40 @@ +{ + "name": "location_hub_ui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", + "@mui/icons-material": "^6.4.3", + "@mui/material": "^6.4.3", + "@mui/x-charts": "^7.25.0", + "@mui/x-data-grid": "^7.25.0", + "@mui/x-date-pickers": "^7.25.0", + "@mui/x-tree-view": "^7.25.0", + "@reduxjs/toolkit": "^2.5.0", + "dayjs": "^1.11.13", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-redux": "^9.2.0" + }, + "devDependencies": { + "@eslint/js": "^9.17.0", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-react-swc": "^3.5.0", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^15.14.0", + "typescript": "~5.6.2", + "typescript-eslint": "^8.18.2", + "vite": "^6.0.5" + } +} diff --git a/webClient/public/vite.svg b/webClient/public/vite.svg new file mode 100644 index 0000000..a77ffb4 --- /dev/null +++ b/webClient/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/webClient/src/App.tsx b/webClient/src/App.tsx new file mode 100644 index 0000000..b0c4c1d --- /dev/null +++ b/webClient/src/App.tsx @@ -0,0 +1,56 @@ +import Box from "@mui/material/Box"; +import CssBaseline from "@mui/material/CssBaseline"; +import Stack from "@mui/material/Stack"; +import { alpha } from "@mui/material/styles"; +import AppNavbar from "./components/AppNavbar"; +import Header from "./components/Header"; +import SideMenu from "./components/SideMenu"; +import AppTheme from "./shared-theme/AppTheme"; +import { + chartsCustomizations, + dataGridCustomizations, + datePickersCustomizations, + treeViewCustomizations, +} from "./theme/customizations"; + +const xThemeComponents = { + ...chartsCustomizations, + ...dataGridCustomizations, + ...datePickersCustomizations, + ...treeViewCustomizations, +}; + +export default function Dashboard(props: { disableCustomTheme?: boolean }) { + return ( + + + + + + {/* Main content */} + ({ + flexGrow: 1, + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.background.defaultChannel} / 1)` + : alpha(theme.palette.background.default, 1), + overflow: "auto", + })} + > + +
+ + + + + ); +} diff --git a/webClient/src/app/apiBaseQuery.ts b/webClient/src/app/apiBaseQuery.ts new file mode 100644 index 0000000..b4b98a9 --- /dev/null +++ b/webClient/src/app/apiBaseQuery.ts @@ -0,0 +1,5 @@ +import { fetchBaseQuery } from "@reduxjs/toolkit/query/react"; + +const BASE_URL = import.meta.env.VITE_BASE_URL; + +export const baseQuery = fetchBaseQuery({ baseUrl: BASE_URL }); diff --git a/webClient/src/app/store.ts b/webClient/src/app/store.ts new file mode 100644 index 0000000..132301b --- /dev/null +++ b/webClient/src/app/store.ts @@ -0,0 +1,14 @@ +import { configureStore } from "@reduxjs/toolkit"; +import { locationApi } from "../features/locations/locationApi"; + +export const store = configureStore({ + reducer: { + [locationApi.reducerPath]: locationApi.reducer, + }, + + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(locationApi.middleware), +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; diff --git a/webClient/src/components/AppNavbar.tsx b/webClient/src/components/AppNavbar.tsx new file mode 100644 index 0000000..5b0b639 --- /dev/null +++ b/webClient/src/components/AppNavbar.tsx @@ -0,0 +1,107 @@ +import DashboardRoundedIcon from "@mui/icons-material/DashboardRounded"; +import MenuRoundedIcon from "@mui/icons-material/MenuRounded"; +import AppBar from "@mui/material/AppBar"; +import Box from "@mui/material/Box"; +import Stack from "@mui/material/Stack"; +import { styled } from "@mui/material/styles"; +import { tabsClasses } from "@mui/material/Tabs"; +import MuiToolbar from "@mui/material/Toolbar"; +import Typography from "@mui/material/Typography"; +import * as React from "react"; +import MenuButton from "./MenuButton"; +import SideMenuMobile from "./SideMenuMobile"; + +const Toolbar = styled(MuiToolbar)({ + width: "100%", + padding: "12px", + display: "flex", + flexDirection: "column", + alignItems: "start", + justifyContent: "center", + gap: "12px", + flexShrink: 0, + [`& ${tabsClasses.flexContainer}`]: { + gap: "8px", + p: "8px", + pb: 0, + }, +}); + +export default function AppNavbar() { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = (newOpen: boolean) => () => { + setOpen(newOpen); + }; + + return ( + + + + + + + Dashboard + + + + + + + + + + ); +} + +export function CustomIcon() { + return ( + + + + ); +} diff --git a/webClient/src/components/CardAlert.tsx b/webClient/src/components/CardAlert.tsx new file mode 100644 index 0000000..ff41ac7 --- /dev/null +++ b/webClient/src/components/CardAlert.tsx @@ -0,0 +1,24 @@ +import AutoAwesomeRoundedIcon from "@mui/icons-material/AutoAwesomeRounded"; +import Button from "@mui/material/Button"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; + +export default function CardAlert() { + return ( + + + + + Plan about to expire + + + Enjoy 10% off when renewing your plan today. + + + + + ); +} diff --git a/webClient/src/components/CustomDatePicker.tsx b/webClient/src/components/CustomDatePicker.tsx new file mode 100644 index 0000000..32985cc --- /dev/null +++ b/webClient/src/components/CustomDatePicker.tsx @@ -0,0 +1,78 @@ +import * as React from "react"; +import dayjs, { Dayjs } from "dayjs"; +import Button from "@mui/material/Button"; +import CalendarTodayRoundedIcon from "@mui/icons-material/CalendarTodayRounded"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import { UseDateFieldProps } from "@mui/x-date-pickers/DateField"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { + BaseSingleInputFieldProps, + DateValidationError, + FieldSection, +} from "@mui/x-date-pickers/models"; + +interface ButtonFieldProps + extends UseDateFieldProps, + BaseSingleInputFieldProps< + Dayjs | null, + Dayjs, + FieldSection, + false, + DateValidationError + > { + setOpen?: React.Dispatch>; +} + +function ButtonField(props: ButtonFieldProps) { + const { + setOpen, + label, + id, + disabled, + InputProps: { ref } = {}, + inputProps: { "aria-label": ariaLabel } = {}, + } = props; + + return ( + + ); +} + +export default function CustomDatePicker() { + const [value, setValue] = React.useState(dayjs("2023-04-17")); + const [open, setOpen] = React.useState(false); + + return ( + + setValue(newValue)} + slots={{ field: ButtonField }} + slotProps={{ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + field: { setOpen } as any, + nextIconButton: { size: "small" }, + previousIconButton: { size: "small" }, + }} + open={open} + onClose={() => setOpen(false)} + onOpen={() => setOpen(true)} + views={["day", "month", "year"]} + /> + + ); +} diff --git a/webClient/src/components/Header.tsx b/webClient/src/components/Header.tsx new file mode 100644 index 0000000..572a0d8 --- /dev/null +++ b/webClient/src/components/Header.tsx @@ -0,0 +1,35 @@ +import NotificationsRoundedIcon from "@mui/icons-material/NotificationsRounded"; +import Stack from "@mui/material/Stack"; +import CustomDatePicker from "./CustomDatePicker"; +import MenuButton from "./MenuButton"; +import NavbarBreadcrumbs from "./NavbarBreadcrumbs"; + +import ColorModeIconDropdown from "../shared-theme/ColorModeIconDropdown"; +import Search from "./Search"; + +export default function Header() { + return ( + + + + + + + + + + + + ); +} diff --git a/webClient/src/components/MenuButton.tsx b/webClient/src/components/MenuButton.tsx new file mode 100644 index 0000000..e26f885 --- /dev/null +++ b/webClient/src/components/MenuButton.tsx @@ -0,0 +1,22 @@ +import Badge, { badgeClasses } from "@mui/material/Badge"; +import IconButton, { IconButtonProps } from "@mui/material/IconButton"; + +export interface MenuButtonProps extends IconButtonProps { + showBadge?: boolean; +} + +export default function MenuButton({ + showBadge = false, + ...props +}: MenuButtonProps) { + return ( + + + + ); +} diff --git a/webClient/src/components/MenuContent.tsx b/webClient/src/components/MenuContent.tsx new file mode 100644 index 0000000..bbbbb61 --- /dev/null +++ b/webClient/src/components/MenuContent.tsx @@ -0,0 +1,54 @@ +import AnalyticsRoundedIcon from "@mui/icons-material/AnalyticsRounded"; +import AssignmentRoundedIcon from "@mui/icons-material/AssignmentRounded"; +import HelpRoundedIcon from "@mui/icons-material/HelpRounded"; +import HomeRoundedIcon from "@mui/icons-material/HomeRounded"; +import InfoRoundedIcon from "@mui/icons-material/InfoRounded"; +import PeopleRoundedIcon from "@mui/icons-material/PeopleRounded"; +import SettingsRoundedIcon from "@mui/icons-material/SettingsRounded"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import ListItemText from "@mui/material/ListItemText"; +import Stack from "@mui/material/Stack"; + +const mainListItems = [ + { text: "Home", icon: }, + { text: "Analytics", icon: }, + { text: "Clients", icon: }, + { text: "Tasks", icon: }, +]; + +const secondaryListItems = [ + { text: "Settings", icon: }, + { text: "About", icon: }, + { text: "Feedback", icon: }, +]; + +export default function MenuContent() { + return ( + + + {mainListItems.map((item, index) => ( + + + {item.icon} + + + + ))} + + + + {secondaryListItems.map((item, index) => ( + + + {item.icon} + + + + ))} + + + ); +} diff --git a/webClient/src/components/NavbarBreadcrumbs.tsx b/webClient/src/components/NavbarBreadcrumbs.tsx new file mode 100644 index 0000000..5d7c6b6 --- /dev/null +++ b/webClient/src/components/NavbarBreadcrumbs.tsx @@ -0,0 +1,32 @@ +import NavigateNextRoundedIcon from "@mui/icons-material/NavigateNextRounded"; +import Breadcrumbs, { breadcrumbsClasses } from "@mui/material/Breadcrumbs"; +import { styled } from "@mui/material/styles"; +import Typography from "@mui/material/Typography"; + +const StyledBreadcrumbs = styled(Breadcrumbs)(({ theme }) => ({ + margin: theme.spacing(1, 0), + [`& .${breadcrumbsClasses.separator}`]: { + color: (theme.vars || theme).palette.action.disabled, + margin: 1, + }, + [`& .${breadcrumbsClasses.ol}`]: { + alignItems: "center", + }, +})); + +export default function NavbarBreadcrumbs() { + return ( + } + > + Dashboard + + Home + + + ); +} diff --git a/webClient/src/components/OptionsMenu.tsx b/webClient/src/components/OptionsMenu.tsx new file mode 100644 index 0000000..8c1f555 --- /dev/null +++ b/webClient/src/components/OptionsMenu.tsx @@ -0,0 +1,79 @@ +import * as React from 'react'; +import { styled } from '@mui/material/styles'; +import Divider, { dividerClasses } from '@mui/material/Divider'; +import Menu from '@mui/material/Menu'; +import MuiMenuItem from '@mui/material/MenuItem'; +import { paperClasses } from '@mui/material/Paper'; +import { listClasses } from '@mui/material/List'; +import ListItemText from '@mui/material/ListItemText'; +import ListItemIcon, { listItemIconClasses } from '@mui/material/ListItemIcon'; +import LogoutRoundedIcon from '@mui/icons-material/LogoutRounded'; +import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded'; +import MenuButton from './MenuButton'; + +const MenuItem = styled(MuiMenuItem)({ + margin: '2px 0', +}); + +export default function OptionsMenu() { + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + return ( + + + + + + Profile + My account + + Add another account + Settings + + + Logout + + + + + + + ); +} diff --git a/webClient/src/components/Search.tsx b/webClient/src/components/Search.tsx new file mode 100644 index 0000000..37d2523 --- /dev/null +++ b/webClient/src/components/Search.tsx @@ -0,0 +1,25 @@ +import SearchRoundedIcon from "@mui/icons-material/SearchRounded"; +import FormControl from "@mui/material/FormControl"; +import InputAdornment from "@mui/material/InputAdornment"; +import OutlinedInput from "@mui/material/OutlinedInput"; + +export default function Search() { + return ( + + + + + } + inputProps={{ + "aria-label": "search", + }} + /> + + ); +} diff --git a/webClient/src/components/SelectContent.tsx b/webClient/src/components/SelectContent.tsx new file mode 100644 index 0000000..b103ab9 --- /dev/null +++ b/webClient/src/components/SelectContent.tsx @@ -0,0 +1,102 @@ +import * as React from 'react'; +import MuiAvatar from '@mui/material/Avatar'; +import MuiListItemAvatar from '@mui/material/ListItemAvatar'; +import MenuItem from '@mui/material/MenuItem'; +import ListItemText from '@mui/material/ListItemText'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListSubheader from '@mui/material/ListSubheader'; +import Select, { SelectChangeEvent, selectClasses } from '@mui/material/Select'; +import Divider from '@mui/material/Divider'; +import { styled } from '@mui/material/styles'; +import AddRoundedIcon from '@mui/icons-material/AddRounded'; +import DevicesRoundedIcon from '@mui/icons-material/DevicesRounded'; +import SmartphoneRoundedIcon from '@mui/icons-material/SmartphoneRounded'; +import ConstructionRoundedIcon from '@mui/icons-material/ConstructionRounded'; + +const Avatar = styled(MuiAvatar)(({ theme }) => ({ + width: 28, + height: 28, + backgroundColor: (theme.vars || theme).palette.background.paper, + color: (theme.vars || theme).palette.text.secondary, + border: `1px solid ${(theme.vars || theme).palette.divider}`, +})); + +const ListItemAvatar = styled(MuiListItemAvatar)({ + minWidth: 0, + marginRight: 12, +}); + +export default function SelectContent() { + const [company, setCompany] = React.useState(''); + + const handleChange = (event: SelectChangeEvent) => { + setCompany(event.target.value as string); + }; + + return ( + + ); +} diff --git a/webClient/src/components/SideMenu.tsx b/webClient/src/components/SideMenu.tsx new file mode 100644 index 0000000..f5b1317 --- /dev/null +++ b/webClient/src/components/SideMenu.tsx @@ -0,0 +1,80 @@ +import Avatar from "@mui/material/Avatar"; +import Box from "@mui/material/Box"; +import Divider from "@mui/material/Divider"; +import MuiDrawer, { drawerClasses } from "@mui/material/Drawer"; +import Stack from "@mui/material/Stack"; +import { styled } from "@mui/material/styles"; +import Typography from "@mui/material/Typography"; +import CardAlert from "./CardAlert"; +import MenuContent from "./MenuContent"; +import OptionsMenu from "./OptionsMenu"; +import SelectContent from "./SelectContent"; + +const drawerWidth = 240; + +const Drawer = styled(MuiDrawer)({ + width: drawerWidth, + flexShrink: 0, + boxSizing: "border-box", + mt: 10, + [`& .${drawerClasses.paper}`]: { + width: drawerWidth, + boxSizing: "border-box", + }, +}); + +export default function SideMenu() { + return ( + + + + + + + + + + + + Riley Carter + + + riley@email.com + + + + + + ); +} diff --git a/webClient/src/components/SideMenuMobile.tsx b/webClient/src/components/SideMenuMobile.tsx new file mode 100644 index 0000000..ed8d286 --- /dev/null +++ b/webClient/src/components/SideMenuMobile.tsx @@ -0,0 +1,79 @@ +import LogoutRoundedIcon from "@mui/icons-material/LogoutRounded"; +import NotificationsRoundedIcon from "@mui/icons-material/NotificationsRounded"; +import Avatar from "@mui/material/Avatar"; +import Button from "@mui/material/Button"; +import Divider from "@mui/material/Divider"; +import Drawer, { drawerClasses } from "@mui/material/Drawer"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; + +import CardAlert from "./CardAlert"; +import MenuButton from "./MenuButton"; +import MenuContent from "./MenuContent"; + +interface SideMenuMobileProps { + open: boolean | undefined; + toggleDrawer: (newOpen: boolean) => () => void; +} + +export default function SideMenuMobile({ + open, + toggleDrawer, +}: SideMenuMobileProps) { + return ( + theme.zIndex.drawer + 1, + [`& .${drawerClasses.paper}`]: { + backgroundImage: "none", + backgroundColor: "background.paper", + }, + }} + > + + + + + + Riley Carter + + + + + + + + + + + + + + + + + + ); +} diff --git a/webClient/src/features/locations/locationApi.ts b/webClient/src/features/locations/locationApi.ts new file mode 100644 index 0000000..897a8be --- /dev/null +++ b/webClient/src/features/locations/locationApi.ts @@ -0,0 +1,47 @@ +import { createApi } from "@reduxjs/toolkit/query/react"; +import { baseQuery } from "../../app/apiBaseQuery"; +import { Location } from "../../models/location"; + +export const locationApi = createApi({ + reducerPath: "locationApi", + baseQuery, + endpoints: (builder) => ({ + getLocations: builder.query({ + query: () => "/locations", + }), + getLocationById: builder.query({ + query: (id) => `/locations/${id}`, + }), + createLocation: builder.mutation>({ + query: (newLocation) => ({ + url: "/locations", + method: "POST", + body: newLocation, + }), + }), + updateLocation: builder.mutation< + Location, + { id: string; location: Partial } + >({ + query: ({ id, location }) => ({ + url: `/locations/${id}`, + method: "PUT", + body: location, + }), + }), + deleteLocation: builder.mutation({ + query: (id) => ({ + url: `/locations/${id}`, + method: "DELETE", + }), + }), + }), +}); + +export const { + useGetLocationsQuery, + useGetLocationByIdQuery, + useCreateLocationMutation, + useUpdateLocationMutation, + useDeleteLocationMutation, +} = locationApi; diff --git a/webClient/src/main.tsx b/webClient/src/main.tsx new file mode 100644 index 0000000..d072210 --- /dev/null +++ b/webClient/src/main.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + +); diff --git a/webClient/src/models/location.ts b/webClient/src/models/location.ts new file mode 100644 index 0000000..b9a7a15 --- /dev/null +++ b/webClient/src/models/location.ts @@ -0,0 +1,12 @@ +export interface Location { + location_id: string; + lp_ttn_end_device_uplinks_id: string; + wifi_latitude: number; + wifi_longitude: number; + gnss_latitude: number; + gnss_longitude: number; + ttn_gw_latitude: number; + ttn_gw_longitude: number; + created_at_utc: string; + updated_at_utc: string; +} diff --git a/webClient/src/shared-theme/AppTheme.tsx b/webClient/src/shared-theme/AppTheme.tsx new file mode 100644 index 0000000..6aa6f02 --- /dev/null +++ b/webClient/src/shared-theme/AppTheme.tsx @@ -0,0 +1,53 @@ +import type { ThemeOptions } from "@mui/material/styles"; +import { ThemeProvider, createTheme } from "@mui/material/styles"; +import * as React from "react"; +import { dataDisplayCustomizations } from "./customizations/dataDisplay"; +import { feedbackCustomizations } from "./customizations/feedback"; +import { inputsCustomizations } from "./customizations/inputs"; +import { navigationCustomizations } from "./customizations/navigation"; +import { surfacesCustomizations } from "./customizations/surfaces"; +import { colorSchemes, shadows, shape, typography } from "./themePrimitives"; + +interface AppThemeProps { + children: React.ReactNode; + /** + * This is for the docs site. You can ignore it or remove it. + */ + disableCustomTheme?: boolean; + themeComponents?: ThemeOptions["components"]; +} + +export default function AppTheme(props: AppThemeProps) { + const { children, disableCustomTheme, themeComponents } = props; + const theme = React.useMemo(() => { + return disableCustomTheme + ? {} + : createTheme({ + // For more details about CSS variables configuration, see https://mui.com/material-ui/customization/css-theme-variables/configuration/ + cssVariables: { + colorSchemeSelector: "data-mui-color-scheme", + cssVarPrefix: "template", + }, + colorSchemes, // Recently added in v6 for building light & dark mode app, see https://mui.com/material-ui/customization/palette/#color-schemes + typography, + shadows, + shape, + components: { + ...inputsCustomizations, + ...dataDisplayCustomizations, + ...feedbackCustomizations, + ...navigationCustomizations, + ...surfacesCustomizations, + ...themeComponents, + }, + }); + }, [disableCustomTheme, themeComponents]); + if (disableCustomTheme) { + return {children}; + } + return ( + + {children} + + ); +} diff --git a/webClient/src/shared-theme/ColorModeIconDropdown.tsx b/webClient/src/shared-theme/ColorModeIconDropdown.tsx new file mode 100644 index 0000000..a4b6edb --- /dev/null +++ b/webClient/src/shared-theme/ColorModeIconDropdown.tsx @@ -0,0 +1,89 @@ +import DarkModeIcon from "@mui/icons-material/DarkModeRounded"; +import LightModeIcon from "@mui/icons-material/LightModeRounded"; +import Box from "@mui/material/Box"; +import IconButton, { IconButtonOwnProps } from "@mui/material/IconButton"; +import Menu from "@mui/material/Menu"; +import MenuItem from "@mui/material/MenuItem"; +import { useColorScheme } from "@mui/material/styles"; +import * as React from "react"; + +export default function ColorModeIconDropdown(props: IconButtonOwnProps) { + const { mode, systemMode, setMode } = useColorScheme(); + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + const handleMode = (targetMode: "system" | "light" | "dark") => () => { + setMode(targetMode); + handleClose(); + }; + if (!mode) { + return ( + ({ + verticalAlign: "bottom", + display: "inline-flex", + width: "2.25rem", + height: "2.25rem", + borderRadius: (theme.vars || theme).shape.borderRadius, + border: "1px solid", + borderColor: (theme.vars || theme).palette.divider, + })} + /> + ); + } + const resolvedMode = (systemMode || mode) as "light" | "dark"; + const icon = { + light: , + dark: , + }[resolvedMode]; + return ( + + + {icon} + + + + System + + + Light + + + Dark + + + + ); +} diff --git a/webClient/src/shared-theme/customizations/dataDisplay.tsx b/webClient/src/shared-theme/customizations/dataDisplay.tsx new file mode 100644 index 0000000..33153d9 --- /dev/null +++ b/webClient/src/shared-theme/customizations/dataDisplay.tsx @@ -0,0 +1,233 @@ +import { Theme, alpha, Components } from '@mui/material/styles'; +import { svgIconClasses } from '@mui/material/SvgIcon'; +import { typographyClasses } from '@mui/material/Typography'; +import { buttonBaseClasses } from '@mui/material/ButtonBase'; +import { chipClasses } from '@mui/material/Chip'; +import { iconButtonClasses } from '@mui/material/IconButton'; +import { gray, red, green } from '../themePrimitives'; + +/* eslint-disable import/prefer-default-export */ +export const dataDisplayCustomizations: Components = { + MuiList: { + styleOverrides: { + root: { + padding: '8px', + display: 'flex', + flexDirection: 'column', + gap: 0, + }, + }, + }, + MuiListItem: { + styleOverrides: { + root: ({ theme }) => ({ + [`& .${svgIconClasses.root}`]: { + width: '1rem', + height: '1rem', + color: (theme.vars || theme).palette.text.secondary, + }, + [`& .${typographyClasses.root}`]: { + fontWeight: 500, + }, + [`& .${buttonBaseClasses.root}`]: { + display: 'flex', + gap: 8, + padding: '2px 8px', + borderRadius: (theme.vars || theme).shape.borderRadius, + opacity: 0.7, + '&.Mui-selected': { + opacity: 1, + backgroundColor: alpha(theme.palette.action.selected, 0.3), + [`& .${svgIconClasses.root}`]: { + color: (theme.vars || theme).palette.text.primary, + }, + '&:focus-visible': { + backgroundColor: alpha(theme.palette.action.selected, 0.3), + }, + '&:hover': { + backgroundColor: alpha(theme.palette.action.selected, 0.5), + }, + }, + '&:focus-visible': { + backgroundColor: 'transparent', + }, + }, + }), + }, + }, + MuiListItemText: { + styleOverrides: { + primary: ({ theme }) => ({ + fontSize: theme.typography.body2.fontSize, + fontWeight: 500, + lineHeight: theme.typography.body2.lineHeight, + }), + secondary: ({ theme }) => ({ + fontSize: theme.typography.caption.fontSize, + lineHeight: theme.typography.caption.lineHeight, + }), + }, + }, + MuiListSubheader: { + styleOverrides: { + root: ({ theme }) => ({ + backgroundColor: 'transparent', + padding: '4px 8px', + fontSize: theme.typography.caption.fontSize, + fontWeight: 500, + lineHeight: theme.typography.caption.lineHeight, + }), + }, + }, + MuiListItemIcon: { + styleOverrides: { + root: { + minWidth: 0, + }, + }, + }, + MuiChip: { + defaultProps: { + size: 'small', + }, + styleOverrides: { + root: ({ theme }) => ({ + border: '1px solid', + borderRadius: '999px', + [`& .${chipClasses.label}`]: { + fontWeight: 600, + }, + variants: [ + { + props: { + color: 'default', + }, + style: { + borderColor: gray[200], + backgroundColor: gray[100], + [`& .${chipClasses.label}`]: { + color: gray[500], + }, + [`& .${chipClasses.icon}`]: { + color: gray[500], + }, + ...theme.applyStyles('dark', { + borderColor: gray[700], + backgroundColor: gray[800], + [`& .${chipClasses.label}`]: { + color: gray[300], + }, + [`& .${chipClasses.icon}`]: { + color: gray[300], + }, + }), + }, + }, + { + props: { + color: 'success', + }, + style: { + borderColor: green[200], + backgroundColor: green[50], + [`& .${chipClasses.label}`]: { + color: green[500], + }, + [`& .${chipClasses.icon}`]: { + color: green[500], + }, + ...theme.applyStyles('dark', { + borderColor: green[800], + backgroundColor: green[900], + [`& .${chipClasses.label}`]: { + color: green[300], + }, + [`& .${chipClasses.icon}`]: { + color: green[300], + }, + }), + }, + }, + { + props: { + color: 'error', + }, + style: { + borderColor: red[100], + backgroundColor: red[50], + [`& .${chipClasses.label}`]: { + color: red[500], + }, + [`& .${chipClasses.icon}`]: { + color: red[500], + }, + ...theme.applyStyles('dark', { + borderColor: red[800], + backgroundColor: red[900], + [`& .${chipClasses.label}`]: { + color: red[200], + }, + [`& .${chipClasses.icon}`]: { + color: red[300], + }, + }), + }, + }, + { + props: { size: 'small' }, + style: { + maxHeight: 20, + [`& .${chipClasses.label}`]: { + fontSize: theme.typography.caption.fontSize, + }, + [`& .${svgIconClasses.root}`]: { + fontSize: theme.typography.caption.fontSize, + }, + }, + }, + { + props: { size: 'medium' }, + style: { + [`& .${chipClasses.label}`]: { + fontSize: theme.typography.caption.fontSize, + }, + }, + }, + ], + }), + }, + }, + MuiTablePagination: { + styleOverrides: { + actions: { + display: 'flex', + gap: 8, + marginRight: 6, + [`& .${iconButtonClasses.root}`]: { + minWidth: 0, + width: 36, + height: 36, + }, + }, + }, + }, + MuiIcon: { + defaultProps: { + fontSize: 'small', + }, + styleOverrides: { + root: { + variants: [ + { + props: { + fontSize: 'small', + }, + style: { + fontSize: '1rem', + }, + }, + ], + }, + }, + }, +}; diff --git a/webClient/src/shared-theme/customizations/feedback.tsx b/webClient/src/shared-theme/customizations/feedback.tsx new file mode 100644 index 0000000..ebd04af --- /dev/null +++ b/webClient/src/shared-theme/customizations/feedback.tsx @@ -0,0 +1,46 @@ +import { Theme, alpha, Components } from '@mui/material/styles'; +import { gray, orange } from '../themePrimitives'; + +/* eslint-disable import/prefer-default-export */ +export const feedbackCustomizations: Components = { + MuiAlert: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: 10, + backgroundColor: orange[100], + color: (theme.vars || theme).palette.text.primary, + border: `1px solid ${alpha(orange[300], 0.5)}`, + '& .MuiAlert-icon': { + color: orange[500], + }, + ...theme.applyStyles('dark', { + backgroundColor: `${alpha(orange[900], 0.5)}`, + border: `1px solid ${alpha(orange[800], 0.5)}`, + }), + }), + }, + }, + MuiDialog: { + styleOverrides: { + root: ({ theme }) => ({ + '& .MuiDialog-paper': { + borderRadius: '10px', + border: '1px solid', + borderColor: (theme.vars || theme).palette.divider, + }, + }), + }, + }, + MuiLinearProgress: { + styleOverrides: { + root: ({ theme }) => ({ + height: 8, + borderRadius: 8, + backgroundColor: gray[200], + ...theme.applyStyles('dark', { + backgroundColor: gray[800], + }), + }), + }, + }, +}; diff --git a/webClient/src/shared-theme/customizations/inputs.tsx b/webClient/src/shared-theme/customizations/inputs.tsx new file mode 100644 index 0000000..65b2a58 --- /dev/null +++ b/webClient/src/shared-theme/customizations/inputs.tsx @@ -0,0 +1,445 @@ +import * as React from 'react'; +import { alpha, Theme, Components } from '@mui/material/styles'; +import { outlinedInputClasses } from '@mui/material/OutlinedInput'; +import { svgIconClasses } from '@mui/material/SvgIcon'; +import { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup'; +import { toggleButtonClasses } from '@mui/material/ToggleButton'; +import CheckBoxOutlineBlankRoundedIcon from '@mui/icons-material/CheckBoxOutlineBlankRounded'; +import CheckRoundedIcon from '@mui/icons-material/CheckRounded'; +import RemoveRoundedIcon from '@mui/icons-material/RemoveRounded'; +import { gray, brand } from '../themePrimitives'; + +/* eslint-disable import/prefer-default-export */ +export const inputsCustomizations: Components = { + MuiButtonBase: { + defaultProps: { + disableTouchRipple: true, + disableRipple: true, + }, + styleOverrides: { + root: ({ theme }) => ({ + boxSizing: 'border-box', + transition: 'all 100ms ease-in', + '&:focus-visible': { + outline: `3px solid ${alpha(theme.palette.primary.main, 0.5)}`, + outlineOffset: '2px', + }, + }), + }, + }, + MuiButton: { + styleOverrides: { + root: ({ theme }) => ({ + boxShadow: 'none', + borderRadius: (theme.vars || theme).shape.borderRadius, + textTransform: 'none', + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2.25rem', + padding: '8px 12px', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', // 40px + }, + }, + { + props: { + color: 'primary', + variant: 'contained', + }, + style: { + color: 'white', + backgroundColor: gray[900], + backgroundImage: `linear-gradient(to bottom, ${gray[700]}, ${gray[800]})`, + boxShadow: `inset 0 1px 0 ${gray[600]}, inset 0 -1px 0 1px hsl(220, 0%, 0%)`, + border: `1px solid ${gray[700]}`, + '&:hover': { + backgroundImage: 'none', + backgroundColor: gray[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: gray[800], + }, + ...theme.applyStyles('dark', { + color: 'black', + backgroundColor: gray[50], + backgroundImage: `linear-gradient(to bottom, ${gray[100]}, ${gray[50]})`, + boxShadow: 'inset 0 -1px 0 hsl(220, 30%, 80%)', + border: `1px solid ${gray[50]}`, + '&:hover': { + backgroundImage: 'none', + backgroundColor: gray[300], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: gray[400], + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'contained', + }, + style: { + color: 'white', + backgroundColor: brand[300], + backgroundImage: `linear-gradient(to bottom, ${alpha(brand[400], 0.8)}, ${brand[500]})`, + boxShadow: `inset 0 2px 0 ${alpha(brand[200], 0.2)}, inset 0 -2px 0 ${alpha(brand[700], 0.4)}`, + border: `1px solid ${brand[500]}`, + '&:hover': { + backgroundColor: brand[700], + boxShadow: 'none', + }, + '&:active': { + backgroundColor: brand[700], + backgroundImage: 'none', + }, + }, + }, + { + props: { + variant: 'outlined', + }, + style: { + color: (theme.vars || theme).palette.text.primary, + border: '1px solid', + borderColor: gray[200], + backgroundColor: alpha(gray[50], 0.3), + '&:hover': { + backgroundColor: gray[100], + borderColor: gray[300], + }, + '&:active': { + backgroundColor: gray[200], + }, + ...theme.applyStyles('dark', { + backgroundColor: gray[800], + borderColor: gray[700], + + '&:hover': { + backgroundColor: gray[900], + borderColor: gray[600], + }, + '&:active': { + backgroundColor: gray[900], + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'outlined', + }, + style: { + color: brand[700], + border: '1px solid', + borderColor: brand[200], + backgroundColor: brand[50], + '&:hover': { + backgroundColor: brand[100], + borderColor: brand[400], + }, + '&:active': { + backgroundColor: alpha(brand[200], 0.7), + }, + ...theme.applyStyles('dark', { + color: brand[50], + border: '1px solid', + borderColor: brand[900], + backgroundColor: alpha(brand[900], 0.3), + '&:hover': { + borderColor: brand[700], + backgroundColor: alpha(brand[900], 0.6), + }, + '&:active': { + backgroundColor: alpha(brand[900], 0.5), + }, + }), + }, + }, + { + props: { + variant: 'text', + }, + style: { + color: gray[600], + '&:hover': { + backgroundColor: gray[100], + }, + '&:active': { + backgroundColor: gray[200], + }, + ...theme.applyStyles('dark', { + color: gray[50], + '&:hover': { + backgroundColor: gray[700], + }, + '&:active': { + backgroundColor: alpha(gray[700], 0.7), + }, + }), + }, + }, + { + props: { + color: 'secondary', + variant: 'text', + }, + style: { + color: brand[700], + '&:hover': { + backgroundColor: alpha(brand[100], 0.5), + }, + '&:active': { + backgroundColor: alpha(brand[200], 0.7), + }, + ...theme.applyStyles('dark', { + color: brand[100], + '&:hover': { + backgroundColor: alpha(brand[900], 0.5), + }, + '&:active': { + backgroundColor: alpha(brand[900], 0.3), + }, + }), + }, + }, + ], + }), + }, + }, + MuiIconButton: { + styleOverrides: { + root: ({ theme }) => ({ + boxShadow: 'none', + borderRadius: (theme.vars || theme).shape.borderRadius, + textTransform: 'none', + fontWeight: theme.typography.fontWeightMedium, + letterSpacing: 0, + color: (theme.vars || theme).palette.text.primary, + border: '1px solid ', + borderColor: gray[200], + backgroundColor: alpha(gray[50], 0.3), + '&:hover': { + backgroundColor: gray[100], + borderColor: gray[300], + }, + '&:active': { + backgroundColor: gray[200], + }, + ...theme.applyStyles('dark', { + backgroundColor: gray[800], + borderColor: gray[700], + '&:hover': { + backgroundColor: gray[900], + borderColor: gray[600], + }, + '&:active': { + backgroundColor: gray[900], + }, + }), + variants: [ + { + props: { + size: 'small', + }, + style: { + width: '2.25rem', + height: '2.25rem', + padding: '0.25rem', + [`& .${svgIconClasses.root}`]: { fontSize: '1rem' }, + }, + }, + { + props: { + size: 'medium', + }, + style: { + width: '2.5rem', + height: '2.5rem', + }, + }, + ], + }), + }, + }, + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: '10px', + boxShadow: `0 4px 16px ${alpha(gray[400], 0.2)}`, + [`& .${toggleButtonGroupClasses.selected}`]: { + color: brand[500], + }, + ...theme.applyStyles('dark', { + [`& .${toggleButtonGroupClasses.selected}`]: { + color: '#fff', + }, + boxShadow: `0 4px 16px ${alpha(brand[700], 0.5)}`, + }), + }), + }, + }, + MuiToggleButton: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '12px 16px', + textTransform: 'none', + borderRadius: '10px', + fontWeight: 500, + ...theme.applyStyles('dark', { + color: gray[400], + boxShadow: '0 4px 16px rgba(0, 0, 0, 0.5)', + [`&.${toggleButtonClasses.selected}`]: { + color: brand[300], + }, + }), + }), + }, + }, + MuiCheckbox: { + defaultProps: { + disableRipple: true, + icon: ( + + ), + checkedIcon: , + indeterminateIcon: , + }, + styleOverrides: { + root: ({ theme }) => ({ + margin: 10, + height: 16, + width: 16, + borderRadius: 5, + border: '1px solid ', + borderColor: alpha(gray[300], 0.8), + boxShadow: '0 0 0 1.5px hsla(210, 0%, 0%, 0.04) inset', + backgroundColor: alpha(gray[100], 0.4), + transition: 'border-color, background-color, 120ms ease-in', + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focusVisible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + borderColor: brand[400], + }, + '&.Mui-checked': { + color: 'white', + backgroundColor: brand[500], + borderColor: brand[500], + boxShadow: `none`, + '&:hover': { + backgroundColor: brand[600], + }, + }, + ...theme.applyStyles('dark', { + borderColor: alpha(gray[700], 0.8), + boxShadow: '0 0 0 1.5px hsl(210, 0%, 0%) inset', + backgroundColor: alpha(gray[900], 0.8), + '&:hover': { + borderColor: brand[300], + }, + '&.Mui-focusVisible': { + borderColor: brand[400], + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '2px', + }, + }), + }), + }, + }, + MuiInputBase: { + styleOverrides: { + root: { + border: 'none', + }, + input: { + '&::placeholder': { + opacity: 0.7, + color: gray[500], + }, + }, + }, + }, + MuiOutlinedInput: { + styleOverrides: { + input: { + padding: 0, + }, + root: ({ theme }) => ({ + padding: '8px 12px', + color: (theme.vars || theme).palette.text.primary, + borderRadius: (theme.vars || theme).shape.borderRadius, + border: `1px solid ${(theme.vars || theme).palette.divider}`, + backgroundColor: (theme.vars || theme).palette.background.default, + transition: 'border 120ms ease-in', + '&:hover': { + borderColor: gray[400], + }, + [`&.${outlinedInputClasses.focused}`]: { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + borderColor: brand[400], + }, + ...theme.applyStyles('dark', { + '&:hover': { + borderColor: gray[500], + }, + }), + variants: [ + { + props: { + size: 'small', + }, + style: { + height: '2.25rem', + }, + }, + { + props: { + size: 'medium', + }, + style: { + height: '2.5rem', + }, + }, + ], + }), + notchedOutline: { + border: 'none', + }, + }, + }, + MuiInputAdornment: { + styleOverrides: { + root: ({ theme }) => ({ + color: (theme.vars || theme).palette.grey[500], + ...theme.applyStyles('dark', { + color: (theme.vars || theme).palette.grey[400], + }), + }), + }, + }, + MuiFormLabel: { + styleOverrides: { + root: ({ theme }) => ({ + typography: theme.typography.caption, + marginBottom: 8, + }), + }, + }, +}; diff --git a/webClient/src/shared-theme/customizations/navigation.tsx b/webClient/src/shared-theme/customizations/navigation.tsx new file mode 100644 index 0000000..714f6f7 --- /dev/null +++ b/webClient/src/shared-theme/customizations/navigation.tsx @@ -0,0 +1,279 @@ +import * as React from 'react'; +import { Theme, alpha, Components } from '@mui/material/styles'; +import { SvgIconProps } from '@mui/material/SvgIcon'; +import { buttonBaseClasses } from '@mui/material/ButtonBase'; +import { dividerClasses } from '@mui/material/Divider'; +import { menuItemClasses } from '@mui/material/MenuItem'; +import { selectClasses } from '@mui/material/Select'; +import { tabClasses } from '@mui/material/Tab'; +import UnfoldMoreRoundedIcon from '@mui/icons-material/UnfoldMoreRounded'; +import { gray, brand } from '../themePrimitives'; + +/* eslint-disable import/prefer-default-export */ +export const navigationCustomizations: Components = { + MuiMenuItem: { + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: (theme.vars || theme).shape.borderRadius, + padding: '6px 8px', + [`&.${menuItemClasses.focusVisible}`]: { + backgroundColor: 'transparent', + }, + [`&.${menuItemClasses.selected}`]: { + [`&.${menuItemClasses.focusVisible}`]: { + backgroundColor: alpha(theme.palette.action.selected, 0.3), + }, + }, + }), + }, + }, + MuiMenu: { + styleOverrides: { + list: { + gap: '0px', + [`&.${dividerClasses.root}`]: { + margin: '0 -8px', + }, + }, + paper: ({ theme }) => ({ + marginTop: '4px', + borderRadius: (theme.vars || theme).shape.borderRadius, + border: `1px solid ${(theme.vars || theme).palette.divider}`, + backgroundImage: 'none', + background: 'hsl(0, 0%, 100%)', + boxShadow: + 'hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px', + [`& .${buttonBaseClasses.root}`]: { + '&.Mui-selected': { + backgroundColor: alpha(theme.palette.action.selected, 0.3), + }, + }, + ...theme.applyStyles('dark', { + background: gray[900], + boxShadow: + 'hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px', + }), + }), + }, + }, + MuiSelect: { + defaultProps: { + IconComponent: React.forwardRef((props, ref) => ( + + )), + }, + styleOverrides: { + root: ({ theme }) => ({ + borderRadius: (theme.vars || theme).shape.borderRadius, + border: '1px solid', + borderColor: gray[200], + backgroundColor: (theme.vars || theme).palette.background.paper, + boxShadow: `inset 0 1px 0 1px hsla(220, 0%, 100%, 0.6), inset 0 -1px 0 1px hsla(220, 35%, 90%, 0.5)`, + '&:hover': { + borderColor: gray[300], + backgroundColor: (theme.vars || theme).palette.background.paper, + boxShadow: 'none', + }, + [`&.${selectClasses.focused}`]: { + outlineOffset: 0, + borderColor: gray[400], + }, + '&:before, &:after': { + display: 'none', + }, + + ...theme.applyStyles('dark', { + borderRadius: (theme.vars || theme).shape.borderRadius, + borderColor: gray[700], + backgroundColor: (theme.vars || theme).palette.background.paper, + boxShadow: `inset 0 1px 0 1px ${alpha(gray[700], 0.15)}, inset 0 -1px 0 1px hsla(220, 0%, 0%, 0.7)`, + '&:hover': { + borderColor: alpha(gray[700], 0.7), + backgroundColor: (theme.vars || theme).palette.background.paper, + boxShadow: 'none', + }, + [`&.${selectClasses.focused}`]: { + outlineOffset: 0, + borderColor: gray[900], + }, + '&:before, &:after': { + display: 'none', + }, + }), + }), + select: ({ theme }) => ({ + display: 'flex', + alignItems: 'center', + ...theme.applyStyles('dark', { + display: 'flex', + alignItems: 'center', + '&:focus-visible': { + backgroundColor: gray[900], + }, + }), + }), + }, + }, + MuiLink: { + defaultProps: { + underline: 'none', + }, + styleOverrides: { + root: ({ theme }) => ({ + color: (theme.vars || theme).palette.text.primary, + fontWeight: 500, + position: 'relative', + textDecoration: 'none', + width: 'fit-content', + '&::before': { + content: '""', + position: 'absolute', + width: '100%', + height: '1px', + bottom: 0, + left: 0, + backgroundColor: (theme.vars || theme).palette.text.secondary, + opacity: 0.3, + transition: 'width 0.3s ease, opacity 0.3s ease', + }, + '&:hover::before': { + width: 0, + }, + '&:focus-visible': { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: '4px', + borderRadius: '2px', + }, + }), + }, + }, + MuiDrawer: { + styleOverrides: { + paper: ({ theme }) => ({ + backgroundColor: (theme.vars || theme).palette.background.default, + }), + }, + }, + MuiPaginationItem: { + styleOverrides: { + root: ({ theme }) => ({ + '&.Mui-selected': { + color: 'white', + backgroundColor: (theme.vars || theme).palette.grey[900], + }, + ...theme.applyStyles('dark', { + '&.Mui-selected': { + color: 'black', + backgroundColor: (theme.vars || theme).palette.grey[50], + }, + }), + }), + }, + }, + MuiTabs: { + styleOverrides: { + root: { minHeight: 'fit-content' }, + indicator: ({ theme }) => ({ + backgroundColor: (theme.vars || theme).palette.grey[800], + ...theme.applyStyles('dark', { + backgroundColor: (theme.vars || theme).palette.grey[200], + }), + }), + }, + }, + MuiTab: { + styleOverrides: { + root: ({ theme }) => ({ + padding: '6px 8px', + marginBottom: '8px', + textTransform: 'none', + minWidth: 'fit-content', + minHeight: 'fit-content', + color: (theme.vars || theme).palette.text.secondary, + borderRadius: (theme.vars || theme).shape.borderRadius, + border: '1px solid', + borderColor: 'transparent', + ':hover': { + color: (theme.vars || theme).palette.text.primary, + backgroundColor: gray[100], + borderColor: gray[200], + }, + [`&.${tabClasses.selected}`]: { + color: gray[900], + }, + ...theme.applyStyles('dark', { + ':hover': { + color: (theme.vars || theme).palette.text.primary, + backgroundColor: gray[800], + borderColor: gray[700], + }, + [`&.${tabClasses.selected}`]: { + color: '#fff', + }, + }), + }), + }, + }, + MuiStepConnector: { + styleOverrides: { + line: ({ theme }) => ({ + borderTop: '1px solid', + borderColor: (theme.vars || theme).palette.divider, + flex: 1, + borderRadius: '99px', + }), + }, + }, + MuiStepIcon: { + styleOverrides: { + root: ({ theme }) => ({ + color: 'transparent', + border: `1px solid ${gray[400]}`, + width: 12, + height: 12, + borderRadius: '50%', + '& text': { + display: 'none', + }, + '&.Mui-active': { + border: 'none', + color: (theme.vars || theme).palette.primary.main, + }, + '&.Mui-completed': { + border: 'none', + color: (theme.vars || theme).palette.success.main, + }, + ...theme.applyStyles('dark', { + border: `1px solid ${gray[700]}`, + '&.Mui-active': { + border: 'none', + color: (theme.vars || theme).palette.primary.light, + }, + '&.Mui-completed': { + border: 'none', + color: (theme.vars || theme).palette.success.light, + }, + }), + variants: [ + { + props: { completed: true }, + style: { + width: 12, + height: 12, + }, + }, + ], + }), + }, + }, + MuiStepLabel: { + styleOverrides: { + label: ({ theme }) => ({ + '&.Mui-completed': { + opacity: 0.6, + ...theme.applyStyles('dark', { opacity: 0.5 }), + }, + }), + }, + }, +}; diff --git a/webClient/src/shared-theme/customizations/surfaces.ts b/webClient/src/shared-theme/customizations/surfaces.ts new file mode 100644 index 0000000..ed583eb --- /dev/null +++ b/webClient/src/shared-theme/customizations/surfaces.ts @@ -0,0 +1,113 @@ +import { alpha, Theme, Components } from '@mui/material/styles'; +import { gray } from '../themePrimitives'; + +/* eslint-disable import/prefer-default-export */ +export const surfacesCustomizations: Components = { + MuiAccordion: { + defaultProps: { + elevation: 0, + disableGutters: true, + }, + styleOverrides: { + root: ({ theme }) => ({ + padding: 4, + overflow: 'clip', + backgroundColor: (theme.vars || theme).palette.background.default, + border: '1px solid', + borderColor: (theme.vars || theme).palette.divider, + ':before': { + backgroundColor: 'transparent', + }, + '&:not(:last-of-type)': { + borderBottom: 'none', + }, + '&:first-of-type': { + borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, + borderTopRightRadius: (theme.vars || theme).shape.borderRadius, + }, + '&:last-of-type': { + borderBottomLeftRadius: (theme.vars || theme).shape.borderRadius, + borderBottomRightRadius: (theme.vars || theme).shape.borderRadius, + }, + }), + }, + }, + MuiAccordionSummary: { + styleOverrides: { + root: ({ theme }) => ({ + border: 'none', + borderRadius: 8, + '&:hover': { backgroundColor: gray[50] }, + '&:focus-visible': { backgroundColor: 'transparent' }, + ...theme.applyStyles('dark', { + '&:hover': { backgroundColor: gray[800] }, + }), + }), + }, + }, + MuiAccordionDetails: { + styleOverrides: { + root: { mb: 20, border: 'none' }, + }, + }, + MuiPaper: { + defaultProps: { + elevation: 0, + }, + }, + MuiCard: { + styleOverrides: { + root: ({ theme }) => { + return { + padding: 16, + gap: 16, + transition: 'all 100ms ease', + backgroundColor: gray[50], + borderRadius: (theme.vars || theme).shape.borderRadius, + border: `1px solid ${(theme.vars || theme).palette.divider}`, + boxShadow: 'none', + ...theme.applyStyles('dark', { + backgroundColor: gray[800], + }), + variants: [ + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${(theme.vars || theme).palette.divider}`, + boxShadow: 'none', + background: 'hsl(0, 0%, 100%)', + ...theme.applyStyles('dark', { + background: alpha(gray[900], 0.4), + }), + }, + }, + ], + }; + }, + }, + }, + MuiCardContent: { + styleOverrides: { + root: { + padding: 0, + '&:last-child': { paddingBottom: 0 }, + }, + }, + }, + MuiCardHeader: { + styleOverrides: { + root: { + padding: 0, + }, + }, + }, + MuiCardActions: { + styleOverrides: { + root: { + padding: 0, + }, + }, + }, +}; diff --git a/webClient/src/shared-theme/themePrimitives.ts b/webClient/src/shared-theme/themePrimitives.ts new file mode 100644 index 0000000..7cfe000 --- /dev/null +++ b/webClient/src/shared-theme/themePrimitives.ts @@ -0,0 +1,410 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ +import { alpha, createTheme, PaletteMode, Shadows } from "@mui/material/styles"; + +declare module "@mui/material/Paper" { + interface PaperPropsVariantOverrides { + highlighted: true; + } +} +declare module "@mui/material/styles/createPalette" { + interface ColorRange { + 50: string; + 100: string; + 200: string; + 300: string; + 400: string; + 500: string; + 600: string; + 700: string; + 800: string; + 900: string; + } + + interface PaletteColor extends ColorRange {} + + interface Palette { + baseShadow: string; + } +} + +const defaultTheme = createTheme(); + +const customShadows: Shadows = [...defaultTheme.shadows]; + +export const brand = { + 50: "hsl(210, 100%, 95%)", + 100: "hsl(210, 100%, 92%)", + 200: "hsl(210, 100%, 80%)", + 300: "hsl(210, 100%, 65%)", + 400: "hsl(210, 98%, 48%)", + 500: "hsl(210, 98%, 42%)", + 600: "hsl(210, 98%, 55%)", + 700: "hsl(210, 100%, 35%)", + 800: "hsl(210, 100%, 16%)", + 900: "hsl(210, 100%, 21%)", +}; + +export const gray = { + 50: "hsl(220, 35%, 97%)", + 100: "hsl(220, 30%, 94%)", + 200: "hsl(220, 20%, 88%)", + 300: "hsl(220, 20%, 80%)", + 400: "hsl(220, 20%, 65%)", + 500: "hsl(220, 20%, 42%)", + 600: "hsl(220, 20%, 35%)", + 700: "hsl(220, 20%, 25%)", + 800: "hsl(220, 30%, 6%)", + 900: "hsl(220, 35%, 3%)", +}; + +export const green = { + 50: "hsl(120, 80%, 98%)", + 100: "hsl(120, 75%, 94%)", + 200: "hsl(120, 75%, 87%)", + 300: "hsl(120, 61%, 77%)", + 400: "hsl(120, 44%, 53%)", + 500: "hsl(120, 59%, 30%)", + 600: "hsl(120, 70%, 25%)", + 700: "hsl(120, 75%, 16%)", + 800: "hsl(120, 84%, 10%)", + 900: "hsl(120, 87%, 6%)", +}; + +export const orange = { + 50: "hsl(45, 100%, 97%)", + 100: "hsl(45, 92%, 90%)", + 200: "hsl(45, 94%, 80%)", + 300: "hsl(45, 90%, 65%)", + 400: "hsl(45, 90%, 40%)", + 500: "hsl(45, 90%, 35%)", + 600: "hsl(45, 91%, 25%)", + 700: "hsl(45, 94%, 20%)", + 800: "hsl(45, 95%, 16%)", + 900: "hsl(45, 93%, 12%)", +}; + +export const red = { + 50: "hsl(0, 100%, 97%)", + 100: "hsl(0, 92%, 90%)", + 200: "hsl(0, 94%, 80%)", + 300: "hsl(0, 90%, 65%)", + 400: "hsl(0, 90%, 40%)", + 500: "hsl(0, 90%, 30%)", + 600: "hsl(0, 91%, 25%)", + 700: "hsl(0, 94%, 18%)", + 800: "hsl(0, 95%, 12%)", + 900: "hsl(0, 93%, 6%)", +}; + +export const getDesignTokens = (mode: PaletteMode) => { + customShadows[1] = + mode === "dark" + ? "hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px" + : "hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px"; + + return { + palette: { + mode, + primary: { + light: brand[200], + main: brand[400], + dark: brand[700], + contrastText: brand[50], + ...(mode === "dark" && { + contrastText: brand[50], + light: brand[300], + main: brand[400], + dark: brand[700], + }), + }, + info: { + light: brand[100], + main: brand[300], + dark: brand[600], + contrastText: gray[50], + ...(mode === "dark" && { + contrastText: brand[300], + light: brand[500], + main: brand[700], + dark: brand[900], + }), + }, + warning: { + light: orange[300], + main: orange[400], + dark: orange[800], + ...(mode === "dark" && { + light: orange[400], + main: orange[500], + dark: orange[700], + }), + }, + error: { + light: red[300], + main: red[400], + dark: red[800], + ...(mode === "dark" && { + light: red[400], + main: red[500], + dark: red[700], + }), + }, + success: { + light: green[300], + main: green[400], + dark: green[800], + ...(mode === "dark" && { + light: green[400], + main: green[500], + dark: green[700], + }), + }, + grey: { + ...gray, + }, + divider: mode === "dark" ? alpha(gray[700], 0.6) : alpha(gray[300], 0.4), + background: { + default: "hsl(0, 0%, 99%)", + paper: "hsl(220, 35%, 97%)", + ...(mode === "dark" && { + default: gray[900], + paper: "hsl(220, 30%, 7%)", + }), + }, + text: { + primary: gray[800], + secondary: gray[600], + warning: orange[400], + ...(mode === "dark" && { + primary: "hsl(0, 0%, 100%)", + secondary: gray[400], + }), + }, + action: { + hover: alpha(gray[200], 0.2), + selected: `${alpha(gray[200], 0.3)}`, + ...(mode === "dark" && { + hover: alpha(gray[600], 0.2), + selected: alpha(gray[600], 0.3), + }), + }, + }, + typography: { + fontFamily: "Inter, sans-serif", + h1: { + fontSize: defaultTheme.typography.pxToRem(48), + fontWeight: 600, + lineHeight: 1.2, + letterSpacing: -0.5, + }, + h2: { + fontSize: defaultTheme.typography.pxToRem(36), + fontWeight: 600, + lineHeight: 1.2, + }, + h3: { + fontSize: defaultTheme.typography.pxToRem(30), + lineHeight: 1.2, + }, + h4: { + fontSize: defaultTheme.typography.pxToRem(24), + fontWeight: 600, + lineHeight: 1.5, + }, + h5: { + fontSize: defaultTheme.typography.pxToRem(20), + fontWeight: 600, + }, + h6: { + fontSize: defaultTheme.typography.pxToRem(18), + fontWeight: 600, + }, + subtitle1: { + fontSize: defaultTheme.typography.pxToRem(18), + }, + subtitle2: { + fontSize: defaultTheme.typography.pxToRem(14), + fontWeight: 500, + }, + body1: { + fontSize: defaultTheme.typography.pxToRem(14), + }, + body2: { + fontSize: defaultTheme.typography.pxToRem(14), + fontWeight: 400, + }, + caption: { + fontSize: defaultTheme.typography.pxToRem(12), + fontWeight: 400, + }, + }, + shape: { + borderRadius: 8, + }, + shadows: customShadows, + }; +}; + +export const colorSchemes = { + light: { + palette: { + primary: { + light: brand[200], + main: brand[400], + dark: brand[700], + contrastText: brand[50], + }, + info: { + light: brand[100], + main: brand[300], + dark: brand[600], + contrastText: gray[50], + }, + warning: { + light: orange[300], + main: orange[400], + dark: orange[800], + }, + error: { + light: red[300], + main: red[400], + dark: red[800], + }, + success: { + light: green[300], + main: green[400], + dark: green[800], + }, + grey: { + ...gray, + }, + divider: alpha(gray[300], 0.4), + background: { + default: "hsl(0, 0%, 99%)", + paper: "hsl(220, 35%, 97%)", + }, + text: { + primary: gray[800], + secondary: gray[600], + warning: orange[400], + }, + action: { + hover: alpha(gray[200], 0.2), + selected: `${alpha(gray[200], 0.3)}`, + }, + baseShadow: + "hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px", + }, + }, + dark: { + palette: { + primary: { + contrastText: brand[50], + light: brand[300], + main: brand[400], + dark: brand[700], + }, + info: { + contrastText: brand[300], + light: brand[500], + main: brand[700], + dark: brand[900], + }, + warning: { + light: orange[400], + main: orange[500], + dark: orange[700], + }, + error: { + light: red[400], + main: red[500], + dark: red[700], + }, + success: { + light: green[400], + main: green[500], + dark: green[700], + }, + grey: { + ...gray, + }, + divider: alpha(gray[700], 0.6), + background: { + default: gray[900], + paper: "hsl(220, 30%, 7%)", + }, + text: { + primary: "hsl(0, 0%, 100%)", + secondary: gray[400], + }, + action: { + hover: alpha(gray[600], 0.2), + selected: alpha(gray[600], 0.3), + }, + baseShadow: + "hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px", + }, + }, +}; + +export const typography = { + fontFamily: "Inter, sans-serif", + h1: { + fontSize: defaultTheme.typography.pxToRem(48), + fontWeight: 600, + lineHeight: 1.2, + letterSpacing: -0.5, + }, + h2: { + fontSize: defaultTheme.typography.pxToRem(36), + fontWeight: 600, + lineHeight: 1.2, + }, + h3: { + fontSize: defaultTheme.typography.pxToRem(30), + lineHeight: 1.2, + }, + h4: { + fontSize: defaultTheme.typography.pxToRem(24), + fontWeight: 600, + lineHeight: 1.5, + }, + h5: { + fontSize: defaultTheme.typography.pxToRem(20), + fontWeight: 600, + }, + h6: { + fontSize: defaultTheme.typography.pxToRem(18), + fontWeight: 600, + }, + subtitle1: { + fontSize: defaultTheme.typography.pxToRem(18), + }, + subtitle2: { + fontSize: defaultTheme.typography.pxToRem(14), + fontWeight: 500, + }, + body1: { + fontSize: defaultTheme.typography.pxToRem(14), + }, + body2: { + fontSize: defaultTheme.typography.pxToRem(14), + fontWeight: 400, + }, + caption: { + fontSize: defaultTheme.typography.pxToRem(12), + fontWeight: 400, + }, +}; + +export const shape = { + borderRadius: 8, +}; + +// @ts-ignore +const defaultShadows: Shadows = [ + "none", + "var(--template-palette-baseShadow)", + ...defaultTheme.shadows.slice(2), +]; +export const shadows = defaultShadows; diff --git a/webClient/src/theme/customizations/charts.ts b/webClient/src/theme/customizations/charts.ts new file mode 100644 index 0000000..df99598 --- /dev/null +++ b/webClient/src/theme/customizations/charts.ts @@ -0,0 +1,76 @@ +import { Theme } from "@mui/material/styles"; +import { axisClasses, chartsGridClasses, legendClasses } from "@mui/x-charts"; +import type { ChartsComponents } from "@mui/x-charts/themeAugmentation"; +import { gray } from "../../shared-theme/themePrimitives"; + +/* eslint-disable import/prefer-default-export */ +export const chartsCustomizations: ChartsComponents = { + MuiChartsAxis: { + styleOverrides: { + root: ({ theme }) => ({ + [`& .${axisClasses.line}`]: { + stroke: gray[300], + }, + [`& .${axisClasses.tick}`]: { stroke: gray[300] }, + [`& .${axisClasses.tickLabel}`]: { + fill: gray[500], + fontWeight: 500, + }, + ...theme.applyStyles("dark", { + [`& .${axisClasses.line}`]: { + stroke: gray[700], + }, + [`& .${axisClasses.tick}`]: { stroke: gray[700] }, + [`& .${axisClasses.tickLabel}`]: { + fill: gray[300], + fontWeight: 500, + }, + }), + }), + }, + }, + MuiChartsTooltip: { + styleOverrides: { + mark: ({ theme }) => ({ + ry: 6, + boxShadow: "none", + border: `1px solid ${(theme.vars || theme).palette.divider}`, + }), + table: ({ theme }) => ({ + border: `1px solid ${(theme.vars || theme).palette.divider}`, + borderRadius: theme.shape.borderRadius, + background: "hsl(0, 0%, 100%)", + ...theme.applyStyles("dark", { + background: gray[900], + }), + }), + }, + }, + MuiChartsLegend: { + styleOverrides: { + root: { + [`& .${legendClasses.mark}`]: { + ry: 6, + }, + }, + }, + }, + MuiChartsGrid: { + styleOverrides: { + root: ({ theme }) => ({ + [`& .${chartsGridClasses.line}`]: { + stroke: gray[200], + strokeDasharray: "4 2", + strokeWidth: 0.8, + }, + ...theme.applyStyles("dark", { + [`& .${chartsGridClasses.line}`]: { + stroke: gray[700], + strokeDasharray: "4 2", + strokeWidth: 0.8, + }, + }), + }), + }, + }, +}; diff --git a/webClient/src/theme/customizations/dataGrid.ts b/webClient/src/theme/customizations/dataGrid.ts new file mode 100644 index 0000000..29f2131 --- /dev/null +++ b/webClient/src/theme/customizations/dataGrid.ts @@ -0,0 +1,138 @@ +import { checkboxClasses } from "@mui/material/Checkbox"; +import { iconButtonClasses } from "@mui/material/IconButton"; +import { listClasses } from "@mui/material/List"; +import { listItemIconClasses } from "@mui/material/ListItemIcon"; +import { menuItemClasses } from "@mui/material/MenuItem"; +import { paperClasses } from "@mui/material/Paper"; +import { alpha, Theme } from "@mui/material/styles"; +import { tablePaginationClasses } from "@mui/material/TablePagination"; +import { gridClasses } from "@mui/x-data-grid"; +import type { DataGridProComponents } from "@mui/x-data-grid-pro/themeAugmentation"; +import type { DataGridComponents } from "@mui/x-data-grid/themeAugmentation"; +import { gray } from "../../shared-theme/themePrimitives"; + +/* eslint-disable import/prefer-default-export */ +export const dataGridCustomizations: DataGridProComponents & + DataGridComponents = { + MuiDataGrid: { + styleOverrides: { + root: ({ theme }) => ({ + "--DataGrid-overlayHeight": "300px", + overflow: "clip", + borderColor: (theme.vars || theme).palette.divider, + backgroundColor: (theme.vars || theme).palette.background.default, + [`& .${gridClasses.columnHeader}`]: { + backgroundColor: (theme.vars || theme).palette.background.paper, + }, + [`& .${gridClasses.footerContainer}`]: { + backgroundColor: (theme.vars || theme).palette.background.paper, + }, + [`& .${checkboxClasses.root}`]: { + padding: theme.spacing(0.5), + "& > svg": { + fontSize: "1rem", + }, + }, + [`& .${tablePaginationClasses.root}`]: { + marginRight: theme.spacing(1), + "& .MuiIconButton-root": { + maxHeight: 32, + maxWidth: 32, + "& > svg": { + fontSize: "1rem", + }, + }, + }, + }), + cell: ({ theme }) => ({ + borderTopColor: (theme.vars || theme).palette.divider, + }), + menu: ({ theme }) => ({ + borderRadius: theme.shape.borderRadius, + backgroundImage: "none", + [`& .${paperClasses.root}`]: { + border: `1px solid ${(theme.vars || theme).palette.divider}`, + }, + + [`& .${menuItemClasses.root}`]: { + margin: "0 4px", + }, + [`& .${listItemIconClasses.root}`]: { + marginRight: 0, + }, + [`& .${listClasses.root}`]: { + paddingLeft: 0, + paddingRight: 0, + }, + }), + + row: ({ theme }) => ({ + "&:last-of-type": { + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + }, + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + "&.Mui-selected": { + background: (theme.vars || theme).palette.action.selected, + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + }, + }), + iconButtonContainer: ({ theme }) => ({ + [`& .${iconButtonClasses.root}`]: { + border: "none", + backgroundColor: "transparent", + "&:hover": { + backgroundColor: alpha(theme.palette.action.selected, 0.3), + }, + "&:active": { + backgroundColor: gray[200], + }, + ...theme.applyStyles("dark", { + color: gray[50], + "&:hover": { + backgroundColor: gray[800], + }, + "&:active": { + backgroundColor: gray[900], + }, + }), + }, + }), + menuIconButton: ({ theme }) => ({ + border: "none", + backgroundColor: "transparent", + "&:hover": { + backgroundColor: gray[100], + }, + "&:active": { + backgroundColor: gray[200], + }, + ...theme.applyStyles("dark", { + color: gray[50], + "&:hover": { + backgroundColor: gray[800], + }, + "&:active": { + backgroundColor: gray[900], + }, + }), + }), + filterForm: ({ theme }) => ({ + gap: theme.spacing(1), + alignItems: "flex-end", + }), + columnsManagementHeader: ({ theme }) => ({ + paddingRight: theme.spacing(3), + paddingLeft: theme.spacing(3), + }), + columnHeaderTitleContainer: { + flexGrow: 1, + justifyContent: "space-between", + }, + columnHeaderDraggableContainer: { paddingRight: 2 }, + }, + }, +}; diff --git a/webClient/src/theme/customizations/datePickers.ts b/webClient/src/theme/customizations/datePickers.ts new file mode 100644 index 0000000..0e18a42 --- /dev/null +++ b/webClient/src/theme/customizations/datePickers.ts @@ -0,0 +1,182 @@ +import { menuItemClasses } from "@mui/material/MenuItem"; +import { alpha, Theme } from "@mui/material/styles"; +import { + pickersDayClasses, + pickersMonthClasses, + pickersYearClasses, +} from "@mui/x-date-pickers"; +import type { PickersProComponents } from "@mui/x-date-pickers-pro/themeAugmentation"; +import type { PickerComponents } from "@mui/x-date-pickers/themeAugmentation"; +import { brand, gray } from "../../shared-theme/themePrimitives"; + +/* eslint-disable import/prefer-default-export */ +export const datePickersCustomizations: PickersProComponents & + PickerComponents = { + MuiPickersPopper: { + styleOverrides: { + paper: ({ theme }) => ({ + marginTop: 4, + borderRadius: theme.shape.borderRadius, + border: `1px solid ${(theme.vars || theme).palette.divider}`, + backgroundImage: "none", + background: "hsl(0, 0%, 100%)", + boxShadow: + "hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px", + [`& .${menuItemClasses.root}`]: { + borderRadius: 6, + margin: "0 6px", + }, + ...theme.applyStyles("dark", { + background: gray[900], + boxShadow: + "hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px", + }), + }), + }, + }, + MuiPickersArrowSwitcher: { + styleOverrides: { + spacer: { width: 16 }, + button: ({ theme }) => ({ + backgroundColor: "transparent", + color: (theme.vars || theme).palette.grey[500], + ...theme.applyStyles("dark", { + color: (theme.vars || theme).palette.grey[400], + }), + }), + }, + }, + MuiPickersCalendarHeader: { + styleOverrides: { + switchViewButton: { + padding: 0, + border: "none", + }, + }, + }, + MuiPickersMonth: { + styleOverrides: { + monthButton: ({ theme }) => ({ + fontSize: theme.typography.body1.fontSize, + color: (theme.vars || theme).palette.grey[600], + padding: theme.spacing(0.5), + borderRadius: theme.shape.borderRadius, + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${pickersMonthClasses.selected}`]: { + backgroundColor: gray[700], + fontWeight: theme.typography.fontWeightMedium, + }, + "&:focus": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + backgroundColor: "transparent", + [`&.${pickersMonthClasses.selected}`]: { backgroundColor: gray[700] }, + }, + ...theme.applyStyles("dark", { + color: (theme.vars || theme).palette.grey[300], + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${pickersMonthClasses.selected}`]: { + color: (theme.vars || theme).palette.common.black, + fontWeight: theme.typography.fontWeightMedium, + backgroundColor: gray[300], + }, + "&:focus": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + backgroundColor: "transparent", + [`&.${pickersMonthClasses.selected}`]: { + backgroundColor: gray[300], + }, + }, + }), + }), + }, + }, + MuiPickersYear: { + styleOverrides: { + yearButton: ({ theme }) => ({ + fontSize: theme.typography.body1.fontSize, + color: (theme.vars || theme).palette.grey[600], + padding: theme.spacing(0.5), + borderRadius: theme.shape.borderRadius, + height: "fit-content", + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${pickersYearClasses.selected}`]: { + backgroundColor: gray[700], + fontWeight: theme.typography.fontWeightMedium, + }, + "&:focus": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + backgroundColor: "transparent", + [`&.${pickersYearClasses.selected}`]: { backgroundColor: gray[700] }, + }, + ...theme.applyStyles("dark", { + color: (theme.vars || theme).palette.grey[300], + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${pickersYearClasses.selected}`]: { + color: (theme.vars || theme).palette.common.black, + fontWeight: theme.typography.fontWeightMedium, + backgroundColor: gray[300], + }, + "&:focus": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + backgroundColor: "transparent", + [`&.${pickersYearClasses.selected}`]: { + backgroundColor: gray[300], + }, + }, + }), + }), + }, + }, + MuiPickersDay: { + styleOverrides: { + root: ({ theme }) => ({ + fontSize: theme.typography.body1.fontSize, + color: (theme.vars || theme).palette.grey[600], + padding: theme.spacing(0.5), + borderRadius: theme.shape.borderRadius, + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${pickersDayClasses.selected}`]: { + backgroundColor: gray[700], + fontWeight: theme.typography.fontWeightMedium, + }, + "&:focus": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + backgroundColor: "transparent", + [`&.${pickersDayClasses.selected}`]: { backgroundColor: gray[700] }, + }, + ...theme.applyStyles("dark", { + color: (theme.vars || theme).palette.grey[300], + "&:hover": { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${pickersDayClasses.selected}`]: { + color: (theme.vars || theme).palette.common.black, + fontWeight: theme.typography.fontWeightMedium, + backgroundColor: gray[300], + }, + "&:focus": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + backgroundColor: "transparent", + [`&.${pickersDayClasses.selected}`]: { backgroundColor: gray[300] }, + }, + }), + }), + }, + }, +}; diff --git a/webClient/src/theme/customizations/index.ts b/webClient/src/theme/customizations/index.ts new file mode 100644 index 0000000..bb50e7f --- /dev/null +++ b/webClient/src/theme/customizations/index.ts @@ -0,0 +1,4 @@ +export { chartsCustomizations } from './charts'; +export { dataGridCustomizations } from './dataGrid'; +export { datePickersCustomizations } from './datePickers'; +export { treeViewCustomizations } from './treeView'; diff --git a/webClient/src/theme/customizations/treeView.ts b/webClient/src/theme/customizations/treeView.ts new file mode 100644 index 0000000..e353b2f --- /dev/null +++ b/webClient/src/theme/customizations/treeView.ts @@ -0,0 +1,62 @@ +import { alpha, Theme } from "@mui/material/styles"; +import type { TreeViewComponents } from "@mui/x-tree-view/themeAugmentation"; +import { brand, gray } from "../../shared-theme/themePrimitives"; + +/* eslint-disable import/prefer-default-export */ +export const treeViewCustomizations: TreeViewComponents = { + MuiTreeItem2: { + styleOverrides: { + root: ({ theme }) => ({ + position: "relative", + boxSizing: "border-box", + padding: theme.spacing(0, 1), + "& .groupTransition": { + marginLeft: theme.spacing(2), + padding: theme.spacing(0), + borderLeft: "1px solid", + borderColor: (theme.vars || theme).palette.divider, + }, + "&:focus-visible .focused": { + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + "&:hover": { + backgroundColor: alpha(gray[300], 0.2), + outline: `3px solid ${alpha(brand[500], 0.5)}`, + outlineOffset: "2px", + }, + }, + }), + content: ({ theme }) => ({ + marginTop: theme.spacing(1), + padding: theme.spacing(0.5, 1), + overflow: "clip", + "&:hover": { + backgroundColor: alpha(gray[300], 0.2), + }, + + "&.selected": { + backgroundColor: alpha(gray[300], 0.4), + "&:hover": { + backgroundColor: alpha(gray[300], 0.6), + }, + }, + ...theme.applyStyles("dark", { + "&:hover": { + backgroundColor: alpha(gray[500], 0.2), + }, + "&:focus-visible": { + "&:hover": { + backgroundColor: alpha(gray[500], 0.2), + }, + }, + "&.selected": { + backgroundColor: alpha(gray[500], 0.4), + "&:hover": { + backgroundColor: alpha(gray[500], 0.6), + }, + }, + }), + }), + }, + }, +}; diff --git a/webClient/src/vite-env.d.ts b/webClient/src/vite-env.d.ts new file mode 100644 index 0000000..216272d --- /dev/null +++ b/webClient/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/webClient/tsconfig.app.json b/webClient/tsconfig.app.json new file mode 100644 index 0000000..4f4cea5 --- /dev/null +++ b/webClient/tsconfig.app.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/webClient/tsconfig.json b/webClient/tsconfig.json new file mode 100644 index 0000000..6099fb5 --- /dev/null +++ b/webClient/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/webClient/tsconfig.node.json b/webClient/tsconfig.node.json new file mode 100644 index 0000000..8cd8a63 --- /dev/null +++ b/webClient/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/webClient/vite.config.ts b/webClient/vite.config.ts new file mode 100644 index 0000000..442ae28 --- /dev/null +++ b/webClient/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react-swc' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +})