diff --git a/front-urban/.editorconfig b/front-urban/.editorconfig new file mode 100644 index 0000000..f709510 --- /dev/null +++ b/front-urban/.editorconfig @@ -0,0 +1,15 @@ +# Editor configuration, see http://editorconfig.org +root = true +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true +[*.md] +max_line_length = off +trim_trailing_whitespace = false +[*.yml] +[*.{yml,yaml}] +indent_size = 2 diff --git a/front-urban/.env.example b/front-urban/.env.example new file mode 100644 index 0000000..0ed7cab --- /dev/null +++ b/front-urban/.env.example @@ -0,0 +1,6 @@ +BACKEND_URL=http://localhost:3001 +NEXT_PUBLIC_BACKEND_URL=http://localhost:3001 +NEXT_PUBLIC_API_URL=http://localhost:3001 +NEXT_PUBLIC_APP_URL=http://localhost:3000 +NEXT_PUBLIC_MIN_AUTH=30 +REACT_EDITOR=code \ No newline at end of file diff --git a/front-urban/.eslintrc.js b/front-urban/.eslintrc.js new file mode 100644 index 0000000..70fda91 --- /dev/null +++ b/front-urban/.eslintrc.js @@ -0,0 +1,128 @@ +module.exports = { + extends: ['next/core-web-vitals', 'plugin:@typescript-eslint/recommended', 'plugin:import/recommended', 'prettier'], + rules: { + 'jsx-a11y/alt-text': 'off', + 'react/display-name': 'off', + 'react/no-children-prop': 'off', + '@next/next/no-img-element': 'off', + '@next/next/no-page-custom-font': 'off', + '@typescript-eslint/consistent-type-imports': 'error', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-non-null-assertion': 'off', + 'lines-around-comment': [ + 'error', + { + beforeBlockComment: true, + beforeLineComment: true, + allowBlockStart: true, + allowObjectStart: true, + allowArrayStart: true + } + ], + 'padding-line-between-statements': [ + 'error', + { + blankLine: 'any', + prev: 'export', + next: 'export' + }, + { + blankLine: 'always', + prev: ['const', 'let', 'var'], + next: '*' + }, + { + blankLine: 'any', + prev: ['const', 'let', 'var'], + next: ['const', 'let', 'var'] + }, + { + blankLine: 'always', + prev: '*', + next: ['function', 'multiline-const', 'multiline-block-like'] + }, + { + blankLine: 'always', + prev: ['function', 'multiline-const', 'multiline-block-like'], + next: '*' + } + ], + 'newline-before-return': 'error', + 'import/newline-after-import': [ + 'error', + { + count: 1 + } + ], + 'import/order': [ + 'error', + { + groups: ['builtin', 'external', ['internal', 'parent', 'sibling', 'index'], ['object', 'unknown']], + pathGroups: [ + { + pattern: 'react', + group: 'external', + position: 'before' + }, + { + pattern: 'next/**', + group: 'external', + position: 'before' + }, + { + pattern: '~/**', + group: 'external', + position: 'before' + }, + { + pattern: '@/**', + group: 'internal' + } + ], + pathGroupsExcludedImportTypes: ['react', 'type'], + 'newlines-between': 'always-and-inside-groups' + } + ], + '@typescript-eslint/ban-types': [ + 'error', + { + extendDefaults: true, + types: { + Function: 'Use a specific function type instead', + Object: 'Use object instead', + Boolean: 'Use boolean instead', + Number: 'Use number instead', + String: 'Use string instead', + Symbol: 'Use symbol instead', + any: false, + '{}': false + } + } + ] + }, + settings: { + react: { + version: 'detect' + }, + 'import/parsers': { + '@typescript-eslint/parser': ['.ts', '.tsx'] + }, + 'import/resolver': { + node: {}, + typescript: { + project: './tsconfig.json' + } + } + }, + overrides: [ + { + files: ['*.ts', '*.tsx', 'src/iconify-bundle/*'], + rules: { + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-var-requires': 'off' + } + } + ] +} diff --git a/front-urban/.gitignore b/front-urban/.gitignore new file mode 100644 index 0000000..c5a2dee --- /dev/null +++ b/front-urban/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local +.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +# icon generated file +src/assets/iconify-icons/generated-icons.js +src/assets/iconify-icons/generated-icons.css diff --git a/front-urban/.npmrc b/front-urban/.npmrc new file mode 100644 index 0000000..4b10cef --- /dev/null +++ b/front-urban/.npmrc @@ -0,0 +1,2 @@ +auto-install-peers=true +shamefully-hoist=true diff --git a/front-urban/.prettierrc.json b/front-urban/.prettierrc.json new file mode 100644 index 0000000..fef33e0 --- /dev/null +++ b/front-urban/.prettierrc.json @@ -0,0 +1,17 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "bracketSameLine": false, + "jsxSingleQuote": true, + "printWidth": 120, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "none", + "useTabs": false +} diff --git a/front-urban/.stylelintrc.json b/front-urban/.stylelintrc.json new file mode 100644 index 0000000..0408dc5 --- /dev/null +++ b/front-urban/.stylelintrc.json @@ -0,0 +1,16 @@ +{ + "plugins": [ + "stylelint-use-logical-spec" + ], + "overrides": [ + { + "customSyntax": "postcss-styled-syntax", + "files": [ + "**/*.{js,ts,jsx,tsx}" + ] + } + ], + "rules": { + "liberty/use-logical-spec": "always" + } +} diff --git a/front-urban/.vscode/custom.code-snippets b/front-urban/.vscode/custom.code-snippets new file mode 100644 index 0000000..141c1c6 --- /dev/null +++ b/front-urban/.vscode/custom.code-snippets @@ -0,0 +1,109 @@ +{ + // JavaScript Snippets + "exportDefault": { + "prefix": "exp", + "body": [ + "export default ${1:moduleName}", + "" + ] + }, + "exportDestructing": { + "prefix": "exd", + "body": [ + "export { ${2:destructuredModule} } from '${1:module}'", + "" + ] + }, + "exportAs": { + "prefix": "exa", + "body": [ + "export { ${2:originalName} as ${3:aliasName}} from '${1:module}'", + "" + ] + }, + "exportDefaultFunction": { + "prefix": "edf", + "body": [ + "export default (${1:params}) => {", + " $0", + "}", + "" + ] + }, + "exportDefaultNamedFunction": { + "prefix": "ednf", + "body": [ + "export default function ${1:functionName}(${2:params}) {", + " $0", + "}", + "" + ] + }, + // React Snippets + "reactArrowFunctionExportComponent": { + "prefix": "rafce", + "body": [ + "const ${1:ComponentName} = () => {", + " return (", + " $0", + " )", + "}", + "", + "export default ${1:ComponentName}", + "" + ] + }, + "reactArrowFunctionComponent": { + "prefix": "rafc", + "body": [ + "const ${1:ComponentName} = () => {", + " return (", + " $0", + " )", + "}", + "" + ] + }, + "reactUseState": { + "prefix": "useState", + "body": [ + "const [${1:state}, set${1/(.*)/${1:/capitalize}/}] = useState(${2:initialState})" + ] + }, + "reactUseEffect": { + "prefix": "useEffect", + "body": [ + "useEffect(() => {", + " $0", + "}, [])" + ] + }, + // Type Snippets + "exportType": { + "prefix": "exptp", + "body": [ + "export type ${1:Props} = {", + " ${2:name}: ${3:string}", + "}", + "" + ] + }, + "type": { + "prefix": "tp", + "body": [ + "type ${1:Props} = {", + " ${2:name}: ${3:string}", + "}", + "" + ] + }, + // Next Snippets + "nextImport": { + "prefix": "impn", + "body": [ + "// Next Import", + "import ${2:second} from '${1:first}'", + "" + ] + } +} diff --git a/front-urban/.vscode/extensions.json b/front-urban/.vscode/extensions.json new file mode 100644 index 0000000..74a42e0 --- /dev/null +++ b/front-urban/.vscode/extensions.json @@ -0,0 +1,26 @@ +{ + "recommendations": [ + "formulahendry.auto-close-tag", + "steoates.autoimport", + "mgmcdermott.vscode-language-babel", + "aaron-bond.better-comments", + "MohammadBaqer.better-folding", + "pustelto.bracketeer", + "streetsidesoftware.code-spell-checker", + "naumovs.color-highlight", + "mikestead.dotenv", + "EditorConfig.EditorConfig", + "usernamehw.errorlens", + "dbaeumer.vscode-eslint", + "eamodio.gitlens", + "antfu.iconify", + "xabikos.JavaScriptSnippets", + "christian-kohler.npm-intellisense", + "christian-kohler.path-intellisense", + "esbenp.prettier-vscode", + "yoavbls.pretty-ts-errors", + "jasonnutter.search-node-modules", + "stylelint.vscode-stylelint", + "styled-components.vscode-styled-components" + ] +} diff --git a/front-urban/.vscode/settings.json b/front-urban/.vscode/settings.json new file mode 100644 index 0000000..42cae1b --- /dev/null +++ b/front-urban/.vscode/settings.json @@ -0,0 +1,57 @@ +{ + // JS + "javascript.updateImportsOnFileMove.enabled": "always", + // JSON + "[json]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + "[jsonc]": { + "editor.defaultFormatter": "vscode.json-language-features" + }, + // VSCode Editor + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never", + "source.fixAll.stylelint": "explicit" + }, + // Extension: Git + "git.rebaseWhenSync": true, + "git.autofetch": true, + "git.enableSmartCommit": true, + // Extension: Prettier + "prettier.requireConfig": true, + // Extension: ESLint + "eslint.validate": [ + "javascript", + "typescript", + "javascriptreact", + "typescriptreact" + ], + "eslint.format.enable": true, + // Stylelint + "css.validate": false, + "less.validate": false, + "scss.validate": false, + "stylelint.enable": true, + "stylelint.validate": [ + "css", + "scss", + "typescript", + "typescriptreact" + ], + "markdown.extension.toc.updateOnSave": false, + "files.insertFinalNewline": true, + "editor.linkedEditing": true, + "typescript.tsdk": "node_modules/typescript/lib", + "cSpell.words": [ + "iconify" + ], + "[typescriptreact]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + }, + "[typescript]": { + "editor.defaultFormatter": "vscode.typescript-language-features" + } +} diff --git a/front-urban/Dockerfile b/front-urban/Dockerfile new file mode 100644 index 0000000..6d7be9a --- /dev/null +++ b/front-urban/Dockerfile @@ -0,0 +1,55 @@ +FROM node:22.9-alpine AS base +WORKDIR /app + +FROM base AS deps +RUN apk add --no-cache libc6-compat +COPY package.json package-lock.json ./ +# Instalar dependencias (lockfile desactualizado). Luego podrás volver a npm ci cuando esté sincronizado. +ENV npm_config_ignore_scripts=true +RUN npm install --legacy-peer-deps +ENV npm_config_ignore_scripts=false + +FROM deps AS builder +ENV NEXT_TELEMETRY_DISABLED=1 + +COPY next.config.mjs ./next.config.mjs +COPY tsconfig.json ./tsconfig.json +COPY postcss.config.mjs ./postcss.config.mjs +COPY tailwind.config.ts ./tailwind.config.ts +COPY public ./public +COPY src ./src +COPY .env* ./ + +ENV NEXT_PUBLIC_BACKEND_URL=https://backend.cl-danzas.valentin-romero.online +ENV NEXT_PUBLIC_API_URL=https://backend.cl-danzas.valentin-romero.online +ENV NEXT_PUBLIC_APP_URL=https://frontend.cl-danzas.valentin-romero.online +ENV NEXT_PUBLIC_MIN_AUTH=30 +ENV NEXT_PUBLIC_DOCS_URL=https://demos.themeselection.com/materio-mui-nextjs-admin-template/documentation +ENV NEXT_PUBLIC_PRO_URL=https://demos.themeselection.com/materio-mui-nextjs-admin-template/demo-1 +ENV NEXT_PUBLIC_REPO_NAME=materio-mui-nextjs-admin-template-free +ENV NEXT_PUBLIC_WHATSAPP_NUMBER=3434067735 +ENV REACT_EDITOR=code +ENV BACKEND_URL=http://urban_backend:3001 +# Generate icons (was postinstall) then build Next.js with output tracing +RUN npm run build:icons && npm run build + +FROM builder AS runner +WORKDIR /app +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +# Use non-root user +RUN addgroup -g 1001 -S nodejs && adduser -S -u 1001 nodejs + +# Copy only necessary runtime files +COPY --from=builder /app/package.json ./package.json +COPY --from=deps /app/node_modules ./node_modules +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static + +ENV PORT=3000 +EXPOSE 3000 +USER nodejs + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/front-urban/dockerignore b/front-urban/dockerignore new file mode 100644 index 0000000..cf23690 --- /dev/null +++ b/front-urban/dockerignore @@ -0,0 +1,10 @@ +node_modules +.next +.env* +.git +.gitignore +Dockerfile* +docker-compose* +**/*.log +coverage +pnpm-lock.yaml \ No newline at end of file diff --git a/front-urban/env.local b/front-urban/env.local new file mode 100644 index 0000000..3e0f245 --- /dev/null +++ b/front-urban/env.local @@ -0,0 +1 @@ +REACT_EDITOR=code diff --git a/front-urban/next.config.mjs b/front-urban/next.config.mjs new file mode 100644 index 0000000..e96c416 --- /dev/null +++ b/front-urban/next.config.mjs @@ -0,0 +1,9 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + output: 'standalone', + eslint: { + ignoreDuringBuilds: true, + }, +} + +export default nextConfig diff --git a/front-urban/package-lock.json b/front-urban/package-lock.json new file mode 100644 index 0000000..66435b0 --- /dev/null +++ b/front-urban/package-lock.json @@ -0,0 +1,10491 @@ +{ + "name": "next-app-test", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "next-app-test", + "version": "0.1.0", + "hasInstallScript": true, + "license": "Commercial", + "dependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", + "@mui/icons-material": "^5.14.0", + "@mui/lab": "5.0.0-alpha.170", + "@mui/material": "^5.15.19", + "@mui/material-nextjs": "^5.15.11", + "@mui/x-date-pickers": "^6.20.0", + "apexcharts": "^4.0.0", + "axios": "^1.10.0", + "classnames": "^2.5.1", + "dayjs": "^1.11.14", + "material-react-table": "^2.13.2", + "next": "^14.2.3", + "react": "^18.3.1", + "react-apexcharts": "^1.8.0", + "react-dom": "^18.3.1", + "react-dropzone": "^14.3.8", + "react-perfect-scrollbar": "^1.5.8", + "react-use": "^17.5.0", + "recharts": "^3.5.0", + "server-only": "^0.0.1", + "swr": "^2.3.6" + }, + "devDependencies": { + "@iconify/json": "^2.2.218", + "@iconify/tools": "^4.0.4", + "@iconify/types": "^2.0.0", + "@iconify/utils": "^2.1.24", + "@types/node": "^20.14.2", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@types/react-dropzone": "^4.2.2", + "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/parser": "^7.13.0", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "eslint-config-next": "^14.2.3", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "postcss": "^8.4.38", + "postcss-styled-syntax": "^0.6.4", + "prettier": "^3.3.2", + "stylelint": "^16.6.1", + "stylelint-use-logical-spec": "^5.0.1", + "tailwindcss": "^3.4.4", + "tailwindcss-logical": "^3.0.1", + "tsx": "^4.15.2", + "typescript": "^5.4.5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz", + "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz", + "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", + "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", + "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.0.0" + } + }, + "node_modules/@dual-bundle/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.4.tgz", + "integrity": "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", + "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.3.tgz", + "integrity": "sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.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.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "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.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz", + "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz", + "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz", + "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz", + "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz", + "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz", + "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz", + "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz", + "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz", + "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz", + "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz", + "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz", + "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz", + "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz", + "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz", + "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz", + "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz", + "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz", + "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz", + "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz", + "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz", + "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz", + "integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz", + "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz", + "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz", + "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz", + "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "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/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", + "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", + "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.7.2", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", + "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.7.2" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "license": "MIT" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" + }, + "node_modules/@iconify/json": { + "version": "2.2.356", + "resolved": "https://registry.npmjs.org/@iconify/json/-/json-2.2.356.tgz", + "integrity": "sha512-UVUnPLu154x8oa4GFNU3SPKkKcNbVpdNBLAGDhQFPVin2kf6dK6146WK5vDZsxs+366Mfdy8ZDkbatDqjlTcPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@iconify/types": "*", + "pathe": "^1.1.2" + } + }, + "node_modules/@iconify/tools": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@iconify/tools/-/tools-4.1.2.tgz", + "integrity": "sha512-q6NzLQYEN9zkDfcyBqD3vItHcZw97w/s++3H3TBxUORr57EfHxj6tOW6fyufDjMq+Vl56WXWaPx1csBPYlI5CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@iconify/types": "^2.0.0", + "@iconify/utils": "^2.3.0", + "@types/tar": "^6.1.13", + "axios": "^1.8.3", + "cheerio": "1.0.0", + "domhandler": "^5.0.3", + "extract-zip": "^2.0.1", + "local-pkg": "^0.5.1", + "pathe": "^1.1.2", + "svgo": "^3.3.2", + "tar": "^6.2.1" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz", + "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.0.0", + "@antfu/utils": "^8.1.0", + "@iconify/types": "^2.0.0", + "debug": "^4.4.0", + "globals": "^15.14.0", + "kolorist": "^1.8.0", + "local-pkg": "^1.0.0", + "mlly": "^1.7.4" + } + }, + "node_modules/@iconify/utils/node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@iconify/utils/node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@iconify/utils/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@iconify/utils/node_modules/pkg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", + "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@keyv/serialize": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz", + "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "deprecated": "This package has been replaced by @base-ui-components/react", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz", + "integrity": "sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.0.tgz", + "integrity": "sha512-z7lYNteDi1GMkF9JP/m2RWuCYK1M/FlaeBSUK7/IhIYzIXNhAVjfD8jRq5vFBV31qkEi2aGBS2z5SfLXwH6U0A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.22.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/lab": { + "version": "5.0.0-alpha.170", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.170.tgz", + "integrity": "sha512-0bDVECGmrNjd3+bLdcLiwYZ0O4HP5j5WSQm5DV6iA/Z9kr8O6AnvZ1bv9ImQbbX7Gj3pX4o43EKwCutj3EQxQg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/system": "^5.15.15", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material": ">=5.15.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz", + "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/core-downloads-tracker": "^5.18.0", + "@mui/system": "^5.18.0", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.0.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.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", + "react-dom": "^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/material-nextjs": { + "version": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/material-nextjs/-/material-nextjs-5.18.0.tgz", + "integrity": "sha512-LPmUAW+xlAF1pJqYe80X238k+PqPJxjnbk/akBGDRlG3PjSafc6VbKabcr71ogTOmW4aqj7Lj6LM+YESJzYzbA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/server": "^11.11.0", + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "next": "^13.0.0 || ^14.0.0 || ^15.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/cache": { + "optional": true + }, + "@emotion/server": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.17.1.tgz", + "integrity": "sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.17.1", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.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": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.18.0.tgz", + "integrity": "sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.13.5", + "@emotion/serialize": "^1.3.3", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.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": "5.18.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.18.0.tgz", + "integrity": "sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.17.1", + "@mui/styled-engine": "^5.18.0", + "@mui/types": "~7.2.15", + "@mui/utils": "^5.17.1", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.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/system/node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz", + "integrity": "sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.17.1.tgz", + "integrity": "sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/types": "~7.2.15", + "@types/prop-types": "^15.7.12", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.0.0" + }, + "engines": { + "node": ">=12.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/utils/node_modules/@mui/types": { + "version": "7.2.24", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.24.tgz", + "integrity": "sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "6.20.2", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.20.2.tgz", + "integrity": "sha512-x1jLg8R+WhvkmUETRfX2wC+xJreMii78EXKLl6r3G+ggcAZlPyt0myID1Amf6hvJb9CtR7CgUo8BwR+1Vx9Ggw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/base": "^5.0.0-beta.22", + "@mui/utils": "^5.14.16", + "@types/react-transition-group": "^4.4.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.8.6", + "@mui/system": "^5.8.0", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.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/@napi-rs/wasm-runtime": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", + "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@next/env": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.30.tgz", + "integrity": "sha512-KBiBKrDY6kxTQWGzKjQB7QirL3PiiOkV7KW98leHFjtVRKtft76Ra5qSA/SL75xT44dp6hOcqiiJ6iievLOYug==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.2.30.tgz", + "integrity": "sha512-mvVsMIutMxQ4NGZEMZ1kiBNc+la8Xmlk30bKUmCPQz2eFkmsLv54Mha8QZarMaCtSPkkFA1TMD+FIZk0l/PpzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "10.3.10" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.30.tgz", + "integrity": "sha512-EAqfOTb3bTGh9+ewpO/jC59uACadRHM6TSA9DdxJB/6gxOpyV+zrbqeXiFTDy9uV6bmipFDkfpAskeaDcO+7/g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.30.tgz", + "integrity": "sha512-TyO7Wz1IKE2kGv8dwQ0bmPL3s44EKVencOqwIY69myoS3rdpO1NPg5xPM5ymKu7nfX4oYJrpMxv8G9iqLsnL4A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.30.tgz", + "integrity": "sha512-I5lg1fgPJ7I5dk6mr3qCH1hJYKJu1FsfKSiTKoYwcuUf53HWTrEkwmMI0t5ojFKeA6Vu+SfT2zVy5NS0QLXV4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.30.tgz", + "integrity": "sha512-8GkNA+sLclQyxgzCDs2/2GSwBc92QLMrmYAmoP2xehe5MUKBLB2cgo34Yu242L1siSkwQkiV4YLdCnjwc/Micw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.30.tgz", + "integrity": "sha512-8Ly7okjssLuBoe8qaRCcjGtcMsv79hwzn/63wNeIkzJVFVX06h5S737XNr7DZwlsbTBDOyI6qbL2BJB5n6TV/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.30.tgz", + "integrity": "sha512-dBmV1lLNeX4mR7uI7KNVHsGQU+OgTG5RGFPi3tBJpsKPvOPtg9poyav/BYWrB3GPQL4dW5YGGgalwZ79WukbKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.30.tgz", + "integrity": "sha512-6MMHi2Qc1Gkq+4YLXAgbYslE1f9zMGBikKMdmQRHXjkGPot1JY3n5/Qrbg40Uvbi8//wYnydPnyvNhI1DMUW1g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.30.tgz", + "integrity": "sha512-pVZMnFok5qEX4RT59mK2hEVtJX+XFfak+/rjHpyFh7juiT52r177bfFKhnlafm0UOSldhXjj32b+LZIOdswGTg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.30.tgz", + "integrity": "sha512-4KCo8hMZXMjpTzs3HOqOGYYwAXymXIy7PEPAXNEcEOyKqkjiDlECumrWziy+JEF0Oi4ILHGxzgQ3YiMGG2t/Lg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "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==", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "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/@reduxjs/toolkit": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.0.tgz", + "integrity": "sha512-hBjYg0aaRL1O2Z0IqWhnTLytnjDIxekmRxm1snsHjHaKVmIF1HiImWqsq+PuEbn6zdMlkIj9WofK1vR8jjx+Xw==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "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/@reduxjs/toolkit/node_modules/immer": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.0.0.tgz", + "integrity": "sha512-XtRG4SINt4dpqlnJvs70O2j6hH7H0X8fUzFsjMn1rwnETaxwp83HLNimXBjZ78MrKl3/d3/pkzDH0o0Lkxm37Q==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.12.0.tgz", + "integrity": "sha512-5EwMtOqvJMMa3HbmxLlF74e+3/HhwBTMcvt3nqVJgGCozO6hzIPOBlwm8mGVNR9SN2IJpxSnlxczyDjcn7qIyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, + "node_modules/@svgdotjs/svg.draggable.js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.draggable.js/-/svg.draggable.js-3.0.6.tgz", + "integrity": "sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA==", + "license": "MIT", + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4" + } + }, + "node_modules/@svgdotjs/svg.filter.js": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.filter.js/-/svg.filter.js-3.0.9.tgz", + "integrity": "sha512-/69XMRCDoam2HgC4ldHIaDgeQf1ViHIsa0Ld4uWgiXtZ+E24DWHe/9Ib6kbNiZ7WRIdlVokUDR1Fg0kjIpkfbw==", + "license": "MIT", + "dependencies": { + "@svgdotjs/svg.js": "^3.2.4" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@svgdotjs/svg.js": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.5.tgz", + "integrity": "sha512-/VNHWYhNu+BS7ktbYoVGrCmsXDh+chFMaONMwGNdIBcFHrWqk2jY8fNyr3DLdtQUIalvkPfM554ZSFa3dm3nxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Fuzzyma" + } + }, + "node_modules/@svgdotjs/svg.resize.js": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.resize.js/-/svg.resize.js-2.0.5.tgz", + "integrity": "sha512-4heRW4B1QrJeENfi7326lUPYBCevj78FJs8kfeDxn5st0IYPIRXoTtOSYvTzFWgaWWXd3YCDE6ao4fmv91RthA==", + "license": "MIT", + "engines": { + "node": ">= 14.18" + }, + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4", + "@svgdotjs/svg.select.js": "^4.0.1" + } + }, + "node_modules/@svgdotjs/svg.select.js": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.select.js/-/svg.select.js-4.0.3.tgz", + "integrity": "sha512-qkMgso1sd2hXKd1FZ1weO7ANq12sNmQJeGDjs46QwDVsxSRcHmvWKL2NDF7Yimpwf3sl5esOLkPqtV2bQ3v/Jg==", + "license": "MIT", + "engines": { + "node": ">= 14.18" + }, + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@tanstack/match-sorter-utils": { + "version": "8.19.4", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz", + "integrity": "sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==", + "license": "MIT", + "dependencies": { + "remove-accents": "0.5.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.5.tgz", + "integrity": "sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==", + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.20.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/react-virtual": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.6.tgz", + "integrity": "sha512-xaSy6uUxB92O8mngHZ6CvbhGuqxQ5lIZWCBy+FjhrbHmOwc6BnOnKkYm2FsB1/BpKw/+FVctlMbEtI+F6I1aJg==", + "license": "MIT", + "dependencies": { + "@tanstack/virtual-core": "3.10.6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.20.5", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.5.tgz", + "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.6.tgz", + "integrity": "sha512-1giLc4dzgEKLMx5pgKjL6HlG5fjZMgCjzlKAlpr7yoUtetVPELgER1NtephAI910nMwfPTHNyWKSFmJdHkz2Cw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", + "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "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-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "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.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "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/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/js-cookie": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", + "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.6.tgz", + "integrity": "sha512-uYssdp9z5zH5GQ0L4zEJ2ZuavYsJwkozjiUzCRfGtaaQcyjAMJ34aP8idv61QlqTozu6kudyr6JMq9Chf09dfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "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.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz", + "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@types/react-dropzone": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dropzone/-/react-dropzone-4.2.2.tgz", + "integrity": "sha512-okO6HY+w7V0uHoy6JpLY6BwY/s/oObtXZmUQdX0ycjPeLhK8Af/xf79CFkLA1fM6oVp16n1d962ejdkEXk375Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "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/tar": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "minipass": "^4.0.0" + } + }, + "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/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "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.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "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.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@xobotyi/scrollbar-width": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", + "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==", + "license": "MIT" + }, + "node_modules/@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "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==", + "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==", + "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-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apexcharts": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-4.7.0.tgz", + "integrity": "sha512-iZSrrBGvVlL+nt2B1NpqfDuBZ9jX61X9I2+XV0hlYXHtTwhwLTHDKGXjNXAgFBDLuvSYCB/rq2nPWVPRv2DrGA==", + "license": "MIT", + "dependencies": { + "@svgdotjs/svg.draggable.js": "^3.0.4", + "@svgdotjs/svg.filter.js": "^3.0.8", + "@svgdotjs/svg.js": "^3.2.4", + "@svgdotjs/svg.resize.js": "^2.0.2", + "@svgdotjs/svg.select.js": "^4.0.1", + "@yr/monotone-cubic-spline": "^1.0.3" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/attr-accept": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "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/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "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/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/cacheable": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.1.tgz", + "integrity": "sha512-Fa2BZY0CS9F0PFc/6aVA6tgpOdw+hmv9dkZOlHXII5v5Hw+meJBIWDcPrG9q/dXxGcNbym5t77fzmawrBQfTmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hookified": "^1.10.0", + "keyv": "^5.3.4" + } + }, + "node_modules/cacheable/node_modules/keyv": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.4.tgz", + "integrity": "sha512-ypEvQvInNpUe+u+w8BIcPkQvEqXquyyibWE/1NB5T2BTzIpS5cGEV1LZskDzPSTvNAaT4+5FutvzlvnkxOSKlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.0.3" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "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/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/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/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/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==", + "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==", + "license": "MIT" + }, + "node_modules/colord": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", + "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "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/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, + "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/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-functions-list": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz", + "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12 || >=16" + } + }, + "node_modules/css-in-js-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz", + "integrity": "sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==", + "license": "MIT", + "dependencies": { + "hyphenate-style-name": "^1.0.3" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, + "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-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "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/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.11.14", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.14.tgz", + "integrity": "sha512-E8fIdSxUlyqSA8XYGnNa3IkIzxtEmFjI+JU/6ic0P1zmSqyL6HyG5jHnpPjRguDNiaHLpfvHKWFiohNsJLqcJQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "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==", + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true, + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.181", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.181.tgz", + "integrity": "sha512-+ISMj8OIQ+0qEeDj14Rt8WwcTOiqHyAB+5bnK1K7xNNLjBJ4hRCQfUkw8RWtcLbfBzDwc15ZnKH0c7SNOfwiyA==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/error-stack-parser": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz", + "integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-toolkit": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.42.0.tgz", + "integrity": "sha512-SLHIyY7VfDJBM8clz4+T2oquwTQxEzu263AyhVK4jREOAwJ+8eebaa4wM3nlvnAqhDrMm2EsA6hWHaQsMPQ1nA==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, + "node_modules/esbuild": { + "version": "0.25.6", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz", + "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.6", + "@esbuild/android-arm": "0.25.6", + "@esbuild/android-arm64": "0.25.6", + "@esbuild/android-x64": "0.25.6", + "@esbuild/darwin-arm64": "0.25.6", + "@esbuild/darwin-x64": "0.25.6", + "@esbuild/freebsd-arm64": "0.25.6", + "@esbuild/freebsd-x64": "0.25.6", + "@esbuild/linux-arm": "0.25.6", + "@esbuild/linux-arm64": "0.25.6", + "@esbuild/linux-ia32": "0.25.6", + "@esbuild/linux-loong64": "0.25.6", + "@esbuild/linux-mips64el": "0.25.6", + "@esbuild/linux-ppc64": "0.25.6", + "@esbuild/linux-riscv64": "0.25.6", + "@esbuild/linux-s390x": "0.25.6", + "@esbuild/linux-x64": "0.25.6", + "@esbuild/netbsd-arm64": "0.25.6", + "@esbuild/netbsd-x64": "0.25.6", + "@esbuild/openbsd-arm64": "0.25.6", + "@esbuild/openbsd-x64": "0.25.6", + "@esbuild/openharmony-arm64": "0.25.6", + "@esbuild/sunos-x64": "0.25.6", + "@esbuild/win32-arm64": "0.25.6", + "@esbuild/win32-ia32": "0.25.6", + "@esbuild/win32-x64": "0.25.6" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.2.30.tgz", + "integrity": "sha512-4pTMb3wfpI+piVeEz3TWG1spjuXJJBZaYabi2H08z2ZTk6/N304POEovHdFmK6EZb4QlKpETulBNaRIITA0+xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "14.2.30", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/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/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/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/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0-canary-7118f5dd7-20230705", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz", + "integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==", + "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" + } + }, + "node_modules/eslint-plugin-react-perf": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-perf/-/eslint-plugin-react-perf-3.3.3.tgz", + "integrity": "sha512-EzPdxsRJg5IllCAH9ny/3nK7sv9251tvKmi/d3Ouv5KzI8TB3zNhzScxL9wnh9Hvv8GYC5LEtzTauynfOEYiAw==", + "license": "MIT", + "engines": { + "node": ">=6.9.1" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/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/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.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==", + "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==", + "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==", + "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==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "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.8" + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/fast-shallow-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz", + "integrity": "sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastest-stable-stringify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz", + "integrity": "sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-selector": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz", + "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==", + "license": "MIT", + "dependencies": { + "tslib": "^2.7.0" + }, + "engines": { + "node": ">= 12" + } + }, + "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==", + "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": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/highlight-words": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/highlight-words/-/highlight-words-1.2.2.tgz", + "integrity": "sha512-Mf4xfPXYm8Ay1wTibCrHpNWeR2nUMynMVFkXCi4mbl+TEgmNOe+I4hV7W3OCZcSvzGL6kupaqpfHOemliMTGxQ==", + "license": "MIT", + "engines": { + "node": ">= 16", + "npm": ">= 8" + } + }, + "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/hookified": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.10.0.tgz", + "integrity": "sha512-dJw0492Iddsj56U1JsSTm9E/0B/29a1AuoSLRAte8vQg/kaTGF3IgjEWT8c8yG4cC10+HisE1x5QAwR0Xwc+DA==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" + } + }, + "node_modules/hyphenate-style-name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz", + "integrity": "sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==", + "license": "BSD-3-Clause" + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "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": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/inline-style-prefixer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-7.0.1.tgz", + "integrity": "sha512-lhYo5qNTQp3EvSSp3sRvXMbVQTLrvGV6DycRMJ5dm2BLMiJ30wpXKdDdgX+GmJZ5uQMucwRKHamXSst3Sj/Giw==", + "license": "MIT", + "dependencies": { + "css-in-js-utils": "^3.1.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "license": "MIT" + }, + "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==", + "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==", + "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==", + "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==", + "license": "MIT" + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.37.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", + "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "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/local-pkg": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz", + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.7.3", + "pkg-types": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "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==", + "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==", + "license": "MIT" + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "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/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/material-react-table": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/material-react-table/-/material-react-table-2.13.2.tgz", + "integrity": "sha512-8q2Jq723rqCNNxZ9yKZOBU9A2EzcdjT/6IQIXoigRZO2IUROEhcv5bvg8Sqojz+Au5bNQJ8f7RNzSP1UOzirNA==", + "license": "MIT", + "dependencies": { + "@tanstack/match-sorter-utils": "8.19.4", + "@tanstack/react-table": "8.20.5", + "@tanstack/react-virtual": "3.10.6", + "highlight-words": "1.2.2" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kevinvandy" + }, + "peerDependencies": { + "@emotion/react": ">=11.11", + "@emotion/styled": ">=11.11", + "@mui/icons-material": ">=5.11", + "@mui/material": ">=5.13", + "@mui/x-date-pickers": ">=6.15.0", + "react": ">=17.0", + "react-dom": ">=17.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "license": "CC0-1.0" + }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "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/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nano-css": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.2.tgz", + "integrity": "sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==", + "license": "Unlicense", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "css-tree": "^1.1.2", + "csstype": "^3.1.2", + "fastest-stable-stringify": "^2.0.2", + "inline-style-prefixer": "^7.0.1", + "rtl-css-js": "^1.16.1", + "stacktrace-js": "^2.0.2", + "stylis": "^4.3.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/nano-css/node_modules/stylis": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/napi-postinstall": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.0.tgz", + "integrity": "sha512-M7NqKyhODKV1gRLdkwE7pDsZP2/SC2a2vHkOYh9MCpKMbWVfyVfUw5MaH83Fv6XMjxr5jryUp3IDDL9rlxsTeA==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/next": { + "version": "14.2.30", + "resolved": "https://registry.npmjs.org/next/-/next-14.2.30.tgz", + "integrity": "sha512-+COdu6HQrHHFQ1S/8BBsCag61jZacmvbuL2avHvQFbWa2Ox7bE+d8FyNgxRLjXQ5wtPyQwEmk85js/AuaG2Sbg==", + "license": "MIT", + "dependencies": { + "@next/env": "14.2.30", + "@swc/helpers": "0.5.5", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001579", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.2.30", + "@next/swc-darwin-x64": "14.2.30", + "@next/swc-linux-arm64-gnu": "14.2.30", + "@next/swc-linux-arm64-musl": "14.2.30", + "@next/swc-linux-x64-gnu": "14.2.30", + "@next/swc-linux-x64-musl": "14.2.30", + "@next/swc-win32-arm64-msvc": "14.2.30", + "@next/swc-win32-ia32-msvc": "14.2.30", + "@next/swc-win32-x64-msvc": "14.2.30" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.41.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "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/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "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/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "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==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.3.0.tgz", + "integrity": "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==", + "dev": true, + "license": "MIT" + }, + "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/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "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==", + "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==", + "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-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "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/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-scrollbar": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.6.tgz", + "integrity": "sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==", + "license": "MIT" + }, + "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/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/pkg-types/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-nested/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", + "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", + "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-styled-syntax": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/postcss-styled-syntax/-/postcss-styled-syntax-0.6.4.tgz", + "integrity": "sha512-uWiLn+9rKgIghUYmTHvXMR6MnyPULMe9Gv3bV537Fg4FH6CA6cn21WMjKss2Qb98LUhT847tKfnRGG3FhSOgUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=14.17" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "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/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT" + }, + "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==", + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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-apexcharts": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.8.0.tgz", + "integrity": "sha512-MuEp56gc0NMO2UUgY94fxQzoBE4XEjmcCha4xYY0vJdRrc1yfFFZE4QrCekOt2wcS3nibghzca/q/CbgkAgN5w==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "apexcharts": ">=4.0.0", + "react": ">=0.13" + } + }, + "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-dropzone": { + "version": "14.3.8", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz", + "integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==", + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-is": { + "version": "19.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.1.0.tgz", + "integrity": "sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==", + "license": "MIT" + }, + "node_modules/react-perfect-scrollbar": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/react-perfect-scrollbar/-/react-perfect-scrollbar-1.5.8.tgz", + "integrity": "sha512-bQ46m70gp/HJtiBOF3gRzBISSZn8FFGNxznTdmTG8AAwpxG1bJCyn7shrgjEvGSQ5FJEafVEiosY+ccER11OSA==", + "license": "MIT", + "dependencies": { + "perfect-scrollbar": "^1.5.0", + "prop-types": "^15.6.1" + }, + "peerDependencies": { + "react": ">=16.3.3", + "react-dom": ">=16.3.3" + } + }, + "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/react-universal-interface": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz", + "integrity": "sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==", + "peerDependencies": { + "react": "*", + "tslib": "*" + } + }, + "node_modules/react-use": { + "version": "17.6.0", + "resolved": "https://registry.npmjs.org/react-use/-/react-use-17.6.0.tgz", + "integrity": "sha512-OmedEScUMKFfzn1Ir8dBxiLLSOzhKe/dPZwVxcujweSj45aNM7BEGPb9BEVIgVEqEXx6f3/TsXzwIktNgUR02g==", + "license": "Unlicense", + "dependencies": { + "@types/js-cookie": "^2.2.6", + "@xobotyi/scrollbar-width": "^1.9.5", + "copy-to-clipboard": "^3.3.1", + "fast-deep-equal": "^3.1.3", + "fast-shallow-equal": "^1.0.0", + "js-cookie": "^2.2.1", + "nano-css": "^5.6.2", + "react-universal-interface": "^0.6.2", + "resize-observer-polyfill": "^1.5.1", + "screenfull": "^5.1.0", + "set-harmonic-interval": "^1.0.1", + "throttle-debounce": "^3.0.1", + "ts-easing": "^0.2.0", + "tslib": "^2.1.0" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recharts": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.5.0.tgz", + "integrity": "sha512-jWqBtu8L3VICXWa3g/y+bKjL8DDHSRme7DHD/70LQ/Tk0di1h11Y0kKC0nPh6YJ2oaa0k6anIFNhg6SfzHWdEA==", + "license": "MIT", + "workspaces": [ + "www" + ], + "dependencies": { + "@reduxjs/toolkit": "1.x.x || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eslint-plugin-react-perf": "^3.3.3", + "eventemitter3": "^5.0.1", + "immer": "^10.1.1", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.1.1", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.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/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==", + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "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/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rtl-css-js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz", + "integrity": "sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.1.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==", + "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/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "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/screenfull": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz", + "integrity": "sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/server-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz", + "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-harmonic-interval": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", + "integrity": "sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==", + "license": "Unlicense", + "engines": { + "node": ">=6.9" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "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==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stack-generator": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz", + "integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==", + "license": "MIT", + "dependencies": { + "stackframe": "^1.3.4" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "license": "MIT" + }, + "node_modules/stacktrace-gps": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz", + "integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==", + "license": "MIT", + "dependencies": { + "source-map": "0.5.6", + "stackframe": "^1.3.4" + } + }, + "node_modules/stacktrace-gps/node_modules/source-map": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", + "integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stacktrace-js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz", + "integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==", + "license": "MIT", + "dependencies": { + "error-stack-parser": "^2.0.6", + "stack-generator": "^2.0.5", + "stacktrace-gps": "^3.0.4" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylelint": { + "version": "16.21.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.21.1.tgz", + "integrity": "sha512-WCXdXnYK2tpCbebgMF0Bme3YZH/Rh/UXerj75twYo4uLULlcrLwFVdZTvTEF8idFnAcW21YUDJFyKOfaf6xJRw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "@csstools/media-query-list-parser": "^4.0.3", + "@csstools/selector-specificity": "^5.0.0", + "@dual-bundle/import-meta-resolve": "^4.1.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.3", + "css-tree": "^3.1.0", + "debug": "^4.4.1", + "fast-glob": "^3.3.3", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^10.1.1", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^7.0.5", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.37.0", + "mathml-tag-names": "^2.1.3", + "meow": "^13.2.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.5.6", + "postcss-resolve-nested-selector": "^0.1.6", + "postcss-safe-parser": "^7.0.1", + "postcss-selector-parser": "^7.1.0", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "supports-hyperlinks": "^3.2.0", + "svg-tags": "^1.0.0", + "table": "^6.9.0", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/stylelint-use-logical-spec": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/stylelint-use-logical-spec/-/stylelint-use-logical-spec-5.0.1.tgz", + "integrity": "sha512-UfLB4LW6iG4r3cXxjxkiHQrFyhWFqt8FpNNngD+TyvgMWSokk5TYwTvBHS3atUvZhOogllTOe/PUrGE+4z84AA==", + "dev": true, + "license": "CC0-1.0", + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "stylelint": ">=11 < 17" + } + }, + "node_modules/stylelint/node_modules/balanced-match": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/stylelint/node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.1.1.tgz", + "integrity": "sha512-zcmsHjg2B2zjuBgjdnB+9q0+cWcgWfykIcsDkWDB4GTPtl1eXUA+gTI6sO0u01AqK3cliHryTU55/b2Ow1hfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^6.1.10" + } + }, + "node_modules/stylelint/node_modules/flat-cache": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.11.tgz", + "integrity": "sha512-zfOAns94mp7bHG/vCn9Ru2eDCmIxVQ5dELUHKjHfDEOJmHNzE+uGa6208kfkgmtym4a0FFjEuFksCXFacbVhSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cacheable": "^1.10.1", + "flatted": "^3.3.3", + "hookified": "^1.10.0" + } + }, + "node_modules/stylelint/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint/node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stylelint/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", + "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + }, + "funding": { + "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" + } + }, + "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/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/svgo": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/svgo/node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/swr": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.6.tgz", + "integrity": "sha512-wfHRmHWk/isGNMwlLGlZX5Gzz/uTgo0o2IRuTMcf4CPuPFJZlq0rDaKUx+ozB5nBOReNV1kiOyzMfj+MBMikLw==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.3", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/table": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", + "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.17", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz", + "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.6", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-logical": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tailwindcss-logical/-/tailwindcss-logical-3.0.1.tgz", + "integrity": "sha512-mv585RJfzS/Cu9Rpl2M5H+JSOdU3qjLHzKMtg63oD5lXfehRJpldbEqll20Obvlexq0Cmyg86l7cmb/I5hEutg==", + "dev": true, + "license": "ISC", + "dependencies": { + "tailwindcss": "3.3.1" + } + }, + "node_modules/tailwindcss-logical/node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/tailwindcss-logical/node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/tailwindcss-logical/node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/tailwindcss-logical/node_modules/postcss-nested": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/tailwindcss-logical/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tailwindcss-logical/node_modules/tailwindcss": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.1.tgz", + "integrity": "sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.17.2", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.0.9", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.11", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1", + "sucrase": "^3.29.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/tailwindcss/node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tailwindcss/node_modules/yaml": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/throttle-debounce": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz", + "integrity": "sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", + "license": "MIT" + }, + "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/ts-easing": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz", + "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", + "license": "Unlicense" + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz", + "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici": { + "version": "6.21.3", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", + "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.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==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", + "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/victory-vendor": { + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "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/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/front-urban/package.json b/front-urban/package.json new file mode 100644 index 0000000..a17960c --- /dev/null +++ b/front-urban/package.json @@ -0,0 +1,75 @@ +{ + "name": "next-app-test", + "version": "0.1.0", + "license": "Commercial", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint", + "lint:fix": "next lint --fix", + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"", + "build:icons": "tsx src/assets/iconify-icons/bundle-icons-css.ts", + "postinstall": "npm run build:icons" + }, + "dependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.5", + "@mui/icons-material": "^5.14.0", + "@mui/lab": "5.0.0-alpha.170", + "@mui/material": "^5.15.19", + "@mui/material-nextjs": "^5.15.11", + "axios": "^1.10.0", + "classnames": "^2.5.1", + "dayjs": "^1.11.14", + "material-react-table": "^2.13.2", + "next": "^14.2.3", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-dropzone": "^14.3.8", + "react-perfect-scrollbar": "^1.5.8", + "react-apexcharts": "^1.8.0", + "apexcharts": "^4.0.0", + "@mui/x-date-pickers": "^6.20.0", + "react-use": "^17.5.0", + "recharts": "^3.5.0", + "server-only": "^0.0.1", + "swr": "^2.3.6" + }, + "devDependencies": { + "@iconify/json": "^2.2.218", + "@iconify/tools": "^4.0.4", + "@iconify/types": "^2.0.0", + "@iconify/utils": "^2.1.24", + "@types/node": "^20.14.2", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@types/react-dropzone": "^4.2.2", + "@typescript-eslint/eslint-plugin": "^7.13.0", + "@typescript-eslint/parser": "^7.13.0", + "autoprefixer": "^10.4.19", + "eslint": "^8.57.0", + "eslint-config-next": "^14.2.3", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "postcss": "^8.4.38", + "postcss-styled-syntax": "^0.6.4", + "prettier": "^3.3.2", + "stylelint": "^16.6.1", + "stylelint-use-logical-spec": "^5.0.1", + "tailwindcss": "^3.4.4", + "tailwindcss-logical": "^3.0.1", + "tsx": "^4.15.2", + "typescript": "^5.4.5" + }, + "resolutions": { + "rimraf": "^5.0.7" + }, + "overrides": { + "react": "^18.3.1", + "rimraf": "^5.0.7" + } +} diff --git a/front-urban/pnpm-lock.yaml b/front-urban/pnpm-lock.yaml new file mode 100644 index 0000000..9802f06 --- /dev/null +++ b/front-urban/pnpm-lock.yaml @@ -0,0 +1,5895 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + rimraf: ^5.0.7 + +importers: + + .: + dependencies: + '@emotion/cache': + specifier: ^11.11.0 + version: 11.11.0 + '@emotion/react': + specifier: ^11.11.4 + version: 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': + specifier: ^11.11.5 + version: 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/lab': + specifier: 5.0.0-alpha.170 + version: 5.0.0-alpha.170(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': + specifier: ^5.15.19 + version: 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material-nextjs': + specifier: ^5.15.11 + version: 5.15.11(@emotion/cache@11.11.0)(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + apexcharts: + specifier: ^3.49.1 + version: 3.49.1 + classnames: + specifier: ^2.5.1 + version: 2.5.1 + next: + specifier: ^14.2.3 + version: 14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: ^18.3.1 + version: 18.3.1 + react-apexcharts: + specifier: ^1.4.1 + version: 1.4.1(apexcharts@3.49.1)(react@18.3.1) + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-perfect-scrollbar: + specifier: ^1.5.8 + version: 1.5.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-use: + specifier: ^17.5.0 + version: 17.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + server-only: + specifier: ^0.0.1 + version: 0.0.1 + devDependencies: + '@iconify/json': + specifier: ^2.2.218 + version: 2.2.219 + '@iconify/tools': + specifier: ^4.0.4 + version: 4.0.4 + '@iconify/types': + specifier: ^2.0.0 + version: 2.0.0 + '@iconify/utils': + specifier: ^2.1.24 + version: 2.1.24 + '@types/node': + specifier: ^20.14.2 + version: 20.14.2 + '@types/react': + specifier: ^18.3.3 + version: 18.3.3 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.0 + '@typescript-eslint/eslint-plugin': + specifier: ^7.13.0 + version: 7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.13.0 + version: 7.13.0(eslint@8.57.0)(typescript@5.4.5) + autoprefixer: + specifier: ^10.4.19 + version: 10.4.19(postcss@8.4.38) + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-config-next: + specifier: ^14.2.3 + version: 14.2.4(eslint@8.57.0)(typescript@5.4.5) + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@8.57.0) + eslint-import-resolver-typescript: + specifier: ^3.6.1 + version: 3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: + specifier: ^2.29.1 + version: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + postcss: + specifier: ^8.4.38 + version: 8.4.38 + postcss-styled-syntax: + specifier: ^0.6.4 + version: 0.6.4(postcss@8.4.38) + prettier: + specifier: ^3.3.2 + version: 3.3.2 + stylelint: + specifier: ^16.6.1 + version: 16.6.1(typescript@5.4.5) + stylelint-use-logical-spec: + specifier: ^5.0.1 + version: 5.0.1(stylelint@16.6.1(typescript@5.4.5)) + tailwindcss: + specifier: ^3.4.4 + version: 3.4.4 + tailwindcss-logical: + specifier: ^3.0.1 + version: 3.0.1(postcss@8.4.38) + tsx: + specifier: ^4.15.2 + version: 4.15.5 + typescript: + specifier: ^5.4.5 + version: 5.4.5 + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@antfu/install-pkg@0.1.1': + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + + '@antfu/utils@0.7.8': + resolution: {integrity: sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.7': + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime@7.24.7': + resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.24.7': + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.7': + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + + '@csstools/css-parser-algorithms@2.6.3': + resolution: {integrity: sha512-xI/tL2zxzEbESvnSxwFgwvy5HS00oCXxL4MLs6HUiDcYfwowsoQaABKxUElp1ARITrINzBnsECOc1q0eg2GOrA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-tokenizer': ^2.3.1 + + '@csstools/css-tokenizer@2.3.1': + resolution: {integrity: sha512-iMNHTyxLbBlWIfGtabT157LH9DUx9X8+Y3oymFEuMj8HNc+rpE3dPFGFgHjpKfjeFDjLjYIAIhXPGvS2lKxL9g==} + engines: {node: ^14 || ^16 || >=18} + + '@csstools/media-query-list-parser@2.1.11': + resolution: {integrity: sha512-uox5MVhvNHqitPP+SynrB1o8oPxPMt2JLgp5ghJOWf54WGQ5OKu47efne49r1SWqs3wRP8xSWjnO9MBKxhB1dA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + '@csstools/css-parser-algorithms': ^2.6.3 + '@csstools/css-tokenizer': ^2.3.1 + + '@csstools/selector-specificity@3.1.1': + resolution: {integrity: sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss-selector-parser: ^6.0.13 + + '@dual-bundle/import-meta-resolve@4.1.0': + resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==} + + '@emotion/babel-plugin@11.11.0': + resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} + + '@emotion/cache@11.11.0': + resolution: {integrity: sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==} + + '@emotion/hash@0.9.1': + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + + '@emotion/is-prop-valid@1.2.2': + resolution: {integrity: sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==} + + '@emotion/memoize@0.8.1': + resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + + '@emotion/react@11.11.4': + resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/serialize@1.1.4': + resolution: {integrity: sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==} + + '@emotion/sheet@1.2.2': + resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} + + '@emotion/styled@11.11.5': + resolution: {integrity: sha512-/ZjjnaNKvuMPxcIiUkf/9SHoG4Q196DRl1w82hQ3WCsjo1IUR8uaGWrC6a87CrYAW0Kb/pK7hk8BnLgLRi9KoQ==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/unitless@0.8.1': + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + + '@emotion/use-insertion-effect-with-fallbacks@1.0.1': + resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + peerDependencies: + react: '>=16.8.0' + + '@emotion/utils@1.2.1': + resolution: {integrity: sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==} + + '@emotion/weak-memoize@0.3.1': + resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.10.1': + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@floating-ui/core@1.6.2': + resolution: {integrity: sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==} + + '@floating-ui/dom@1.6.5': + resolution: {integrity: sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==} + + '@floating-ui/react-dom@2.1.0': + resolution: {integrity: sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.2': + resolution: {integrity: sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@iconify/json@2.2.219': + resolution: {integrity: sha512-q8asqbM61woVZ9rJGm/gvW46i5vdeHrq4TqZQ/5wF5ypk4pAZU9+4qVa5NQE2MZngYkMPeO68PDGGl7WaEV8jQ==} + + '@iconify/tools@4.0.4': + resolution: {integrity: sha512-hX1Z3i1Tm6JxyrDv45jNEijPpepZZfal/4leFGtUC04H9LsgRo597BOBFB9PUZsQdFGLOxVUUfv6lqU/dC+xXw==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.24': + resolution: {integrity: sha512-H8r2KpL5uKyrkb3z9/3HD/22JcxqW3BJyjEWZhX2T7DehnYVZthEap1cNsEl/UtCDC3TlpNmwiPX8wg3y8E4dg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@mui/base@5.0.0-beta.40': + resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/core-downloads-tracker@5.15.20': + resolution: {integrity: sha512-DoL2ppgldL16utL8nNyj/P12f8mCNdx/Hb/AJnX9rLY4b52hCMIx1kH83pbXQ6uMy6n54M3StmEbvSGoj2OFuA==} + + '@mui/lab@5.0.0-alpha.170': + resolution: {integrity: sha512-0bDVECGmrNjd3+bLdcLiwYZ0O4HP5j5WSQm5DV6iA/Z9kr8O6AnvZ1bv9ImQbbX7Gj3pX4o43EKwCutj3EQxQg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material': '>=5.15.0' + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/material-nextjs@5.15.11': + resolution: {integrity: sha512-cp5RWYbBngyi7NKP91R9QITllfxumCVPFjqe4AKzNROVuCot0VpgkafxXqfbv0uFsyUU0ROs0O2M3r17q604Aw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/cache': ^11.11.0 + '@emotion/server': ^11.11.0 + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 + next: ^13.0.0 || ^14.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/cache': + optional: true + '@emotion/server': + optional: true + '@types/react': + optional: true + + '@mui/material@5.15.20': + resolution: {integrity: sha512-tVq3l4qoXx/NxUgIx/x3lZiPn/5xDbdTE8VrLczNpfblLYZzlrbxA7kb9mI8NoBF6+w9WE9IrxWnKK5KlPI2bg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/private-theming@5.15.20': + resolution: {integrity: sha512-BK8F94AIqSrnaPYXf2KAOjGZJgWfvqAVQ2gVR3EryvQFtuBnG6RwodxrCvd3B48VuMy6Wsk897+lQMUxJyk+6g==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/styled-engine@5.15.14': + resolution: {integrity: sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + + '@mui/system@5.15.20': + resolution: {integrity: sha512-LoMq4IlAAhxzL2VNUDBTQxAb4chnBe8JvRINVNDiMtHE2PiPOoHlhOPutSxEbaL5mkECPVWSv6p8JEV+uykwIA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/types@7.2.14': + resolution: {integrity: sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/utils@5.15.20': + resolution: {integrity: sha512-mAbYx0sovrnpAu1zHc3MDIhPqL8RPVC5W5xcO1b7PiSCJPtckIZmBkp8hefamAvUiAV8gpfMOM6Zb+eSisbI2A==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@next/env@14.2.4': + resolution: {integrity: sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg==} + + '@next/eslint-plugin-next@14.2.4': + resolution: {integrity: sha512-svSFxW9f3xDaZA3idQmlFw7SusOuWTpDTAeBlO3AEPDltrraV+lqs7mAc6A27YdnpQVVIA3sODqUAAHdWhVWsA==} + + '@next/swc-darwin-arm64@14.2.4': + resolution: {integrity: sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@14.2.4': + resolution: {integrity: sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@14.2.4': + resolution: {integrity: sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@14.2.4': + resolution: {integrity: sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@14.2.4': + resolution: {integrity: sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@14.2.4': + resolution: {integrity: sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@14.2.4': + resolution: {integrity: sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-ia32-msvc@14.2.4': + resolution: {integrity: sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@next/swc-win32-x64-msvc@14.2.4': + resolution: {integrity: sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + + '@rushstack/eslint-patch@1.10.3': + resolution: {integrity: sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.5': + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@types/js-cookie@2.2.7': + resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@20.14.2': + resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + + '@types/prop-types@15.7.12': + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} + + '@types/react-dom@18.3.0': + resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + + '@types/react-transition-group@4.4.10': + resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==} + + '@types/react@18.3.3': + resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} + + '@types/tar@6.1.13': + resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + + '@typescript-eslint/eslint-plugin@7.13.0': + resolution: {integrity: sha512-FX1X6AF0w8MdVFLSdqwqN/me2hyhuQg4ykN6ZpVhh1ij/80pTvDKclX1sZB9iqex8SjQfVhwMKs3JtnnMLzG9w==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.13.0': + resolution: {integrity: sha512-EjMfl69KOS9awXXe83iRN7oIEXy9yYdqWfqdrFAYAAr6syP8eLEFI7ZE4939antx2mNgPRW/o1ybm2SFYkbTVA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.2.0': + resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.13.0': + resolution: {integrity: sha512-ZrMCe1R6a01T94ilV13egvcnvVJ1pxShkE0+NDjDzH4nvG1wXpwsVI5bZCvE7AEDH1mXEx5tJSVR68bLgG7Dng==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/scope-manager@7.2.0': + resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/type-utils@7.13.0': + resolution: {integrity: sha512-xMEtMzxq9eRkZy48XuxlBFzpVMDurUAfDu5Rz16GouAtXm0TaAoTFzqWUFPPuQYXI/CDaH/Bgx/fk/84t/Bc9A==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.13.0': + resolution: {integrity: sha512-QWuwm9wcGMAuTsxP+qz6LBBd3Uq8I5Nv8xb0mk54jmNoCyDspnMvVsOxI6IsMmway5d1S9Su2+sCKv1st2l6eA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/types@7.2.0': + resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@typescript-eslint/typescript-estree@7.13.0': + resolution: {integrity: sha512-cAvBvUoobaoIcoqox1YatXOnSl3gx92rCZoMRPzMNisDiM12siGilSM4+dJAekuuHTibI2hVC2fYK79iSFvWjw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@7.2.0': + resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.13.0': + resolution: {integrity: sha512-jceD8RgdKORVnB4Y6BqasfIkFhl4pajB1wVxrF4akxD2QPM8GNYjgGwEzYS+437ewlqqrg7Dw+6dhdpjMpeBFQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.13.0': + resolution: {integrity: sha512-nxn+dozQx+MK61nn/JP+M4eCkHDSxSLDpgE3WcQo0+fkjEolnaB5jswvIKC4K56By8MMgIho7f1PVxERHEo8rw==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/visitor-keys@7.2.0': + resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} + engines: {node: ^16.0.0 || >=18.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@xobotyi/scrollbar-width@1.9.5': + resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==} + + '@yr/monotone-cubic-spline@1.0.3': + resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.12.0: + resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.16.0: + resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + apexcharts@3.49.1: + resolution: {integrity: sha512-MqGtlq/KQuO8j0BBsUJYlRG8VBctKwYdwuBtajHgHTmSgUU3Oai+8oYN/rKCXwXzrUlYA+GiMgotAIbXY2BCGw==} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + array.prototype.toreversed@1.1.2: + resolution: {integrity: sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + autoprefixer@10.4.19: + resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.7.0: + resolution: {integrity: sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==} + engines: {node: '>=4'} + + axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + + axobject-query@3.2.1: + resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} + + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@2.0.0: + resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.23.1: + resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001636: + resolution: {integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-functions-list@3.2.2: + resolution: {integrity: sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==} + engines: {node: '>=12 || >=16'} + + css-in-js-utils@3.1.0: + resolution: {integrity: sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A==} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.4.803: + resolution: {integrity: sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enhanced-resolve@5.17.0: + resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.0.19: + resolution: {integrity: sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@14.2.4: + resolution: {integrity: sha512-Qr0wMgG9m6m4uYy2jrYJmyuNlYZzPRQq5Kvb9IDlYwn+7yq6W6sfMNFgb+9guM1KYwuIo6TIaiFhZJ6SnQ/Efw==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.1: + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + + eslint-module-utils@2.8.1: + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.8.0: + resolution: {integrity: sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react@7.34.2: + resolution: {integrity: sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-loops@1.1.3: + resolution: {integrity: sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g==} + + fast-shallow-equal@1.0.0: + resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==} + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastest-stable-stringify@2.0.2: + resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-entry-cache@9.0.0: + resolution: {integrity: sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==} + engines: {node: '>=18'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat-cache@5.0.0: + resolution: {integrity: sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==} + engines: {node: '>=18'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.2.1: + resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} + engines: {node: '>=14'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globjoin@0.1.4: + resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + hyphenate-style-name@1.0.5: + resolution: {integrity: sha512-fedL7PRwmeVkgyhu9hLeTBaI6wcGk7JGJswdaRsa5aUbkXI1kr1xZwTPBtaYPpwf56878iDek6VbVnuWMebJmw==} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + inline-style-prefixer@7.0.0: + resolution: {integrity: sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.2: + resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} + + jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + js-cookie@2.2.1: + resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + known-css-properties@0.31.0: + resolution: {integrity: sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + mathml-tag-names@2.1.3: + resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + meow@13.2.0: + resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} + engines: {node: '>=18'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nano-css@5.6.1: + resolution: {integrity: sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==} + peerDependencies: + react: '*' + react-dom: '*' + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next@14.2.4: + resolution: {integrity: sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ==} + engines: {node: '>=18.17.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + sass: + optional: true + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.hasown@1.1.4: + resolution: {integrity: sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + perfect-scrollbar@1.5.5: + resolution: {integrity: sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-import@14.1.0: + resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==} + engines: {node: '>=10.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.0.0: + resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-nested@6.0.1: + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-resolve-nested-selector@0.1.1: + resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} + + postcss-safe-parser@7.0.0: + resolution: {integrity: sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==} + engines: {node: '>=18.0'} + peerDependencies: + postcss: ^8.4.31 + + postcss-selector-parser@6.1.0: + resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==} + engines: {node: '>=4'} + + postcss-styled-syntax@0.6.4: + resolution: {integrity: sha512-uWiLn+9rKgIghUYmTHvXMR6MnyPULMe9Gv3bV537Fg4FH6CA6cn21WMjKss2Qb98LUhT847tKfnRGG3FhSOgUQ==} + engines: {node: '>=14.17'} + peerDependencies: + postcss: ^8.4.21 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.3.2: + resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} + engines: {node: '>=14'} + hasBin: true + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + react-apexcharts@1.4.1: + resolution: {integrity: sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==} + peerDependencies: + apexcharts: ^3.41.0 + react: '>=0.13' + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-perfect-scrollbar@1.5.8: + resolution: {integrity: sha512-bQ46m70gp/HJtiBOF3gRzBISSZn8FFGNxznTdmTG8AAwpxG1bJCyn7shrgjEvGSQ5FJEafVEiosY+ccER11OSA==} + peerDependencies: + react: '>=16.3.3' + react-dom: '>=16.3.3' + + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + + react-universal-interface@0.6.2: + resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==} + peerDependencies: + react: '*' + tslib: '*' + + react-use@17.5.0: + resolution: {integrity: sha512-PbfwSPMwp/hoL847rLnm/qkjg3sTRCvn6YhUZiHaUa3FA6/aNoFX79ul5Xt70O1rK+9GxSVqkY0eTwMdsR/bWg==} + peerDependencies: + react: '*' + react-dom: '*' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@5.0.7: + resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} + engines: {node: '>=14.18'} + hasBin: true + + rtl-css-js@1.16.1: + resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + screenfull@5.2.0: + resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} + engines: {node: '>=0.10.0'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-harmonic-interval@1.0.1: + resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==} + engines: {node: '>=6.9'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map@0.5.6: + resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} + engines: {node: '>=0.10.0'} + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + stack-generator@2.0.10: + resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + stacktrace-gps@3.1.2: + resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==} + + stacktrace-js@2.0.2: + resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.1: + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylelint-use-logical-spec@5.0.1: + resolution: {integrity: sha512-UfLB4LW6iG4r3cXxjxkiHQrFyhWFqt8FpNNngD+TyvgMWSokk5TYwTvBHS3atUvZhOogllTOe/PUrGE+4z84AA==} + engines: {node: '>=8.0.0'} + peerDependencies: + stylelint: '>=11 < 17' + + stylelint@16.6.1: + resolution: {integrity: sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==} + engines: {node: '>=18.12.0'} + hasBin: true + + stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + + stylis@4.3.2: + resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-hyperlinks@3.0.0: + resolution: {integrity: sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==} + engines: {node: '>=14.18'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + svg.draggable.js@2.2.2: + resolution: {integrity: sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==} + engines: {node: '>= 0.8.0'} + + svg.easing.js@2.0.0: + resolution: {integrity: sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==} + engines: {node: '>= 0.8.0'} + + svg.filter.js@2.0.2: + resolution: {integrity: sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==} + engines: {node: '>= 0.8.0'} + + svg.js@2.7.1: + resolution: {integrity: sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==} + + svg.pathmorphing.js@0.1.3: + resolution: {integrity: sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==} + engines: {node: '>= 0.8.0'} + + svg.resize.js@1.4.3: + resolution: {integrity: sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==} + engines: {node: '>= 0.8.0'} + + svg.select.js@2.1.2: + resolution: {integrity: sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==} + engines: {node: '>= 0.8.0'} + + svg.select.js@3.0.1: + resolution: {integrity: sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==} + engines: {node: '>= 0.8.0'} + + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + + table@6.8.2: + resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} + engines: {node: '>=10.0.0'} + + tailwindcss-logical@3.0.1: + resolution: {integrity: sha512-mv585RJfzS/Cu9Rpl2M5H+JSOdU3qjLHzKMtg63oD5lXfehRJpldbEqll20Obvlexq0Cmyg86l7cmb/I5hEutg==} + + tailwindcss@3.3.1: + resolution: {integrity: sha512-Vkiouc41d4CEq0ujXl6oiGFQ7bA3WEhUZdTgXAhtKxSy49OmKs8rEfQmupsfF0IGW8fv2iQkp1EVUuapCFrZ9g==} + engines: {node: '>=12.13.0'} + hasBin: true + peerDependencies: + postcss: ^8.0.9 + + tailwindcss@3.4.4: + resolution: {integrity: sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==} + engines: {node: '>=14.0.0'} + hasBin: true + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + throttle-debounce@3.0.1: + resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} + engines: {node: '>=10'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-easing@0.2.0: + resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsx@4.15.5: + resolution: {integrity: sha512-iKi8jQ2VBmZ2kU/FkGkL2OSHBHsazsUzsdC/W/RwhKIEsIoZ1alCclZHP5jGfNHEaEWUJFM1GquzCf+4db3b0w==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + update-browserslist-db@1.0.16: + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-builtin-type@1.1.3: + resolution: {integrity: sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + engines: {node: '>= 14'} + hasBin: true + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@antfu/install-pkg@0.1.1': + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + + '@antfu/utils@0.7.8': {} + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/generator@7.24.7': + dependencies: + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-function-name@7.24.7': + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/helper-hoist-variables@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-string-parser@7.24.7': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/runtime@7.24.7': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/traverse@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.24.7': + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@csstools/css-parser-algorithms@2.6.3(@csstools/css-tokenizer@2.3.1)': + dependencies: + '@csstools/css-tokenizer': 2.3.1 + + '@csstools/css-tokenizer@2.3.1': {} + + '@csstools/media-query-list-parser@2.1.11(@csstools/css-parser-algorithms@2.6.3(@csstools/css-tokenizer@2.3.1))(@csstools/css-tokenizer@2.3.1)': + dependencies: + '@csstools/css-parser-algorithms': 2.6.3(@csstools/css-tokenizer@2.3.1) + '@csstools/css-tokenizer': 2.3.1 + + '@csstools/selector-specificity@3.1.1(postcss-selector-parser@6.1.0)': + dependencies: + postcss-selector-parser: 6.1.0 + + '@dual-bundle/import-meta-resolve@4.1.0': {} + + '@emotion/babel-plugin@11.11.0': + dependencies: + '@babel/helper-module-imports': 7.24.7 + '@babel/runtime': 7.24.7 + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/serialize': 1.1.4 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color + + '@emotion/cache@11.11.0': + dependencies: + '@emotion/memoize': 0.8.1 + '@emotion/sheet': 1.2.2 + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + stylis: 4.2.0 + + '@emotion/hash@0.9.1': {} + + '@emotion/is-prop-valid@1.2.2': + dependencies: + '@emotion/memoize': 0.8.1 + + '@emotion/memoize@0.8.1': {} + + '@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@emotion/babel-plugin': 11.11.0 + '@emotion/cache': 11.11.0 + '@emotion/serialize': 1.1.4 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) + '@emotion/utils': 1.2.1 + '@emotion/weak-memoize': 0.3.1 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + transitivePeerDependencies: + - supports-color + + '@emotion/serialize@1.1.4': + dependencies: + '@emotion/hash': 0.9.1 + '@emotion/memoize': 0.8.1 + '@emotion/unitless': 0.8.1 + '@emotion/utils': 1.2.1 + csstype: 3.1.3 + + '@emotion/sheet@1.2.2': {} + + '@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@emotion/babel-plugin': 11.11.0 + '@emotion/is-prop-valid': 1.2.2 + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/serialize': 1.1.4 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.3.1) + '@emotion/utils': 1.2.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + transitivePeerDependencies: + - supports-color + + '@emotion/unitless@0.8.1': {} + + '@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@emotion/utils@1.2.1': {} + + '@emotion/weak-memoize@0.3.1': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.10.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@floating-ui/core@1.6.2': + dependencies: + '@floating-ui/utils': 0.2.2 + + '@floating-ui/dom@1.6.5': + dependencies: + '@floating-ui/core': 1.6.2 + '@floating-ui/utils': 0.2.2 + + '@floating-ui/react-dom@2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.6.5 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.2': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@iconify/json@2.2.219': + dependencies: + '@iconify/types': 2.0.0 + pathe: 1.1.2 + + '@iconify/tools@4.0.4': + dependencies: + '@iconify/types': 2.0.0 + '@iconify/utils': 2.1.24 + '@types/tar': 6.1.13 + axios: 1.7.2 + cheerio: 1.0.0-rc.12 + extract-zip: 2.0.1 + local-pkg: 0.5.0 + pathe: 1.1.2 + svgo: 3.3.2 + tar: 6.2.1 + transitivePeerDependencies: + - debug + - supports-color + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.24': + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.8 + '@iconify/types': 2.0.0 + debug: 4.3.5 + kolorist: 1.8.0 + local-pkg: 0.5.0 + mlly: 1.7.1 + transitivePeerDependencies: + - supports-color + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@mui/base@5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@floating-ui/react-dom': 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.14(@types/react@18.3.3) + '@mui/utils': 5.15.20(@types/react@18.3.3)(react@18.3.1) + '@popperjs/core': 2.11.8 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + + '@mui/core-downloads-tracker@5.15.20': {} + + '@mui/lab@5.0.0-alpha.170(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/material': 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/system': 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/types': 7.2.14(@types/react@18.3.3) + '@mui/utils': 5.15.20(@types/react@18.3.3)(react@18.3.1) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + + '@mui/material-nextjs@5.15.11(@emotion/cache@11.11.0)(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/material': 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@emotion/cache': 11.11.0 + '@types/react': 18.3.3 + + '@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/base': 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@mui/core-downloads-tracker': 5.15.20 + '@mui/system': 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@mui/types': 7.2.14(@types/react@18.3.3) + '@mui/utils': 5.15.20(@types/react@18.3.3)(react@18.3.1) + '@types/react-transition-group': 4.4.10 + clsx: 2.1.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + + '@mui/private-theming@5.15.20(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/utils': 5.15.20(@types/react@18.3.3)(react@18.3.1) + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@mui/styled-engine@5.15.14(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@emotion/cache': 11.11.0 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + + '@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@mui/private-theming': 5.15.20(@types/react@18.3.3)(react@18.3.1) + '@mui/styled-engine': 5.15.14(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(react@18.3.1) + '@mui/types': 7.2.14(@types/react@18.3.3) + '@mui/utils': 5.15.20(@types/react@18.3.3)(react@18.3.1) + clsx: 2.1.1 + csstype: 3.1.3 + prop-types: 15.8.1 + react: 18.3.1 + optionalDependencies: + '@emotion/react': 11.11.4(@types/react@18.3.3)(react@18.3.1) + '@emotion/styled': 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1) + '@types/react': 18.3.3 + + '@mui/types@7.2.14(@types/react@18.3.3)': + optionalDependencies: + '@types/react': 18.3.3 + + '@mui/utils@5.15.20(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.24.7 + '@types/prop-types': 15.7.12 + prop-types: 15.8.1 + react: 18.3.1 + react-is: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@next/env@14.2.4': {} + + '@next/eslint-plugin-next@14.2.4': + dependencies: + glob: 10.3.10 + + '@next/swc-darwin-arm64@14.2.4': + optional: true + + '@next/swc-darwin-x64@14.2.4': + optional: true + + '@next/swc-linux-arm64-gnu@14.2.4': + optional: true + + '@next/swc-linux-arm64-musl@14.2.4': + optional: true + + '@next/swc-linux-x64-gnu@14.2.4': + optional: true + + '@next/swc-linux-x64-musl@14.2.4': + optional: true + + '@next/swc-win32-arm64-msvc@14.2.4': + optional: true + + '@next/swc-win32-ia32-msvc@14.2.4': + optional: true + + '@next/swc-win32-x64-msvc@14.2.4': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@popperjs/core@2.11.8': {} + + '@rushstack/eslint-patch@1.10.3': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.5': + dependencies: + '@swc/counter': 0.1.3 + tslib: 2.6.3 + + '@trysound/sax@0.2.0': {} + + '@types/js-cookie@2.2.7': {} + + '@types/json5@0.0.29': {} + + '@types/node@20.14.2': + dependencies: + undici-types: 5.26.5 + + '@types/parse-json@4.0.2': {} + + '@types/prop-types@15.7.12': {} + + '@types/react-dom@18.3.0': + dependencies: + '@types/react': 18.3.3 + + '@types/react-transition-group@4.4.10': + dependencies: + '@types/react': 18.3.3 + + '@types/react@18.3.3': + dependencies: + '@types/prop-types': 15.7.12 + csstype: 3.1.3 + + '@types/tar@6.1.13': + dependencies: + '@types/node': 20.14.2 + minipass: 4.2.8 + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 20.14.2 + optional: true + + '@typescript-eslint/eslint-plugin@7.13.0(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.10.1 + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/type-utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.13.0 + debug: 4.3.5 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.2.0 + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.5 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.13.0': + dependencies: + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/visitor-keys': 7.13.0 + + '@typescript-eslint/scope-manager@7.2.0': + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + + '@typescript-eslint/type-utils@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + debug: 4.3.5 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.13.0': {} + + '@typescript-eslint/types@7.2.0': {} + + '@typescript-eslint/typescript-estree@7.13.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/visitor-keys': 7.13.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/visitor-keys': 7.2.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.13.0(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.13.0 + '@typescript-eslint/types': 7.13.0 + '@typescript-eslint/typescript-estree': 7.13.0(typescript@5.4.5) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.13.0': + dependencies: + '@typescript-eslint/types': 7.13.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@7.2.0': + dependencies: + '@typescript-eslint/types': 7.2.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@xobotyi/scrollbar-width@1.9.5': {} + + '@yr/monotone-cubic-spline@1.0.3': {} + + acorn-jsx@5.3.2(acorn@8.12.0): + dependencies: + acorn: 8.12.0 + + acorn@8.12.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.16.0: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + apexcharts@3.49.1: + dependencies: + '@yr/monotone-cubic-spline': 1.0.3 + svg.draggable.js: 2.2.2 + svg.easing.js: 2.0.0 + svg.filter.js: 2.0.2 + svg.pathmorphing.js: 0.1.3 + svg.resize.js: 1.4.3 + svg.select.js: 3.0.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.toreversed@1.1.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + ast-types-flow@0.0.8: {} + + astral-regex@2.0.0: {} + + asynckit@0.4.0: {} + + autoprefixer@10.4.19(postcss@8.4.38): + dependencies: + browserslist: 4.23.1 + caniuse-lite: 1.0.30001636 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.1 + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axe-core@4.7.0: {} + + axios@1.7.2: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axobject-query@3.2.1: + dependencies: + dequal: 2.0.3 + + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.24.7 + cosmiconfig: 7.1.0 + resolve: 1.22.8 + + balanced-match@1.0.2: {} + + balanced-match@2.0.0: {} + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.23.1: + dependencies: + caniuse-lite: 1.0.30001636 + electron-to-chromium: 1.4.803 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.1) + + buffer-crc32@0.2.13: {} + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + caniuse-lite@1.0.30001636: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@2.0.0: {} + + classnames@2.5.1: {} + + client-only@0.0.1: {} + + clsx@2.1.1: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colord@2.9.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@4.1.1: {} + + commander@7.2.0: {} + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + convert-source-map@1.9.0: {} + + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + + cosmiconfig@9.0.0(typescript@5.4.5): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.4.5 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-functions-list@3.2.2: {} + + css-in-js-utils@3.1.0: + dependencies: + hyphenate-style-name: 1.0.5 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.0 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + csstype@3.1.3: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + dequal@2.0.3: {} + + didyoumean@1.2.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dlv@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-helpers@5.2.1: + dependencies: + '@babel/runtime': 7.24.7 + csstype: 3.1.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.4.803: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.17.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-iterator-helpers@1.0.19: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.2 + safe-array-concat: 1.1.2 + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-next@14.2.4(eslint@8.57.0)(typescript@5.4.5): + dependencies: + '@next/eslint-plugin-next': 14.2.4 + '@rushstack/eslint-patch': 1.10.3 + '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) + eslint-plugin-react: 7.34.2(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - supports-color + + eslint-config-prettier@9.1.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0): + dependencies: + debug: 4.3.5 + enhanced-resolve: 5.17.0 + eslint: 8.57.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.5 + is-core-module: 2.13.1 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + dependencies: + debug: 4.3.5 + enhanced-resolve: 5.17.0 + eslint: 8.57.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.5 + is-core-module: 2.13.1 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.5) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.13.0(eslint@8.57.0)(typescript@5.4.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.8.0(eslint@8.57.0): + dependencies: + '@babel/runtime': 7.24.7 + aria-query: 5.3.0 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.7.0 + axobject-query: 3.2.1 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + + eslint-plugin-react-hooks@4.6.2(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-react@7.34.2(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.2 + array.prototype.toreversed: 1.1.2 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.0.19 + eslint: 8.57.0 + estraverse: 5.3.0 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.hasown: 1.1.4 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.5 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.12.0 + acorn-jsx: 5.3.2(acorn@8.12.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + extract-zip@2.0.1: + dependencies: + debug: 4.3.5 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-loops@1.1.3: {} + + fast-shallow-equal@1.0.0: {} + + fastest-levenshtein@1.0.16: {} + + fastest-stable-stringify@2.0.2: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + file-entry-cache@9.0.0: + dependencies: + flat-cache: 5.0.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-root@1.1.0: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 5.0.7 + + flat-cache@5.0.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + follow-redirects@1.15.6: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.2.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fraction.js@4.3.7: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@5.2.0: + dependencies: + pump: 3.0.0 + + get-stream@6.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.3.10: + dependencies: + foreground-child: 3.2.1 + jackspeak: 2.3.6 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + glob@10.4.1: + dependencies: + foreground-child: 3.2.1 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + globals@11.12.0: {} + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + globjoin@0.1.4: {} + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.0.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + html-tags@3.3.1: {} + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + human-signals@2.1.0: {} + + hyphenate-style-name@1.0.5: {} + + ignore@5.3.1: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + ini@1.3.8: {} + + inline-style-prefixer@7.0.0: + dependencies: + css-in-js-utils: 3.1.0 + fast-loops: 1.1.3 + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.13.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-object@5.0.0: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@2.0.1: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakmap@2.0.2: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.2: + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + + jackspeak@2.3.6: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.6: {} + + js-cookie@2.2.1: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@2.5.2: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + known-css-properties@0.31.0: {} + + kolorist@1.8.0: {} + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@2.1.0: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.1 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash.truncate@4.4.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.2.2: {} + + mathml-tag-names@2.1.3: {} + + mdn-data@2.0.14: {} + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + meow@13.2.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@4.2.8: {} + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mkdirp@1.0.4: {} + + mlly@1.7.1: + dependencies: + acorn: 8.12.0 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + + ms@2.1.2: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nano-css@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + css-tree: 1.1.3 + csstype: 3.1.3 + fastest-stable-stringify: 2.0.2 + inline-style-prefixer: 7.0.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + rtl-css-js: 1.16.1 + stacktrace-js: 2.0.2 + stylis: 4.3.2 + + nanoid@3.3.7: {} + + natural-compare@1.4.0: {} + + next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 14.2.4 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001636 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.1(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.4 + '@next/swc-darwin-x64': 14.2.4 + '@next/swc-linux-arm64-gnu': 14.2.4 + '@next/swc-linux-arm64-musl': 14.2.4 + '@next/swc-linux-x64-gnu': 14.2.4 + '@next/swc-linux-x64-musl': 14.2.4 + '@next/swc-win32-arm64-msvc': 14.2.4 + '@next/swc-win32-ia32-msvc': 14.2.4 + '@next/swc-win32-x64-msvc': 14.2.4 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + node-releases@2.0.14: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + object-inspect@1.13.1: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.entries@1.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.hasown@1.1.4: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + + path-type@4.0.0: {} + + pathe@1.1.2: {} + + pend@1.2.0: {} + + perfect-scrollbar@1.5.5: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pify@2.3.0: {} + + pirates@4.0.6: {} + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + possible-typed-array-names@1.0.0: {} + + postcss-import@14.1.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + + postcss-import@15.1.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + + postcss-js@4.0.1(postcss@8.4.38): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.38 + + postcss-load-config@3.1.4(postcss@8.4.38): + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.2 + optionalDependencies: + postcss: 8.4.38 + + postcss-load-config@4.0.2(postcss@8.4.38): + dependencies: + lilconfig: 3.1.2 + yaml: 2.4.5 + optionalDependencies: + postcss: 8.4.38 + + postcss-nested@6.0.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + postcss-selector-parser: 6.1.0 + + postcss-nested@6.0.1(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + postcss-selector-parser: 6.1.0 + + postcss-resolve-nested-selector@0.1.1: {} + + postcss-safe-parser@7.0.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + + postcss-selector-parser@6.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-styled-syntax@0.6.4(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + typescript: 5.4.5 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prelude-ls@1.2.1: {} + + prettier@3.3.2: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + proxy-from-env@1.1.0: {} + + pump@3.0.0: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + react-apexcharts@1.4.1(apexcharts@3.49.1)(react@18.3.1): + dependencies: + apexcharts: 3.49.1 + prop-types: 15.8.1 + react: 18.3.1 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-is@16.13.1: {} + + react-is@18.3.1: {} + + react-perfect-scrollbar@1.5.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + perfect-scrollbar: 1.5.5 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.24.7 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-universal-interface@0.6.2(react@18.3.1)(tslib@2.6.3): + dependencies: + react: 18.3.1 + tslib: 2.6.3 + + react-use@17.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@types/js-cookie': 2.2.7 + '@xobotyi/scrollbar-width': 1.9.5 + copy-to-clipboard: 3.3.3 + fast-deep-equal: 3.1.3 + fast-shallow-equal: 1.0.0 + js-cookie: 2.2.1 + nano-css: 5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-universal-interface: 0.6.2(react@18.3.1)(tslib@2.6.3) + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + set-harmonic-interval: 1.0.1 + throttle-debounce: 3.0.1 + ts-easing: 0.2.0 + tslib: 2.6.3 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + reflect.getprototypeof@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.3 + + regenerator-runtime@0.14.1: {} + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + require-from-string@2.0.2: {} + + resize-observer-polyfill@1.5.1: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rimraf@5.0.7: + dependencies: + glob: 10.4.1 + + rtl-css-js@1.16.1: + dependencies: + '@babel/runtime': 7.24.7 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + screenfull@5.2.0: {} + + semver@6.3.1: {} + + semver@7.6.2: {} + + server-only@0.0.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-harmonic-interval@1.0.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + source-map-js@1.2.0: {} + + source-map@0.5.6: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + stack-generator@2.0.10: + dependencies: + stackframe: 1.3.4 + + stackframe@1.3.4: {} + + stacktrace-gps@3.1.2: + dependencies: + source-map: 0.5.6 + stackframe: 1.3.4 + + stacktrace-js@2.0.2: + dependencies: + error-stack-parser: 2.1.4 + stack-generator: 2.0.10 + stacktrace-gps: 3.1.2 + + streamsearch@1.1.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string.prototype.matchall@4.0.11: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 + side-channel: 1.0.6 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom@3.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.1(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + + stylelint-use-logical-spec@5.0.1(stylelint@16.6.1(typescript@5.4.5)): + dependencies: + stylelint: 16.6.1(typescript@5.4.5) + + stylelint@16.6.1(typescript@5.4.5): + dependencies: + '@csstools/css-parser-algorithms': 2.6.3(@csstools/css-tokenizer@2.3.1) + '@csstools/css-tokenizer': 2.3.1 + '@csstools/media-query-list-parser': 2.1.11(@csstools/css-parser-algorithms@2.6.3(@csstools/css-tokenizer@2.3.1))(@csstools/css-tokenizer@2.3.1) + '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.0) + '@dual-bundle/import-meta-resolve': 4.1.0 + balanced-match: 2.0.0 + colord: 2.9.3 + cosmiconfig: 9.0.0(typescript@5.4.5) + css-functions-list: 3.2.2 + css-tree: 2.3.1 + debug: 4.3.5 + fast-glob: 3.3.2 + fastest-levenshtein: 1.0.16 + file-entry-cache: 9.0.0 + global-modules: 2.0.0 + globby: 11.1.0 + globjoin: 0.1.4 + html-tags: 3.3.1 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-plain-object: 5.0.0 + known-css-properties: 0.31.0 + mathml-tag-names: 2.1.3 + meow: 13.2.0 + micromatch: 4.0.7 + normalize-path: 3.0.0 + picocolors: 1.0.1 + postcss: 8.4.38 + postcss-resolve-nested-selector: 0.1.1 + postcss-safe-parser: 7.0.0(postcss@8.4.38) + postcss-selector-parser: 6.1.0 + postcss-value-parser: 4.2.0 + resolve-from: 5.0.0 + string-width: 4.2.3 + strip-ansi: 7.1.0 + supports-hyperlinks: 3.0.0 + svg-tags: 1.0.0 + table: 6.8.2 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + - typescript + + stylis@4.2.0: {} + + stylis@4.3.2: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@3.0.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-tags@1.0.0: {} + + svg.draggable.js@2.2.2: + dependencies: + svg.js: 2.7.1 + + svg.easing.js@2.0.0: + dependencies: + svg.js: 2.7.1 + + svg.filter.js@2.0.2: + dependencies: + svg.js: 2.7.1 + + svg.js@2.7.1: {} + + svg.pathmorphing.js@0.1.3: + dependencies: + svg.js: 2.7.1 + + svg.resize.js@1.4.3: + dependencies: + svg.js: 2.7.1 + svg.select.js: 2.1.2 + + svg.select.js@2.1.2: + dependencies: + svg.js: 2.7.1 + + svg.select.js@3.0.1: + dependencies: + svg.js: 2.7.1 + + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.0.1 + + table@6.8.2: + dependencies: + ajv: 8.16.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tailwindcss-logical@3.0.1(postcss@8.4.38): + dependencies: + tailwindcss: 3.3.1(postcss@8.4.38) + transitivePeerDependencies: + - postcss + - ts-node + + tailwindcss@3.3.1(postcss@8.4.38): + dependencies: + arg: 5.0.2 + chokidar: 3.6.0 + color-name: 1.1.4 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.7 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.1 + postcss: 8.4.38 + postcss-import: 14.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 3.1.4(postcss@8.4.38) + postcss-nested: 6.0.0(postcss@8.4.38) + postcss-selector-parser: 6.1.0 + postcss-value-parser: 4.2.0 + quick-lru: 5.1.1 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + tailwindcss@3.4.4: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.7 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.1 + postcss: 8.4.38 + postcss-import: 15.1.0(postcss@8.4.38) + postcss-js: 4.0.1(postcss@8.4.38) + postcss-load-config: 4.0.2(postcss@8.4.38) + postcss-nested: 6.0.1(postcss@8.4.38) + postcss-selector-parser: 6.1.0 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + tapable@2.2.1: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + throttle-debounce@3.0.1: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toggle-selection@1.0.6: {} + + ts-api-utils@1.3.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + ts-easing@0.2.0: {} + + ts-interface-checker@0.1.13: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.6.3: {} + + tsx@4.15.5: + dependencies: + esbuild: 0.21.5 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typescript@5.4.5: {} + + ufo@1.5.3: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici-types@5.26.5: {} + + update-browserslist-db@1.0.16(browserslist@4.23.1): + dependencies: + browserslist: 4.23.1 + escalade: 3.1.2 + picocolors: 1.0.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-builtin-type@1.1.3: + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + yallist@4.0.0: {} + + yaml@1.10.2: {} + + yaml@2.4.5: {} + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yocto-queue@0.1.0: {} diff --git a/front-urban/postcss.config.mjs b/front-urban/postcss.config.mjs new file mode 100644 index 0000000..e64b252 --- /dev/null +++ b/front-urban/postcss.config.mjs @@ -0,0 +1,10 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + 'tailwindcss/nesting': {}, + tailwindcss: {}, + autoprefixer: {} + } +} + +export default config diff --git a/front-urban/public/next.svg b/front-urban/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/front-urban/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front-urban/public/vercel.svg b/front-urban/public/vercel.svg new file mode 100644 index 0000000..d2f8422 --- /dev/null +++ b/front-urban/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/front-urban/src/@core/components/mui/Avatar.tsx b/front-urban/src/@core/components/mui/Avatar.tsx new file mode 100644 index 0000000..92512c5 --- /dev/null +++ b/front-urban/src/@core/components/mui/Avatar.tsx @@ -0,0 +1,51 @@ +'use client' + +// React Imports +import { forwardRef } from 'react' + +// MUI Imports +import MuiAvatar from '@mui/material/Avatar' +import { lighten, styled } from '@mui/material/styles' +import type { AvatarProps } from '@mui/material/Avatar' + +// Type Imports +import type { ThemeColor } from '@core/types' + +export type CustomAvatarProps = AvatarProps & { + color?: ThemeColor + skin?: 'filled' | 'light' | 'light-static' + size?: number +} + +const Avatar = styled(MuiAvatar)(({ skin, color, size, theme }) => { + return { + ...(color && + skin === 'light' && { + backgroundColor: `var(--mui-palette-${color}-lightOpacity)`, + color: `var(--mui-palette-${color}-main)` + }), + ...(color && + skin === 'light-static' && { + backgroundColor: lighten(theme.palette[color as ThemeColor].main, 0.84), + color: `var(--mui-palette-${color}-main)` + }), + ...(color && + skin === 'filled' && { + backgroundColor: `var(--mui-palette-${color}-main)`, + color: `var(--mui-palette-${color}-contrastText)` + }), + ...(size && { + height: size, + width: size + }) + } +}) + +const CustomAvatar = forwardRef((props: CustomAvatarProps, ref) => { + // Props + const { color, skin = 'filled', ...rest } = props + + return +}) + +export default CustomAvatar diff --git a/front-urban/src/@core/components/mui/IconButton.tsx b/front-urban/src/@core/components/mui/IconButton.tsx new file mode 100644 index 0000000..9a609f2 --- /dev/null +++ b/front-urban/src/@core/components/mui/IconButton.tsx @@ -0,0 +1,75 @@ +'use client' + +import MuiButton from '@mui/material/Button' +import { styled } from '@mui/material/styles' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +const CustomIconButton = styled(MuiButton)(({ color, size, theme, variant }) => { + return { + minInlineSize: 0, + ...(size === 'small' + ? { + fontSize: '20px', + padding: theme.spacing(variant === 'outlined' ? 1 : 1.25), + '& i, & svg': { + fontSize: 'inherit' + } + } + : { + ...(size === 'large' + ? { + fontSize: '24px', + padding: theme.spacing(variant === 'outlined' ? 2 : 2.25), + '& i, & svg': { + fontSize: 'inherit' + } + } + : { + fontSize: '22px', + padding: theme.spacing(variant === 'outlined' ? 1.5 : 1.75), + '& i, & svg': { + fontSize: 'inherit' + } + }) + }), + ...(!color && { + color: 'var(--mui-palette-action-active)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { + backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)' + } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-action-active)' + }, + ...(variant === 'outlined' && { + border: 'none !important', + ...(size === 'small' + ? { + padding: theme.spacing(1.5) + } + : { + ...(size === 'large' + ? { + padding: theme.spacing(2.25) + } + : { + padding: theme.spacing(1.75) + }) + }) + }), + ...(variant === 'contained' && { + boxShadow: 'none !important', + backgroundColor: 'transparent' + }) + }) + } +}) as typeof MuiButton + +export default CustomIconButton diff --git a/front-urban/src/@core/components/option-menu/index.tsx b/front-urban/src/@core/components/option-menu/index.tsx new file mode 100644 index 0000000..d788090 --- /dev/null +++ b/front-urban/src/@core/components/option-menu/index.tsx @@ -0,0 +1,135 @@ +'use client' + +// React Imports +import { useRef, useState } from 'react' +import type { ReactElement, ReactNode, SyntheticEvent } from 'react' + +// Next Imports +import Link from 'next/link' + +// MUI Imports +import Tooltip from '@mui/material/Tooltip' +import Box from '@mui/material/Box' +import Popper from '@mui/material/Popper' +import MenuItem from '@mui/material/MenuItem' +import MenuList from '@mui/material/MenuList' +import ClickAwayListener from '@mui/material/ClickAwayListener' +import Fade from '@mui/material/Fade' +import Paper from '@mui/material/Paper' +import IconButton from '@mui/material/IconButton' +import Divider from '@mui/material/Divider' + +// Third-party Imports +import classnames from 'classnames' + +// Type Imports +import type { OptionsMenuType, OptionType, OptionMenuItemType } from './types' + +const IconButtonWrapper = (props: Pick & { children: ReactElement }) => { + // Props + const { tooltipProps, children } = props + + return tooltipProps?.title ? {children} : children +} + +const MenuItemWrapper = ({ children, option }: { children: ReactNode; option: OptionMenuItemType }) => { + if (option.href) { + return ( + + {children} + + ) + } else { + return <>{children} + } +} + +const OptionMenu = (props: OptionsMenuType) => { + // Props + const { tooltipProps, icon, iconClassName, options, leftAlignMenu, iconButtonProps } = props + + // States + const [open, setOpen] = useState(false) + + // Refs + const anchorRef = useRef(null) + + const handleToggle = () => { + setOpen(prevOpen => !prevOpen) + } + + const handleClose = (event: Event | SyntheticEvent) => { + if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) { + return + } + + setOpen(false) + } + + return ( + <> + + + {typeof icon === 'string' ? ( + + ) : (icon as ReactNode) ? ( + icon + ) : ( + + )} + + + + {({ TransitionProps }) => ( + + + + + {options.map((option: OptionType, index: number) => { + if (typeof option === 'string') { + return ( + + {option} + + ) + } else if ('divider' in option) { + return option.divider && + } else { + return ( + { + handleClose(e) + option.menuItemProps && option.menuItemProps.onClick + ? option.menuItemProps.onClick(e) + : null + }} + > + + {(typeof option.icon === 'string' ? : option.icon) || null} + {option.text} + + + ) + } + })} + + + + + )} + + + ) +} + +export default OptionMenu diff --git a/front-urban/src/@core/components/option-menu/types.ts b/front-urban/src/@core/components/option-menu/types.ts new file mode 100644 index 0000000..795777f --- /dev/null +++ b/front-urban/src/@core/components/option-menu/types.ts @@ -0,0 +1,42 @@ +// React Imports +import type { ReactNode } from 'react' + +// Next Imports +import type { LinkProps } from 'next/link' + +// MUI Imports +import type { IconButtonProps } from '@mui/material/IconButton' +import type { MenuItemProps } from '@mui/material/MenuItem' +import type { DividerProps } from '@mui/material/Divider' +import type { BoxProps } from '@mui/material/Box' +import type { TooltipProps } from '@mui/material/Tooltip' + +export type OptionDividerType = { + divider: boolean + dividerProps?: DividerProps + href?: never + icon?: never + text?: never + linkProps?: never + menuItemProps?: never +} +export type OptionMenuItemType = { + text: ReactNode + icon?: ReactNode + linkProps?: BoxProps + href?: LinkProps['href'] + menuItemProps?: MenuItemProps + divider?: never + dividerProps?: never +} + +export type OptionType = string | OptionDividerType | OptionMenuItemType + +export type OptionsMenuType = { + tooltipProps?: Omit + icon?: ReactNode + iconClassName?: string + options: OptionType[] + leftAlignMenu?: boolean + iconButtonProps?: IconButtonProps +} diff --git a/front-urban/src/@core/contexts/settingsContext.tsx b/front-urban/src/@core/contexts/settingsContext.tsx new file mode 100644 index 0000000..b8a3df9 --- /dev/null +++ b/front-urban/src/@core/contexts/settingsContext.tsx @@ -0,0 +1,122 @@ +'use client' + +// React Imports +import type { ReactNode } from 'react' +import { createContext, useMemo, useState } from 'react' + +// Type Imports +import type { Mode } from '@core/types' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +// Hook Imports +import { useObjectCookie } from '@core/hooks/useObjectCookie' + +// Settings type +export type Settings = { + mode?: Mode +} + +// UpdateSettingsOptions type +type UpdateSettingsOptions = { + updateCookie?: boolean +} + +// SettingsContextProps type +type SettingsContextProps = { + settings: Settings + updateSettings: (settings: Partial, options?: UpdateSettingsOptions) => void + isSettingsChanged: boolean + resetSettings: () => void + updatePageSettings: (settings: Partial) => () => void +} + +type Props = { + children: ReactNode + settingsCookie: Settings | null + mode?: Mode +} + +// Initial Settings Context +export const SettingsContext = createContext(null) + +// Settings Provider +export const SettingsProvider = (props: Props) => { + // Initial Settings + const initialSettings: Settings = { + mode: themeConfig.mode + } + + const updatedInitialSettings = { + ...initialSettings, + mode: props.mode || themeConfig.mode + } + + // Cookies + const [settingsCookie, updateSettingsCookie] = useObjectCookie( + themeConfig.settingsCookieName, + JSON.stringify(props.settingsCookie) !== '{}' ? props.settingsCookie : updatedInitialSettings + ) + + // State + const [_settingsState, _updateSettingsState] = useState( + JSON.stringify(settingsCookie) !== '{}' ? settingsCookie : updatedInitialSettings + ) + + const updateSettings = (settings: Partial, options?: UpdateSettingsOptions) => { + const { updateCookie = true } = options || {} + + _updateSettingsState(prev => { + const newSettings = { ...prev, ...settings } + + // Update cookie if needed + if (updateCookie) updateSettingsCookie(newSettings) + + return newSettings + }) + } + + /** + * Updates the settings for page with the provided settings object. + * Updated settings won't be saved to cookie hence will be reverted once navigating away from the page. + * + * @param settings - The partial settings object containing the properties to update. + * @returns A function to reset the page settings. + * + * @example + * useEffect(() => { + * return updatePageSettings({ theme: 'dark' }); + * }, []); + */ + const updatePageSettings = (settings: Partial): (() => void) => { + updateSettings(settings, { updateCookie: false }) + + // Returns a function to reset the page settings + return () => updateSettings(settingsCookie, { updateCookie: false }) + } + + const resetSettings = () => { + updateSettings(initialSettings) + } + + const isSettingsChanged = useMemo( + () => JSON.stringify(initialSettings) !== JSON.stringify(_settingsState), + // eslint-disable-next-line react-hooks/exhaustive-deps + [_settingsState] + ) + + return ( + + {props.children} + + ) +} diff --git a/front-urban/src/@core/hooks/downloadInvoicePdf.ts b/front-urban/src/@core/hooks/downloadInvoicePdf.ts new file mode 100644 index 0000000..c47f5f1 --- /dev/null +++ b/front-urban/src/@core/hooks/downloadInvoicePdf.ts @@ -0,0 +1,18 @@ +import apiClient from '@/lib/apiClient'; + +export const downloadInvoicePdf = async (invoiceId: string) => { + const response = await apiClient.get( + `/invoices/download/${invoiceId}`, + { responseType: 'blob' } + ); + + const blob = new Blob([response.data], { type: 'application/pdf' }); + const url = URL.createObjectURL(blob); + + const a = document.createElement('a'); + a.href = url; + a.download = `factura-${invoiceId}.pdf`; + a.click(); + + URL.revokeObjectURL(url); +}; diff --git a/front-urban/src/@core/hooks/useAccessLogs.ts b/front-urban/src/@core/hooks/useAccessLogs.ts new file mode 100644 index 0000000..90a80a3 --- /dev/null +++ b/front-urban/src/@core/hooks/useAccessLogs.ts @@ -0,0 +1,55 @@ +// src/@core/hooks/useAccessLogs.ts +'use client'; + +import { useCallback, useEffect, useState } from 'react'; +import apiClient from '@/lib/apiClient'; +import { useUserAuth } from '@/app/context/UserAuth'; + +export type AccessLog = { + id: string; + userId: string; + direction: 'INGRESS' | 'EGRESS'; + timestamp: string; +}; + +export type ResponseAccessLogs = { + userId: string; + name: string; + accessLogs: AccessLog[]; +}; + +export function useAccessLogs(userId?: string, date?: string, enabled: boolean = true) { + const { token } = useUserAuth(); + const [data, setData] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const fetchData = useCallback( + async (signal?: AbortSignal) => { + if (!enabled || !userId || !date) return; + setLoading(true); + setError(null); + try { + const res = await apiClient.get('/attendance', { + params: { userId, date }, + signal, + }); + setData(res.data); + } catch (e: any) { + if (e?.name === 'CanceledError') return; + setError(e?.response?.data?.message ?? 'No se pudieron cargar los registros de acceso.'); + } finally { + setLoading(false); + } + }, + [enabled, userId, date, token] + ); + + useEffect(() => { + const ctrl = new AbortController(); + fetchData(ctrl.signal); + return () => ctrl.abort(); + }, [fetchData]); + + return { data, loading, error, refresh: fetchData }; +} diff --git a/front-urban/src/@core/hooks/useAttendeesSnapshot.ts b/front-urban/src/@core/hooks/useAttendeesSnapshot.ts new file mode 100644 index 0000000..7814bff --- /dev/null +++ b/front-urban/src/@core/hooks/useAttendeesSnapshot.ts @@ -0,0 +1,49 @@ +// src/@core/hooks/useAttendeesSnapshot.ts +'use client'; + +import { useCallback, useEffect, useState } from 'react'; +import apiClient from '@/lib/apiClient'; +import { useUserAuth } from '@/app/context/UserAuth'; + +export type ResponseAttendeesSnapshot = { + dateRange: { start: string; end: string }; + instructors: { id: string; name: string }[]; + assistants: { id: string; name: string }[]; + attendance: { id: string; name: string }[]; +}; + +export function useAttendeesSnapshot(snapshotId?: string, enabled: boolean = true) { + const { token } = useUserAuth(); + const [data, setData] = useState(null); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const fetchData = useCallback( + async (signal?: AbortSignal) => { + if (!enabled || !snapshotId) return; + setLoading(true); + setError(null); + try { + const res = await apiClient.get( + `/sessions/${snapshotId}/attendees`, + { signal } + ); + setData(res.data); + } catch (e: any) { + if (e?.name === 'CanceledError') return; + setError(e?.response?.data?.message ?? 'No se pudieron cargar los asistentes.'); + } finally { + setLoading(false); + } + }, + [enabled, snapshotId, token] + ); + + useEffect(() => { + const ctrl = new AbortController(); + fetchData(ctrl.signal); + return () => ctrl.abort(); + }, [fetchData]); + + return { data, loading, error, refresh: fetchData }; +} diff --git a/front-urban/src/@core/hooks/useClases.ts b/front-urban/src/@core/hooks/useClases.ts new file mode 100644 index 0000000..b441d1f --- /dev/null +++ b/front-urban/src/@core/hooks/useClases.ts @@ -0,0 +1,66 @@ +// useClases.ts +'use client'; + +import { useCallback, useEffect, useRef, useState } from 'react'; +import apiClient from '@/lib/apiClient'; +import { Clase } from '@/views/clases/DetailClaseDialog'; + +type Options = { + /** Lanza el fetch al montar el hook (default: true) */ + auto?: boolean; + /** Filtro de estado: 'all', 'active', 'inactive' */ + status?: 'all' | 'active' | 'inactive'; +}; + +type UseClasesResult = { + data: Clase[]; + loading: boolean; + error: unknown; + /** Vuelve a pedir la lista */ + refresh: () => Promise; + /** Setea manualmente el array (útil para optimist updates) */ + setData: React.Dispatch>; +}; + +export function useClases(opts: Options = {}): UseClasesResult { + const { auto = true, status = 'all' } = opts; + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(auto); + const [error, setError] = useState(null); + + // guardamos una referencia al abortController para cancelar en unmount + const abortRef = useRef(null); + + const refresh = useCallback(async () => { + setLoading(true); + setError(null); + + // cancelar request previa si hubiera + if (abortRef.current) abortRef.current.abort(); + const ac = new AbortController(); + abortRef.current = ac; + + try { + const params = status && status !== 'all' ? { status } : undefined; + const res = await apiClient.get('/sessions', { params, signal: ac.signal }); + setData(res.data ?? []); + } catch (e: any) { + if (e?.name === 'CanceledError' || e?.message === 'canceled') return; + setError(e); + console.error('Error al obtener clases:', e); + } finally { + if (!ac.signal.aborted) setLoading(false); + } + }, [status]); + + useEffect(() => { + if (auto) refresh(); + return () => { + // cancelar si el componente se desmonta + abortRef.current?.abort(); + }; + }, [auto, refresh]); + + return { data, loading, error, refresh, setData }; +} diff --git a/front-urban/src/@core/hooks/useDashboard.ts b/front-urban/src/@core/hooks/useDashboard.ts new file mode 100644 index 0000000..d37f58b --- /dev/null +++ b/front-urban/src/@core/hooks/useDashboard.ts @@ -0,0 +1,65 @@ +// useDashboard.ts +'use client' + +import { useCallback, useEffect, useRef, useState } from 'react' +import apiClient from '@/lib/apiClient' +import { useUserAuth } from '@/app/context/UserAuth' + +export type DashboardUser = { + message: string + accessLog: { currentAccess: string; lastAccess: string } + cardDetails: { sessions: number; users: number; assistants: number; revenue: number } + sessions: { id: string; description: string; instructors: string; startDate: string }[] +} + +type Options = { + auto?: boolean +} + +type UseDashboardResult = { + data: DashboardUser | null + loading: boolean + error: unknown + refresh: () => Promise +} + +export function useDashboard(opts: Options = {}): UseDashboardResult { + const { token } = useUserAuth() + const { auto = true } = opts + + const [data, setData] = useState(null) + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + + const abortRef = useRef(null) + + const refresh = useCallback(async () => { + // si no hay token aún, no pidas nada ni cambies loading + if (!token) return + + setLoading(true) + setError(null) + + abortRef.current?.abort() + const ac = new AbortController() + abortRef.current = ac + + try { + const res = await apiClient.get('/dashboard', { signal: ac.signal }) + setData(res.data ?? null) + } catch (e: any) { + if (e?.name === 'CanceledError' || e?.message === 'canceled') return + setError(e) + console.error('Error al obtener dashboard:', e) + } finally { + if (!ac.signal.aborted) setLoading(false) + } + }, [token]) // ← incluye token! + + useEffect(() => { + if (auto && token) refresh() // ← solo cuando haya token + return () => abortRef.current?.abort() + }, [auto, token, refresh]) // ← depende de token también + + return { data, loading, error, refresh } +} diff --git a/front-urban/src/@core/hooks/useImageVariant.ts b/front-urban/src/@core/hooks/useImageVariant.ts new file mode 100644 index 0000000..f98c215 --- /dev/null +++ b/front-urban/src/@core/hooks/useImageVariant.ts @@ -0,0 +1,28 @@ +// React Imports +import { useMemo } from 'react' + +// Third-party imports +import { useColorScheme } from '@mui/material' + +// Type imports +import type { Mode } from '@core/types' + +export const useImageVariant = (mode: Mode, imgLight: string, imgDark: string): string => { + // Hooks + const { mode: muiMode } = useColorScheme() + + return useMemo(() => { + const isServer = typeof window === 'undefined' + + const currentMode = (() => { + if (isServer) return mode + + return muiMode + })() + + const isDarkMode = currentMode === 'dark' + + return isDarkMode ? imgDark : imgLight + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [mode, muiMode]) +} diff --git a/front-urban/src/@core/hooks/useInstructors.ts b/front-urban/src/@core/hooks/useInstructors.ts new file mode 100644 index 0000000..343b6b6 --- /dev/null +++ b/front-urban/src/@core/hooks/useInstructors.ts @@ -0,0 +1,74 @@ +// src/@core/hooks/useInstructors.ts +'use client'; + +import { useCallback, useEffect, useState } from 'react'; +import apiClient from '@/lib/apiClient'; +import { useUserAuth } from '@/app/context/UserAuth'; +import type { Instructor } from '@/app/modules/users/dto/instructor.dto'; + +type UseInstructorsResult = { + data: Instructor[]; + loading: boolean; + error: string | null; + refresh: () => Promise; +}; + +/** + * Hook para obtener la lista de instructores. + * - Lee el token del contexto. + * - Maneja estados data/loading/error. + * - Cancela la request al desmontar. + */ +export function useInstructors(enabled: boolean = true): UseInstructorsResult { + const { token } = useUserAuth(); + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const fetchData = useCallback( + async (signal?: AbortSignal) => { + if (!token) { + setData([]); + setLoading(false); + setError(null); + return; + } + + try { + setLoading(true); + setError(null); + + const res = await apiClient.get('/users/instructor', { signal }); + + setData(res.data ?? []); + } catch (err: any) { + if (err?.name !== 'CanceledError') { + const msg = + err?.response?.data?.message || + err?.message || + 'Error al obtener instructores.'; + setError(msg); + } + } finally { + setLoading(false); + } + }, + [token] + ); + + useEffect(() => { + if (!enabled) return; + const ctrl = new AbortController(); + fetchData(ctrl.signal); + return () => ctrl.abort(); + }, [enabled, fetchData]); + + const refresh = useCallback(async () => { + await fetchData(); + }, [fetchData]); + + return { data, loading, error, refresh }; +} + +export default useInstructors; diff --git a/front-urban/src/@core/hooks/useInvoices.ts b/front-urban/src/@core/hooks/useInvoices.ts new file mode 100644 index 0000000..e561894 --- /dev/null +++ b/front-urban/src/@core/hooks/useInvoices.ts @@ -0,0 +1,68 @@ +'use client'; + +import { useCallback, useEffect, useRef, useState } from 'react'; +import apiClient from '@/lib/apiClient'; +export type InvoiceStatus = 'PENDING' | 'PAID' | 'FAILED' | 'CANCELED'; + +export type InvoiceWithDescription = { + id: string; + subscriptionId: string; + base64Invoice: string | null; + linkPayment: string | null; + status: InvoiceStatus | string; + amount: number; + createdAt: string | Date; + updatedAt: string | Date; + description: string; +}; + +export type UseInvoicesOptions = { + auto?: boolean; +}; + +export type UseInvoicesResult = { + data: InvoiceWithDescription[]; + loading: boolean; + error: unknown; + refresh: () => Promise; + setData: React.Dispatch>; +}; + +export function useInvoices( + userId: string, + opts: UseInvoicesOptions = {} +): UseInvoicesResult { + const { auto = true } = opts; + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(auto); + const [error, setError] = useState(null); + + const abortRef = useRef(null); + + const refresh = useCallback(async () => { + if (!userId) return; + setLoading(true); + setError(null); + if (abortRef.current) abortRef.current.abort(); + const ac = new AbortController(); + abortRef.current = ac; + + try { + const res = await apiClient.get(`/invoices/${encodeURIComponent(userId)}`, { signal: ac.signal }); + setData((res.data ?? []) as InvoiceWithDescription[]); + } catch (e: any) { + if (e?.name === 'CanceledError' || e?.message === 'canceled') return; + setError(e); + } finally { + if (!ac.signal.aborted) setLoading(false); + } + }, [userId]); + + useEffect(() => { + if (auto) refresh(); + return () => abortRef.current?.abort(); + }, [auto, refresh, userId]); + + return { data, loading, error, refresh, setData }; +} diff --git a/front-urban/src/@core/hooks/useObjectCookie.ts b/front-urban/src/@core/hooks/useObjectCookie.ts new file mode 100644 index 0000000..0c1f7d0 --- /dev/null +++ b/front-urban/src/@core/hooks/useObjectCookie.ts @@ -0,0 +1,19 @@ +// React Imports +import { useMemo } from 'react' + +// Third-party Imports +import { useCookie } from 'react-use' + +export const useObjectCookie = (key: string, fallback?: T | null): [T, (newVal: T) => void] => { + // Hooks + const [valStr, updateCookie] = useCookie(key) + + // eslint-disable-next-line react-hooks/exhaustive-deps + const value = useMemo(() => (valStr ? JSON.parse(valStr) : fallback), [valStr]) + + const updateValue = (newVal: T) => { + updateCookie(JSON.stringify(newVal)) + } + + return [value, updateValue] +} diff --git a/front-urban/src/@core/hooks/useProfilePicture.ts b/front-urban/src/@core/hooks/useProfilePicture.ts new file mode 100644 index 0000000..db44834 --- /dev/null +++ b/front-urban/src/@core/hooks/useProfilePicture.ts @@ -0,0 +1,82 @@ +'use client'; + +import { useState, useCallback, useEffect } from 'react'; +import apiClient from '@/lib/apiClient'; + +export type ProfilePictureResponse = { + profilePicture: string | null; + updatedAt: string | null; +}; + +export type UseProfilePictureOptions = { + auto?: boolean; +}; + +export type UseProfilePictureResult = { + profilePicture: string | null; + updatedAt: string | null; + loading: boolean; + error: unknown; + refresh: () => Promise; +}; + +/** + * Hook para obtener la foto de perfil de un usuario + * + * @param userId - ID del usuario + * @param options - Opciones de configuración + * + * @example + * ```tsx + * const { profilePicture, loading, error, refresh } = useProfilePicture('user-123', { auto: true }); + * + * return ( + * Profile + * ); + * ``` + */ +export function useProfilePicture( + userId: string, + options: UseProfilePictureOptions = {} +): UseProfilePictureResult { + const { auto = true } = options; + + const [profilePicture, setProfilePicture] = useState(null); + const [updatedAt, setUpdatedAt] = useState(null); + const [loading, setLoading] = useState(auto); + const [error, setError] = useState(null); + + const refresh = useCallback(async () => { + if (!userId) return; + + setLoading(true); + setError(null); + + try { + const res = await apiClient.get(`/users/${encodeURIComponent(userId)}/profile-picture`); + + setProfilePicture(res.data.profilePicture); + setUpdatedAt(res.data.updatedAt); + } catch (e: any) { + setError(e); + setProfilePicture(null); + setUpdatedAt(null); + } finally { + setLoading(false); + } + }, [userId]); + + useEffect(() => { + if (auto && userId) { + refresh(); + } + }, [auto, userId, refresh]); + + return { + profilePicture, + updatedAt, + loading, + error, + refresh, + }; +} diff --git a/front-urban/src/@core/hooks/useSessionInvoicesByMonth.ts b/front-urban/src/@core/hooks/useSessionInvoicesByMonth.ts new file mode 100644 index 0000000..092ef6a --- /dev/null +++ b/front-urban/src/@core/hooks/useSessionInvoicesByMonth.ts @@ -0,0 +1,91 @@ +// useSessionInvoicesByMonth.ts +'use client'; + +import { useCallback, useEffect, useRef, useState } from 'react'; +import apiClient from '@/lib/apiClient'; + +export type InvoiceStatus = 'PENDING' | 'PAID' | 'CANCELED'; + +export type AssistantInvoice = { + id: string; + name: string; + hasInvoice: boolean; + invoiceStatus: InvoiceStatus | null; + invoiceId: string | null; + amount: number | null; +}; + +export type SessionInvoicesByMonth = { + sessionId: string; + sessionCustomId: string; + sessionDescription: string; + sessionType: string; + month: string; + year: string; + assistants: AssistantInvoice[]; +}; + +type Options = { + sessionId: string; + month: string; // "01" a "12" + year: string; // "YYYY" + auto?: boolean; +}; + +type UseSessionInvoicesByMonthResult = { + data: SessionInvoicesByMonth | null; + loading: boolean; + error: unknown; + refresh: () => Promise; +}; + +export function useSessionInvoicesByMonth( + opts: Options +): UseSessionInvoicesByMonthResult { + const { sessionId, month, year, auto = true } = opts; + + const [data, setData] = useState(null); + const [loading, setLoading] = useState(auto); + const [error, setError] = useState(null); + + const abortRef = useRef(null); + + const refresh = useCallback(async () => { + if (!sessionId || !month || !year) { + setData(null); + setLoading(false); + return; + } + + setLoading(true); + setError(null); + + // Cancelar request previa si hubiera + if (abortRef.current) abortRef.current.abort(); + const ac = new AbortController(); + abortRef.current = ac; + + try { + const res = await apiClient.get( + `/sessions/${sessionId}/invoices-by-month`, + { params: { month, year }, signal: ac.signal } + ); + setData(res.data); + } catch (e: any) { + if (e?.name === 'CanceledError' || e?.message === 'canceled') return; + setError(e); + console.error('Error al obtener facturas por mes:', e); + } finally { + if (!ac.signal.aborted) setLoading(false); + } + }, [sessionId, month, year]); + + useEffect(() => { + if (auto) refresh(); + return () => { + abortRef.current?.abort(); + }; + }, [auto, refresh]); + + return { data, loading, error, refresh }; +} diff --git a/front-urban/src/@core/hooks/useSessionParticipants.ts b/front-urban/src/@core/hooks/useSessionParticipants.ts new file mode 100644 index 0000000..004b73c --- /dev/null +++ b/front-urban/src/@core/hooks/useSessionParticipants.ts @@ -0,0 +1,42 @@ +// useSessionParticipants.ts +'use client'; +import { useCallback, useEffect, useState } from 'react'; +import apiClient from '@/lib/apiClient'; + +export type Participant = { id: string; name: string; customId?: string }; + +export function useSessionParticipants(token: string, sessionId: string, auto = true) { + const [selected, setSelected] = useState([]); + const [available, setAvailable] = useState([]); + const [loading, setLoading] = useState(auto); + const [error, setError] = useState(null); + + const refresh = useCallback(async () => { + setLoading(true); setError(null); + try { + const { data } = await apiClient.get(`/sessions/${sessionId}/participants`); + setSelected(data.selected); + setAvailable(data.available); + } catch (e) { setError(e); } finally { setLoading(false); } + }, [sessionId]); + + const save = useCallback(async () => { + await apiClient.put(`/sessions/${sessionId}/participants`, { + userIds: selected.map(s => s.id), + }); + }, [sessionId, selected]); + + useEffect(() => { if (auto) refresh(); }, [auto, refresh]); + + // helpers UI + const add = (p: Participant) => { + setAvailable(prev => prev.filter(x => x.id !== p.id)); + setSelected(prev => [...prev, p]); + }; + const remove = (p: Participant) => { + setSelected(prev => prev.filter(x => x.id !== p.id)); + setAvailable(prev => [...prev, p]); + }; + + return { selected, available, setSelected, setAvailable, loading, error, refresh, save, add, remove }; +} diff --git a/front-urban/src/@core/hooks/useSettings.tsx b/front-urban/src/@core/hooks/useSettings.tsx new file mode 100644 index 0000000..0844fde --- /dev/null +++ b/front-urban/src/@core/hooks/useSettings.tsx @@ -0,0 +1,16 @@ +// React Imports +import { useContext } from 'react' + +// Context Imports +import { SettingsContext } from '@core/contexts/settingsContext' + +export const useSettings = () => { + // Hooks + const context = useContext(SettingsContext) + + if (!context) { + throw new Error('useSettingsContext must be used within a SettingsProvider') + } + + return context +} diff --git a/front-urban/src/@core/hooks/useSystemConfig.ts b/front-urban/src/@core/hooks/useSystemConfig.ts new file mode 100644 index 0000000..6a385d2 --- /dev/null +++ b/front-urban/src/@core/hooks/useSystemConfig.ts @@ -0,0 +1,94 @@ +'use client'; +import type { SystemConfig, UpdateSystemConfigDto } from '@/@core/types/system-config'; +import apiClient from '@/lib/apiClient'; +import { useCallback, useState } from 'react'; + +export type UseSystemConfigOptions = {}; + +export type UseSystemConfigResult = { + data: SystemConfig | null; + loading: boolean; + error: unknown; + fetchConfig: () => Promise; + updateConfig: (dto: UpdateSystemConfigDto) => Promise; + reloadConfig: () => Promise; + updating: boolean; + reloading: boolean; +}; + +/** + * Hook para gestionar la configuración del sistema + */ +export function useSystemConfig( + options: UseSystemConfigOptions = {} +): UseSystemConfigResult { + + const [data, setData] = useState(null); + const [loading, setLoading] = useState(false); + const [updating, setUpdating] = useState(false); + const [reloading, setReloading] = useState(false); + const [error, setError] = useState(null); + + // Obtener configuración actual + const fetchConfig = useCallback(async () => { + setLoading(true); + setError(null); + + try { + const res = await apiClient.get('/system-config'); + setData(res.data); + } catch (e: any) { + console.log('Error fetching system config:', e); + setError(e); + throw e; + } finally { + setLoading(false); + } + }, []); + + // Actualizar configuración + const updateConfig = useCallback( + async (dto: UpdateSystemConfigDto) => { + setUpdating(true); + setError(null); + + try { + const res = await apiClient.patch('/system-config', dto); + setData(res.data); + } catch (e: any) { + setError(e); + throw e; + } finally { + setUpdating(false); + } + }, + [] + ); + + // Recargar configuración desde BD + const reloadConfig = useCallback(async () => { + setReloading(true); + setError(null); + + try { + const res = await apiClient.get('/system-config/reload'); + setData(res.data); + } catch (e: any) { + setError(e); + throw e; + } finally { + setReloading(false); + } + }, []); + + return { + data, + loading, + error, + fetchConfig, + updateConfig, + reloadConfig, + updating, + reloading, + }; +} diff --git a/front-urban/src/@core/hooks/useToggleUserActive.ts b/front-urban/src/@core/hooks/useToggleUserActive.ts new file mode 100644 index 0000000..01b5e21 --- /dev/null +++ b/front-urban/src/@core/hooks/useToggleUserActive.ts @@ -0,0 +1,38 @@ +import { useUserAuth } from '@/app/context/UserAuth'; +import apiClient from '@/lib/apiClient'; +import { useState } from 'react'; + +export const useToggleUserActive = () => { + const { token } = useUserAuth(); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const toggleActive = async (userId: string, isActive: boolean) => { + setLoading(true); + setError(null); + try { +<<<<<<< Updated upstream + const deleted = isActive ? null : new Date().toISOString(); + const response = await apiClient.put(`/users/${userId}/active`, { deleted }); + console.log('✅ User active status updated successfully:', response.data); +======= + const url = `${process.env.NEXT_PUBLIC_BACKEND_URL ?? ''}/users/${userId}/active`; + const deleted = isActive ? null : new Date().toISOString(); + const response = await axios.put( + url, + { deleted }, + { headers: { Authorization: `Bearer ${token}` } } + ); +>>>>>>> Stashed changes + return true; + } catch (err) { + console.error('❌ Error al cambiar estado del usuario', err); + setError('No se pudo cambiar el estado del usuario'); + return false; + } finally { + setLoading(false); + } + }; + + return { toggleActive, loading, error }; +}; diff --git a/front-urban/src/@core/hooks/useUpdateInvoiceStatus.ts b/front-urban/src/@core/hooks/useUpdateInvoiceStatus.ts new file mode 100644 index 0000000..71db3bf --- /dev/null +++ b/front-urban/src/@core/hooks/useUpdateInvoiceStatus.ts @@ -0,0 +1,100 @@ +'use client'; + +import { useState, useCallback } from 'react'; +import apiClient from '@/lib/apiClient'; +import type { InvoiceStatus } from './useInvoices'; + +export type UpdateInvoiceStatusParams = { + userId: string; + invoiceId: string; + status: InvoiceStatus; +}; + +export type UpdateInvoiceStatusOptions = { + onSuccess?: () => void | Promise; + onError?: (error: any) => void; +}; + +export type UpdateInvoiceStatusResult = { + mutate: (params: UpdateInvoiceStatusParams) => Promise; + loading: boolean; + error: unknown; + isSuccess: boolean; + reset: () => void; +}; + +/** + * Hook para actualizar el estado de una factura + * + * @example + * ```tsx + * const { mutate, loading, error, isSuccess } = useUpdateInvoiceStatus({ + * onSuccess: () => { + * toast.success('Factura actualizada'); + * refetchInvoices(); + * }, + * onError: (error) => { + * toast.error('Error al actualizar factura'); + * } + * }); + * + * // Usar la mutación + * await mutate({ + * userId: 'user-123', + * invoiceId: 'invoice-456', + * status: 'PAID' + * }); + * ``` + */ +export function useUpdateInvoiceStatus( + options: UpdateInvoiceStatusOptions = {} +): UpdateInvoiceStatusResult { + const { onSuccess, onError } = options; + + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [isSuccess, setIsSuccess] = useState(false); + + const mutate = useCallback( + async ({ userId, invoiceId, status }: UpdateInvoiceStatusParams) => { + if (!userId || !invoiceId || !status) { + const validationError = new Error('userId, invoiceId y status son requeridos'); + setError(validationError); + onError?.(validationError); + throw validationError; + } + + setLoading(true); + setError(null); + setIsSuccess(false); + + try { + await apiClient.put( + `/invoices/${encodeURIComponent(userId)}/${encodeURIComponent(invoiceId)}`, + { status } + ); + + setIsSuccess(true); + + // Ejecutar callback de éxito + await onSuccess?.(); + } catch (e: any) { + setError(e); + setIsSuccess(false); + onError?.(e); + throw e; + } finally { + setLoading(false); + } + }, + [onSuccess, onError] + ); + + const reset = useCallback(() => { + setLoading(false); + setError(null); + setIsSuccess(false); + }, []); + + return { mutate, loading, error, isSuccess, reset }; +} diff --git a/front-urban/src/@core/hooks/useUsuarios.ts b/front-urban/src/@core/hooks/useUsuarios.ts new file mode 100644 index 0000000..b73c67c --- /dev/null +++ b/front-urban/src/@core/hooks/useUsuarios.ts @@ -0,0 +1,78 @@ +// useUsuarios.ts +'use client'; + +import { useCallback, useEffect, useRef, useState } from 'react'; +import apiClient from '@/lib/apiClient'; +import { Usuario } from '@/views/usuarios/usuarios.dto'; + +type Options = { + /** Lanza el fetch al montar el hook (default: true) */ + auto?: boolean; +}; + +type UseUsuariosResult = { + data: Usuario[]; + loading: boolean; + error: unknown; + /** Vuelve a pedir la lista */ + refresh: () => Promise; + /** Setea manualmente el array (útil para optimist updates) */ + setData: React.Dispatch>; +}; + +export function useUsuarios(opts: Options = {}): UseUsuariosResult { + const { auto = true } = opts; + + const [data, setData] = useState([]); + const [loading, setLoading] = useState(auto); + const [error, setError] = useState(null); + + // guardamos una referencia al abortController para cancelar en unmount + const abortRef = useRef(null); + + const refresh = useCallback(async () => { + setLoading(true); + setError(null); + + // cancelar request previa si hubiera + if (abortRef.current) abortRef.current.abort(); + const ac = new AbortController(); + abortRef.current = ac; + + try { +<<<<<<< Updated upstream + const res = await apiClient.get('/users', { signal: ac.signal }); +======= + if (!token) throw new Error('Token no encontrado'); + + // Asegurar que baseUrl no esté vacío + const backendUrl = baseUrl + const url = `${backendUrl}/users`; + + + const res = await axios.get(url, { + headers: { Authorization: `Bearer ${token}` }, + signal: ac.signal, // axios v1 soporta AbortController + }); + +>>>>>>> Stashed changes + setData(res.data ?? []); + } catch (e: any) { + if (e?.name === 'CanceledError' || e?.message === 'canceled') return; + setError(e); + console.error('Error al obtener usuarios:', e); + } finally { + if (!ac.signal.aborted) setLoading(false); + } + }, []); + + useEffect(() => { + if (auto) refresh(); + return () => { + // cancelar si el componente se desmonta + abortRef.current?.abort(); + }; + }, [auto, refresh]); + + return { data, loading, error, refresh, setData }; +} diff --git a/front-urban/src/@core/hooks/useWhatsappStatus.ts b/front-urban/src/@core/hooks/useWhatsappStatus.ts new file mode 100644 index 0000000..3638255 --- /dev/null +++ b/front-urban/src/@core/hooks/useWhatsappStatus.ts @@ -0,0 +1,36 @@ +// hooks/useWhatsappStatus.ts +'use client'; +import useSWR from 'swr'; +import apiClient from '@/lib/apiClient'; + +const WHATSAPP_STATUS_PATH = '/whatsapp/status'; + +const fetcher = async (path: string) => { + const res = await apiClient.get(path); + return res.data; // { status, phone, qr } +}; + +export type UseWhatsappStatusOptions = {}; + +export function useWhatsappStatus(_options: UseWhatsappStatusOptions = {}) { + const { data, error, isLoading, mutate } = useSWR( + WHATSAPP_STATUS_PATH, + fetcher, + { + // más frecuencia si NO hay sesión; más relajado si ya está conectada + refreshInterval: (data) => + data?.status === 'Correcto' ? 30_000 : 3_000, + revalidateOnFocus: false, + shouldRetryOnError: true, + } + ); + + return { + status: data?.status ?? 'Sin session', + phone: data?.phone ?? 'No disponible', + qr: data?.qr ?? null, + loading: isLoading, + error, + refresh: () => mutate(), // botón "Actualizar" + }; +} diff --git a/front-urban/src/@core/styles/stepper.ts b/front-urban/src/@core/styles/stepper.ts new file mode 100644 index 0000000..9d2d0fe --- /dev/null +++ b/front-urban/src/@core/styles/stepper.ts @@ -0,0 +1,103 @@ +// MUI imports +import Box from '@mui/material/Box' +import { styled } from '@mui/material/styles' +import type { BoxProps } from '@mui/material/Box' + +const StepperWrapper = styled(Box)(({ theme }) => { + return { + [theme.breakpoints.down('md')]: { + '& .MuiStepper-horizontal:not(.MuiStepper-alternativeLabel)': { + flexDirection: 'column', + alignItems: 'flex-start' + } + }, + '& .MuiStep-root': { + '& .MuiStepLabel-iconContainer:empty': { + display: 'none' + }, + '& .step-label': { + display: 'flex', + alignItems: 'center', + justifyContent: 'center' + }, + '& .step-number': { + ...theme.typography.h4, + marginRight: theme.spacing(2) + }, + '&:not(:has(.step-subtitle)) .step-number': { + ...theme.typography.h6 + }, + '& .step-title': { + ...theme.typography.body1, + letterSpacing: 0.15, + fontWeight: 500 + }, + '& .step-subtitle': { + ...theme.typography.body2, + color: 'var(--mui-palette-text-secondary)' + }, + '& .MuiStepLabel-root.Mui-disabled': { + '& .step-number': { + color: 'var(--mui-palette-text-disabled)' + } + }, + '& .Mui-error': { + '& .MuiStepLabel-labelContainer, & .step-number, & .step-title, & .step-subtitle': { + color: 'var(--mui-palette-error-main)' + } + } + }, + '& .MuiStepConnector-root': { + '& .MuiStepConnector-line': { + borderBlockStartWidth: 3, + borderRadius: 3 + }, + '&.Mui-active, &.Mui-completed': { + '& .MuiStepConnector-line': { + borderColor: 'var(--mui-palette-primary-main)' + } + }, + '&.Mui-disabled .MuiStepConnector-line': { + borderColor: 'var(--mui-palette-primary-lightOpacity)' + } + }, + '& .MuiStepper-alternativeLabel': { + '& .MuiStepConnector-root': { + top: 9 + }, + '& .MuiStepLabel-labelContainer': { + display: 'flex', + alignItems: 'center', + flexDirection: 'column' + } + }, + '& .MuiStepper-vertical': { + '& .MuiStep-root': { + '& .step-label': { + justifyContent: 'flex-start' + }, + '& .MuiStepContent-root': { + borderInlineStartWidth: 3, + marginLeft: theme.spacing(2.25), + borderColor: 'var(--mui-palette-primary-main)' + }, + '& .button-wrapper': { + marginTop: theme.spacing(4) + }, + '&.active + .MuiStepConnector-root .MuiStepConnector-line': { + borderColor: 'var(--mui-palette-primary-main)' + } + }, + '& .MuiStepConnector-root': { + marginLeft: theme.spacing(2.25), + '& .MuiStepConnector-line': { + borderBlockStartWidth: 0, + borderInlineStartWidth: 3, + borderRadius: 0 + } + } + } + } +}) + +export default StepperWrapper diff --git a/front-urban/src/@core/styles/table.module.css b/front-urban/src/@core/styles/table.module.css new file mode 100644 index 0000000..22d3c9b --- /dev/null +++ b/front-urban/src/@core/styles/table.module.css @@ -0,0 +1,92 @@ +.table { + inline-size: 100%; + border-collapse: collapse; + font-size: 0.875rem; + white-space: nowrap; + + [align='right'] > * { + text-align: end; + } + [align='center'] > * { + text-align: center; + } + + thead { + text-transform: uppercase; + color: var(--mui-palette-text-primary); + + th { + font-weight: 500; + font-size: 0.8125rem; + letter-spacing: 0.2px; + line-height: 1.8462; + text-align: start; + block-size: 56px; + background-color: var(--mui-palette-customColors-tableHeaderBg); + &:not(:first-of-type):not(:last-of-type) { + padding-block: 0.5rem; + padding-inline: 1rem; + } + &:first-of-type { + &:not(:has(input[type='checkbox'])) { + padding-block: 0.5rem; + padding-inline: 1.25rem 1rem; + } + &:has(input[type='checkbox']) { + padding-inline-start: 0.6875rem; + } + } + &:last-of-type { + padding-block: 0.5rem; + padding-inline: 1rem 1.25rem; + } + } + } + + tbody { + color: var(--mui-palette-text-secondary); + + th, + td { + font-size: 0.9375rem; + line-height: 1.4667; + block-size: 50px; + &:not(:first-of-type):not(:last-of-type) { + padding-block: 0.5rem; + padding-inline: 1rem; + } + &:first-of-type { + &:not(:has(input[type='checkbox'])) { + padding-block: 0.5rem; + padding-inline: 1.25rem 1rem; + } + &:has(input[type='checkbox']) { + padding-inline-start: 0.6875rem; + } + } + &:last-of-type { + padding-block: 0.5rem; + padding-inline: 1rem 1.25rem; + } + } + + tr:not(:last-child) { + border-block-end: 1px solid var(--border-color); + } + } +} + +.cellWithInput input { + inline-size: 100%; + background-color: transparent; + font-size: inherit; + color: inherit; + border-radius: var(--mui-shape-customBorderRadius-sm); + padding-block: 6px; + padding-inline: 10px; + margin-inline: -10px; + + &:focus-visible { + outline: 1px solid var(--mui-palette-primary-main); + } +} diff --git a/front-urban/src/@core/styles/vertical/menuItemStyles.ts b/front-urban/src/@core/styles/vertical/menuItemStyles.ts new file mode 100644 index 0000000..98c5a5c --- /dev/null +++ b/front-urban/src/@core/styles/vertical/menuItemStyles.ts @@ -0,0 +1,99 @@ +// MUI Imports +import { lighten } from '@mui/material/styles' +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { MenuItemStyles } from '@menu/types' + +// Util Imports +import { menuClasses } from '@menu/utils/menuClasses' + +const menuItemStyles = (theme: Theme): MenuItemStyles => { + return { + root: { + marginBlockStart: theme.spacing(1.5), + [`&.${menuClasses.subMenuRoot}.${menuClasses.open} > .${menuClasses.button}, &.${menuClasses.subMenuRoot} > .${menuClasses.button}.${menuClasses.active}`]: + { + backgroundColor: 'var(--mui-palette-action-selected) !important' + }, + [`&.${menuClasses.disabled} > .${menuClasses.button}`]: { + color: 'var(--mui-palette-text-disabled)', + [`& .${menuClasses.icon}`]: { + color: 'inherit' + } + }, + [`&:not(.${menuClasses.subMenuRoot}) > .${menuClasses.button}.${menuClasses.active}`]: { + color: 'var(--mui-palette-primary-contrastText)', + background: + theme.direction === 'ltr' + ? `linear-gradient(270deg, var(--mui-palette-primary-main), ${lighten( + theme.palette.primary.main, + 0.5 + )} 100%)` + : `linear-gradient(270deg, ${lighten( + theme.palette.primary.main, + 0.5 + )}, var(--mui-palette-primary-main) 100%)`, + [`& .${menuClasses.icon}`]: { + color: 'inherit' + } + } + }, + button: ({ active }) => ({ + paddingBlock: theme.spacing(2), + '&:has(.MuiChip-root)': { + paddingBlock: theme.spacing(1.75) + }, + paddingInlineStart: theme.spacing(5.5), + paddingInlineEnd: theme.spacing(3.5), + borderStartEndRadius: 50, + borderEndEndRadius: 50, + ...(!active && { + '&:hover, &:focus-visible': { + backgroundColor: 'var(--mui-palette-action-hover)' + }, + '&[aria-expanded="true"]': { + backgroundColor: 'var(--mui-palette-action-selected)' + } + }) + }), + icon: ({ level }) => ({ + ...(level === 0 && { + fontSize: '1.375rem', + marginInlineEnd: theme.spacing(2) + }), + ...(level > 0 && { + fontSize: '0.75rem', + color: 'var(--mui-palette-text-secondary)', + marginInlineEnd: theme.spacing(3.5) + }), + ...(level === 1 && { + marginInlineStart: theme.spacing(1.5) + }), + ...(level > 1 && { + marginInlineStart: theme.spacing(1.5 + 2.5 * (level - 1)) + }), + '& > i, & > svg': { + fontSize: 'inherit' + } + }), + prefix: { + marginInlineEnd: theme.spacing(2) + }, + suffix: { + marginInlineStart: theme.spacing(2) + }, + subMenuExpandIcon: { + fontSize: '1.375rem', + marginInlineStart: theme.spacing(2), + '& i, & svg': { + fontSize: 'inherit' + } + }, + subMenuContent: { + backgroundColor: 'transparent' + } + } +} + +export default menuItemStyles diff --git a/front-urban/src/@core/styles/vertical/menuSectionStyles.ts b/front-urban/src/@core/styles/vertical/menuSectionStyles.ts new file mode 100644 index 0000000..b3282fd --- /dev/null +++ b/front-urban/src/@core/styles/vertical/menuSectionStyles.ts @@ -0,0 +1,42 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { MenuProps } from '@menu/vertical-menu' + +// Util Imports +import { menuClasses } from '@menu/utils/menuClasses' + +const menuSectionStyles = (theme: Theme): MenuProps['menuSectionStyles'] => { + return { + root: { + marginBlockStart: theme.spacing(7), + [`& .${menuClasses.menuSectionContent}`]: { + color: 'var(--mui-palette-text-disabled)', + paddingInline: '0 !important', + paddingBlock: `${theme.spacing(1.75)} !important`, + gap: theme.spacing(2.5), + + '&:before': { + content: '""', + blockSize: 1, + inlineSize: '0.875rem', + backgroundColor: 'var(--mui-palette-divider)' + }, + '&:after': { + content: '""', + blockSize: 1, + flexGrow: 1, + backgroundColor: 'var(--mui-palette-divider)' + } + }, + [`& .${menuClasses.menuSectionLabel}`]: { + flexGrow: 0, + fontSize: '13px', + lineHeight: 1.38462 + } + } + } +} + +export default menuSectionStyles diff --git a/front-urban/src/@core/styles/vertical/navigationCustomStyles.ts b/front-urban/src/@core/styles/vertical/navigationCustomStyles.ts new file mode 100644 index 0000000..58a4c85 --- /dev/null +++ b/front-urban/src/@core/styles/vertical/navigationCustomStyles.ts @@ -0,0 +1,35 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Util Imports +import { menuClasses, verticalNavClasses } from '@menu/utils/menuClasses' + +const navigationCustomStyles = (theme: Theme) => { + return { + color: 'var(--mui-palette-text-primary)', + zIndex: 'var(--drawer-z-index) !important', + [`& .${verticalNavClasses.bgColorContainer}`]: { + backgroundColor: 'var(--mui-palette-background-default)' + }, + [`& .${verticalNavClasses.header}`]: { + paddingBlock: theme.spacing(5), + paddingInline: theme.spacing(5.5, 4) + }, + [`& .${verticalNavClasses.container}`]: { + transition: 'none', + borderColor: 'transparent', + [`& .${verticalNavClasses.toggled}`]: { + boxShadow: 'var(--mui-customShadows-lg)' + } + }, + [`& .${menuClasses.root}`]: { + paddingBlockEnd: theme.spacing(2), + paddingInlineEnd: theme.spacing(4) + }, + [`& .${verticalNavClasses.backdrop}`]: { + backgroundColor: 'var(--backdrop-color)' + } + } +} + +export default navigationCustomStyles diff --git a/front-urban/src/@core/svg/Logo.tsx b/front-urban/src/@core/svg/Logo.tsx new file mode 100644 index 0000000..31d5dea --- /dev/null +++ b/front-urban/src/@core/svg/Logo.tsx @@ -0,0 +1,77 @@ +// React Imports +import type { SVGAttributes } from 'react' + +const Logo = (props: SVGAttributes) => { + return ( + + + + + + + + + + + + + ) +} + +export default Logo diff --git a/front-urban/src/@core/tailwind/plugin.ts b/front-urban/src/@core/tailwind/plugin.ts new file mode 100644 index 0000000..ce91f05 --- /dev/null +++ b/front-urban/src/@core/tailwind/plugin.ts @@ -0,0 +1,74 @@ +import plugin from 'tailwindcss/plugin' + +module.exports = plugin(function () {}, { + theme: { + borderColor: ({ theme }) => ({ + ...theme('colors'), + DEFAULT: 'var(--border-color, currentColor)' + }), + borderRadius: { + none: '0px', + xs: 'var(--mui-shape-customBorderRadius-xs)', + sm: 'var(--mui-shape-customBorderRadius-sm)', + DEFAULT: '0.375rem', + md: 'var(--mui-shape-customBorderRadius-md)', + lg: 'var(--mui-shape-customBorderRadius-lg)', + xl: 'var(--mui-shape-customBorderRadius-xl)', + '2xl': '0.75rem', + '3xl': '1rem', + '4xl': '1.5rem', + full: '9999px' + }, + screens: { + sm: '600px', + md: '900px', + lg: '1200px', + xl: '1536px', + '2xl': '1920px' + }, + extend: { + boxShadow: { + xs: 'var(--mui-customShadows-xs)', + sm: 'var(--mui-customShadows-sm)', + DEFAULT: 'var(--mui-customShadows-md)', + md: 'var(--mui-customShadows-md)', + lg: 'var(--mui-customShadows-lg)', + xl: 'var(--mui-customShadows-xl)' + }, + colors: { + primary: 'var(--primary-color)', + primaryLight: 'var(--mui-palette-primary-lightOpacity)', + primaryLighter: 'var(--mui-palette-primary-lighterOpacity)', + secondary: 'var(--mui-palette-secondary-main)', + error: 'var(--mui-palette-error-main)', + errorLight: 'var(--mui-palette-error-lightOpacity)', + errorLighter: 'var(--mui-palette-error-lighterOpacity)', + warning: 'var(--mui-palette-warning-main)', + info: 'var(--mui-palette-info-main)', + success: 'var(--mui-palette-success-main)', + textPrimary: 'var(--mui-palette-text-primary)', + textSecondary: 'var(--mui-palette-text-secondary)', + textDisabled: 'var(--mui-palette-text-disabled)', + actionActive: 'var(--mui-palette-action-active)', + actionHover: 'var(--mui-palette-action-hover)', + actionSelected: 'var(--mui-palette-action-selected)', + actionFocus: 'var(--mui-palette-action-focus)', + backgroundPaper: 'var(--mui-palette-background-paper)', + backgroundDefault: 'var(--mui-palette-background-default)', + track: 'var(--mui-palette-customColors-trackBg)', + backdrop: 'var(--backdrop-color)', + facebook: '#497ce2', + twitter: '#1da1f2', + github: '#272727', + googlePlus: '#db4437' + }, + zIndex: { + header: 'var(--header-z-index)', + footer: 'var(--footer-z-index)', + customizer: 'var(--customizer-z-index)', + search: 'var(--search-z-index)', + drawer: 'var(--drawer-z-index)' + } + } + } +}) diff --git a/front-urban/src/@core/theme/colorSchemes.ts b/front-urban/src/@core/theme/colorSchemes.ts new file mode 100644 index 0000000..544c4bb --- /dev/null +++ b/front-urban/src/@core/theme/colorSchemes.ts @@ -0,0 +1,329 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const colorSchemes = (): Theme['colorSchemes'] => { + const skin = 'default' as string + + return { + light: { + palette: { + primary: { + main: '#8C57FF', + light: '#A379FF', + dark: '#7E4EE6', + lighterOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.38)' + }, + secondary: { + main: '#8A8D93', + light: '#A1A4A9', + dark: '#7C7F84', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.38)' + }, + error: { + main: '#FF4C51', + light: '#FF7074', + dark: '#E64449', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.38)' + }, + warning: { + main: '#FFB400', + light: '#FFC333', + dark: '#E6A200', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.38)' + }, + info: { + main: '#16B1FF', + light: '#45C1FF', + dark: '#149FE6', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.38)' + }, + success: { + main: '#56CA00', + light: '#78D533', + dark: '#4DB600', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.38)' + }, + text: { + primary: `rgb(var(--mui-mainColorChannels-light) / 0.9)`, + secondary: `rgb(var(--mui-mainColorChannels-light) / 0.7)`, + disabled: `rgb(var(--mui-mainColorChannels-light) / 0.4)`, + primaryChannel: 'var(--mui-mainColorChannels-light)', + secondaryChannel: 'var(--mui-mainColorChannels-light)' + }, + divider: `rgb(var(--mui-mainColorChannels-light) / 0.12)`, + dividerChannel: 'var(--mui-mainColorChannels-light)', + background: { + default: skin === 'bordered' ? '#FFFFFF' : '#F4F5FA', + paper: '#FFFFFF' + }, + action: { + active: `rgb(var(--mui-mainColorChannels-light) / 0.6)`, + hover: `rgb(var(--mui-mainColorChannels-light) / 0.04)`, + selected: `rgb(var(--mui-mainColorChannels-light) / 0.08)`, + disabled: `rgb(var(--mui-mainColorChannels-light) / 0.3)`, + disabledBackground: `rgb(var(--mui-mainColorChannels-light) / 0.12)`, + focus: `rgb(var(--mui-mainColorChannels-light) / 0.1)`, + focusOpacity: 0.1, + activeChannel: 'var(--mui-mainColorChannels-light)', + selectedChannel: 'var(--mui-mainColorChannels-light)' + }, + Alert: { + errorColor: 'var(--mui-palette-error-main)', + warningColor: 'var(--mui-palette-warning-main)', + infoColor: 'var(--mui-palette-info-main)', + successColor: 'var(--mui-palette-success-main)', + errorStandardBg: 'var(--mui-palette-error-lightOpacity)', + warningStandardBg: 'var(--mui-palette-warning-lightOpacity)', + infoStandardBg: 'var(--mui-palette-info-lightOpacity)', + successStandardBg: 'var(--mui-palette-success-lightOpacity)', + errorFilledColor: 'var(--mui-palette-error-contrastText)', + warningFilledColor: 'var(--mui-palette-warning-contrastText)', + infoFilledColor: 'var(--mui-palette-info-contrastText)', + successFilledColor: 'var(--mui-palette-success-contrastText)', + errorFilledBg: 'var(--mui-palette-error-main)', + warningFilledBg: 'var(--mui-palette-warning-main)', + infoFilledBg: 'var(--mui-palette-info-main)', + successFilledBg: 'var(--mui-palette-success-main)' + }, + Avatar: { + defaultBg: '#F0EFF0' + }, + Chip: { + defaultBorder: 'var(--mui-palette-divider)' + }, + FilledInput: { + bg: `rgb(var(--mui-mainColorChannels-light) / 0.06)`, + hoverBg: `rgb(var(--mui-mainColorChannels-light) / 0.08)`, + disabledBg: `rgb(var(--mui-mainColorChannels-light) / 0.06)` + }, + LinearProgress: { + primaryBg: 'var(--mui-palette-primary-mainOpacity)', + secondaryBg: 'var(--mui-palette-secondary-mainOpacity)', + errorBg: 'var(--mui-palette-error-mainOpacity)', + warningBg: 'var(--mui-palette-warning-mainOpacity)', + infoBg: 'var(--mui-palette-info-mainOpacity)', + successBg: 'var(--mui-palette-success-mainOpacity)' + }, + SnackbarContent: { + bg: '#1A0E33', + color: 'var(--mui-palette-background-paper)' + }, + Switch: { + defaultColor: 'var(--mui-palette-common-white)', + defaultDisabledColor: 'var(--mui-palette-common-white)', + primaryDisabledColor: 'var(--mui-palette-common-white)', + secondaryDisabledColor: 'var(--mui-palette-common-white)', + errorDisabledColor: 'var(--mui-palette-common-white)', + warningDisabledColor: 'var(--mui-palette-common-white)', + infoDisabledColor: 'var(--mui-palette-common-white)', + successDisabledColor: 'var(--mui-palette-common-white)' + }, + Tooltip: { + bg: '#1A0E33' + }, + TableCell: { + border: 'var(--mui-palette-divider)' + }, + customColors: { + bodyBg: '#F4F5FA', + chatBg: '#F7F6FA', + greyLightBg: '#FAFAFA', + inputBorder: `rgb(var(--mui-mainColorChannels-light) / 0.22)`, + tableHeaderBg: '#F6F7FB', + tooltipText: '#FFFFFF', + trackBg: '#F0F2F8' + } + } + }, + dark: { + palette: { + primary: { + main: '#8C57FF', + light: '#A379FF', + dark: '#7E4EE6', + lighterOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-primary-mainChannel) / 0.38)' + }, + secondary: { + main: '#8A8D93', + light: '#A1A4A9', + dark: '#7C7F84', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.38)' + }, + error: { + main: '#FF4C51', + light: '#FF7074', + dark: '#E64449', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-error-mainChannel) / 0.38)' + }, + warning: { + main: '#FFB400', + light: '#FFC333', + dark: '#E6A200', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-warning-mainChannel) / 0.38)' + }, + info: { + main: '#16B1FF', + light: '#45C1FF', + dark: '#149FE6', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-info-mainChannel) / 0.38)' + }, + success: { + main: '#56CA00', + light: '#78D533', + dark: '#4DB600', + contrastText: '#fff', + lighterOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.08)', + lightOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.16)', + mainOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.24)', + darkOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.32)', + darkerOpacity: 'rgb(var(--mui-palette-success-mainChannel) / 0.38)' + }, + text: { + primary: `rgb(var(--mui-mainColorChannels-dark) / 0.9)`, + secondary: `rgb(var(--mui-mainColorChannels-dark) / 0.7)`, + disabled: `rgb(var(--mui-mainColorChannels-dark) / 0.4)`, + primaryChannel: 'var(--mui-mainColorChannels-dark)', + secondaryChannel: 'var(--mui-mainColorChannels-dark)' + }, + divider: `rgb(var(--mui-mainColorChannels-dark) / 0.12)`, + dividerChannel: 'var(--mui-mainColorChannels-dark)', + background: { + default: skin === 'bordered' ? '#312D4B' : '#28243D', + paper: '#312D4B' + }, + action: { + active: `rgb(var(--mui-mainColorChannels-dark) / 0.6)`, + hover: `rgb(var(--mui-mainColorChannels-dark) / 0.04)`, + selected: `rgb(var(--mui-mainColorChannels-dark) / 0.08)`, + disabled: `rgb(var(--mui-mainColorChannels-dark) / 0.3)`, + disabledBackground: `rgb(var(--mui-mainColorChannels-dark) / 0.12)`, + focus: `rgb(var(--mui-mainColorChannels-dark) / 0.1)`, + focusOpacity: 0.1, + activeChannel: 'var(--mui-mainColorChannels-dark)', + selectedChannel: 'var(--mui-mainColorChannels-dark)' + }, + Alert: { + errorColor: 'var(--mui-palette-error-main)', + warningColor: 'var(--mui-palette-warning-main)', + infoColor: 'var(--mui-palette-info-main)', + successColor: 'var(--mui-palette-success-main)', + errorStandardBg: 'var(--mui-palette-error-lightOpacity)', + warningStandardBg: 'var(--mui-palette-warning-lightOpacity)', + infoStandardBg: 'var(--mui-palette-info-lightOpacity)', + successStandardBg: 'var(--mui-palette-success-lightOpacity)', + errorFilledColor: 'var(--mui-palette-error-contrastText)', + warningFilledColor: 'var(--mui-palette-warning-contrastText)', + infoFilledColor: 'var(--mui-palette-info-contrastText)', + successFilledColor: 'var(--mui-palette-success-contrastText)', + errorFilledBg: 'var(--mui-palette-error-main)', + warningFilledBg: 'var(--mui-palette-warning-main)', + infoFilledBg: 'var(--mui-palette-info-main)', + successFilledBg: 'var(--mui-palette-success-main)' + }, + Avatar: { + defaultBg: '#3F3B59' + }, + Chip: { + defaultBorder: 'var(--mui-palette-divider)' + }, + FilledInput: { + bg: `rgb(var(--mui-mainColorChannels-dark) / 0.06)`, + hoverBg: `rgb(var(--mui-mainColorChannels-dark) / 0.08)`, + disabledBg: `rgb(var(--mui-mainColorChannels-dark) / 0.06)` + }, + LinearProgress: { + primaryBg: 'var(--mui-palette-primary-mainOpacity)', + secondaryBg: 'var(--mui-palette-secondary-mainOpacity)', + errorBg: 'var(--mui-palette-error-mainOpacity)', + warningBg: 'var(--mui-palette-warning-mainOpacity)', + infoBg: 'var(--mui-palette-info-mainOpacity)', + successBg: 'var(--mui-palette-success-mainOpacity)' + }, + SnackbarContent: { + bg: '#F7F4FF', + color: 'var(--mui-palette-background-paper)' + }, + Switch: { + defaultColor: 'var(--mui-palette-common-white)', + defaultDisabledColor: 'var(--mui-palette-common-white)', + primaryDisabledColor: 'var(--mui-palette-common-white)', + secondaryDisabledColor: 'var(--mui-palette-common-white)', + errorDisabledColor: 'var(--mui-palette-common-white)', + warningDisabledColor: 'var(--mui-palette-common-white)', + infoDisabledColor: 'var(--mui-palette-common-white)', + successDisabledColor: 'var(--mui-palette-common-white)' + }, + Tooltip: { + bg: '#F7F4FF' + }, + TableCell: { + border: 'var(--mui-palette-divider)' + }, + customColors: { + bodyBg: '#28243D', + chatBg: '#373452', + greyLightBg: '#373350', + inputBorder: `rgb(var(--mui-mainColorChannels-dark) / 0.22)`, + tableHeaderBg: '#3D3759', + tooltipText: '#312D4B', + trackBg: '#474360' + } + } + } + } as Theme['colorSchemes'] +} + +export default colorSchemes diff --git a/front-urban/src/@core/theme/customShadows.ts b/front-urban/src/@core/theme/customShadows.ts new file mode 100644 index 0000000..67d6a94 --- /dev/null +++ b/front-urban/src/@core/theme/customShadows.ts @@ -0,0 +1,17 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { SystemMode } from '@core/types' + +const customShadows = (mode: SystemMode): Theme['customShadows'] => { + return { + xs: `0px 2px 4px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.16 : 0.2})`, + sm: `0px 3px 6px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.18 : 0.22})`, + md: `0px 4px 10px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.2 : 0.24})`, + lg: `0px 6px 16px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.22 : 0.26})`, + xl: `0px 8px 28px rgb(var(--mui-mainColorChannels-${mode}Shadow) / ${mode === 'light' ? 0.24 : 0.28})` + } +} + +export default customShadows diff --git a/front-urban/src/@core/theme/index.ts b/front-urban/src/@core/theme/index.ts new file mode 100644 index 0000000..27137a6 --- /dev/null +++ b/front-urban/src/@core/theme/index.ts @@ -0,0 +1,48 @@ +// Next Imports +import { Inter } from 'next/font/google' + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { SystemMode } from '@core/types' + +// Theme Options Imports +import overrides from './overrides' +import colorSchemes from './colorSchemes' +import spacing from './spacing' +import shadows from './shadows' +import customShadows from './customShadows' +import typography from './typography' + +const inter = Inter({ subsets: ['latin'], weight: ['300', '400', '500', '600', '700', '800', '900'] }) + +const theme = (mode: SystemMode, direction: Theme['direction']): Theme => { + return { + direction, + components: overrides(), + colorSchemes: colorSchemes(), + ...spacing, + shape: { + borderRadius: 6, + customBorderRadius: { + xs: 2, + sm: 4, + md: 6, + lg: 8, + xl: 10 + } + }, + shadows: shadows(mode), + typography: typography(inter.style.fontFamily), + customShadows: customShadows(mode), + mainColorChannels: { + light: '46 38 61', + dark: '231 227 252', + lightShadow: '46 38 61', + darkShadow: '19 17 32' + } + } as Theme +} + +export default theme diff --git a/front-urban/src/@core/theme/overrides/accordion.tsx b/front-urban/src/@core/theme/overrides/accordion.tsx new file mode 100644 index 0000000..56d280f --- /dev/null +++ b/front-urban/src/@core/theme/overrides/accordion.tsx @@ -0,0 +1,90 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const accordion = (skin: Skin): Theme['components'] => ({ + MuiAccordion: { + defaultProps: { + ...(skin === 'bordered' && { + variant: 'outlined' + }) + }, + styleOverrides: { + root: ({ theme }) => ({ + transition: theme.transitions.create(['margin', 'border-radius', 'box-shadow']), + ...(skin !== 'bordered' + ? { + boxShadow: 'var(--mui-customShadows-xs)' + } + : { + '&:not(.Mui-expanded) + &:not(.Mui-expanded)': { + borderBlockStart: 0 + }, + '&:not(.Mui-expanded):has(+ &:not(.Mui-expanded))': { + borderBlockEnd: 0 + } + }), + '&:not(.Mui-expanded):has(+ .Mui-expanded)': { + borderBottomLeftRadius: 'var(--mui-shape-borderRadius)', + borderBottomRightRadius: 'var(--mui-shape-borderRadius)' + }, + '&.Mui-expanded': { + borderRadius: 'var(--mui-shape-borderRadius)', + ...(skin !== 'bordered' && { + boxShadow: 'var(--mui-customShadows-md)' + }), + margin: theme.spacing(2, 0), + '& + .MuiAccordion-root': { + borderTopLeftRadius: 'var(--mui-shape-borderRadius)', + borderTopRightRadius: 'var(--mui-shape-borderRadius)', + '&:before': { + opacity: 0 + } + } + } + }) + } + }, + MuiAccordionSummary: { + defaultProps: { + expandIcon: + }, + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(3, 5), + color: 'var(--mui-palette-text-primary)', + '&.Mui-expanded': { + minHeight: 48 + }, + '& .MuiTypography-root': { + color: 'inherit', + fontWeight: theme.typography.fontWeightMedium + } + }), + content: { + margin: '0 !important' + }, + expandIconWrapper: { + color: 'var(--mui-palette-text-primary)', + fontSize: '1.25rem', + '& i, & svg': { + fontSize: 'inherit' + } + } + } + }, + MuiAccordionDetails: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(0, 5, 5), + '& .MuiTypography-root': { + color: 'var(--mui-palette-text-secondary)' + } + }) + } + } +}) + +export default accordion diff --git a/front-urban/src/@core/theme/overrides/alerts.tsx b/front-urban/src/@core/theme/overrides/alerts.tsx new file mode 100644 index 0000000..ddd0d1e --- /dev/null +++ b/front-urban/src/@core/theme/overrides/alerts.tsx @@ -0,0 +1,179 @@ +// React Imports +import React from 'react' + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const alerts: Theme['components'] = { + MuiAlert: { + defaultProps: { + iconMapping: { + error: , + warning: , + info: , + success: + } + }, + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(4), + gap: theme.spacing(4), + ...theme.typography.body1, + '&:not(:has(.MuiAlertTitle-root))': { + '& .MuiAlert-icon + .MuiAlert-message': { + alignSelf: 'center' + } + } + }), + icon: { + padding: 0, + margin: 0, + minWidth: 30, + height: 30, + borderRadius: 'var(--mui-shape-borderRadius)', + alignItems: 'center', + justifyContent: 'center', + '& i, & svg': { + fontSize: 'inherit' + } + }, + message: { + padding: 0 + }, + action: { + padding: 0, + marginRight: 0 + } + }, + variants: [ + { + props: { variant: 'standard', severity: 'error' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-error-main)', + color: 'var(--mui-palette-error-contrastText)' + } + } + }, + { + props: { variant: 'standard', severity: 'warning' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-warning-main)', + color: 'var(--mui-palette-warning-contrastText)' + } + } + }, + { + props: { variant: 'standard', severity: 'info' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-info-main)', + color: 'var(--mui-palette-info-contrastText)' + } + } + }, + { + props: { variant: 'standard', severity: 'success' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-success-main)', + color: 'var(--mui-palette-success-contrastText)' + } + } + }, + { + props: { variant: 'outlined', severity: 'error' }, + style: { + borderColor: 'var(--mui-palette-error-main)', + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-error-mainOpacity)', + color: 'var(--mui-palette-error-main)' + } + } + }, + { + props: { variant: 'outlined', severity: 'warning' }, + style: { + borderColor: 'var(--mui-palette-warning-main)', + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-warning-mainOpacity)', + color: 'var(--mui-palette-warning-main)' + } + } + }, + { + props: { variant: 'outlined', severity: 'info' }, + style: { + borderColor: 'var(--mui-palette-info-main)', + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-info-mainOpacity)', + color: 'var(--mui-palette-info-main)' + } + } + }, + { + props: { variant: 'outlined', severity: 'success' }, + style: { + borderColor: 'var(--mui-palette-success-main)', + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-success-mainOpacity)', + color: 'var(--mui-palette-success-main)' + } + } + }, + { + props: { variant: 'filled', severity: 'error' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-common-white)', + color: 'var(--mui-palette-error-main)', + boxShadow: 'var(--mui-customShadows-xs)' + } + } + }, + { + props: { variant: 'filled', severity: 'warning' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-common-white)', + color: 'var(--mui-palette-warning-main)', + boxShadow: 'var(--mui-customShadows-xs)' + } + } + }, + { + props: { variant: 'filled', severity: 'info' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-common-white)', + color: 'var(--mui-palette-info-main)', + boxShadow: 'var(--mui-customShadows-xs)' + } + } + }, + { + props: { variant: 'filled', severity: 'success' }, + style: { + '& .MuiAlert-icon': { + backgroundColor: 'var(--mui-palette-common-white)', + color: 'var(--mui-palette-success-main)', + boxShadow: 'var(--mui-customShadows-xs)' + } + } + } + ] + }, + MuiAlertTitle: { + styleOverrides: { + root: ({ theme }) => ({ + ...theme.typography.h5, + marginTop: 0, + marginBottom: theme.spacing(1), + color: 'inherit' + }) + } + } +} + +export default alerts diff --git a/front-urban/src/@core/theme/overrides/autocomplete.tsx b/front-urban/src/@core/theme/overrides/autocomplete.tsx new file mode 100644 index 0000000..b3589ae --- /dev/null +++ b/front-urban/src/@core/theme/overrides/autocomplete.tsx @@ -0,0 +1,76 @@ +// React Imports +import React from 'react' + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const autocomplete = (skin: Skin): Theme['components'] => ({ + MuiAutocomplete: { + defaultProps: { + ...(skin === 'bordered' && { + slotProps: { + paper: { + variant: 'outlined' + } + } + }), + ChipProps: { + size: 'small' + }, + popupIcon: + }, + styleOverrides: { + root: { + '& .MuiButtonBase-root.Mui-disabled i, & .MuiButtonBase-root.Mui-disabled svg': { + color: 'var(--mui-palette-action-disabled)' + }, + '& .MuiOutlinedInput-input': { + height: '1.4375em' + } + }, + input: { + '& + .MuiAutocomplete-endAdornment': { + right: '1rem', + '& i, & svg': { + fontSize: '1.5rem', + color: 'var(--mui-palette-text-primary)' + }, + '& .MuiAutocomplete-clearIndicator': { + padding: 2 + } + }, + '&.MuiInputBase-inputSizeSmall + .MuiAutocomplete-endAdornment': { + '& i, & svg': { + fontSize: '1.375rem' + } + } + }, + paper: { + ...(skin !== 'bordered' && { + boxShadow: 'var(--mui-customShadows-lg)', + marginBlockStart: '0.125rem' + }) + }, + listbox: ({ theme }) => ({ + '& .MuiAutocomplete-option': { + padding: theme.spacing(2, 5), + '&[aria-selected="true"]': { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)', + '&.Mui-focused, &.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-primary-mainOpacity)' + } + } + }, + '& .MuiAutocomplete-option.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-action-hover)' + } + }) + } + } +}) + +export default autocomplete diff --git a/front-urban/src/@core/theme/overrides/avatar.ts b/front-urban/src/@core/theme/overrides/avatar.ts new file mode 100644 index 0000000..512a048 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/avatar.ts @@ -0,0 +1,38 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const avatar: Theme['components'] = { + MuiAvatarGroup: { + styleOverrides: { + root: ({ theme }) => ({ + justifyContent: 'flex-end', + '& .MuiAvatar-root': { + borderColor: 'var(--mui-palette-background-paper)' + }, + '&.pull-up .MuiAvatar-root': { + cursor: 'pointer', + transition: theme.transitions.create(['box-shadow', 'transform'], { + easing: 'ease', + duration: theme.transitions.duration.shorter + }), + '&:hover': { + zIndex: 2, + boxShadow: 'var(--mui-customShadows-md)', + transform: 'translateY(-5px)' + } + } + }) + } + }, + MuiAvatar: { + styleOverrides: { + root: ({ theme }) => ({ + color: 'var(--mui-palette-text-primary)', + fontSize: theme.typography.body1.fontSize, + lineHeight: 1.2 + }) + } + } +} + +export default avatar diff --git a/front-urban/src/@core/theme/overrides/backdrop.ts b/front-urban/src/@core/theme/overrides/backdrop.ts new file mode 100644 index 0000000..7a596aa --- /dev/null +++ b/front-urban/src/@core/theme/overrides/backdrop.ts @@ -0,0 +1,16 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const backdrop: Theme['components'] = { + MuiBackdrop: { + styleOverrides: { + root: { + '&:not(.MuiBackdrop-invisible)': { + backgroundColor: 'var(--backdrop-color)' + } + } + } + } +} + +export default backdrop diff --git a/front-urban/src/@core/theme/overrides/badges.ts b/front-urban/src/@core/theme/overrides/badges.ts new file mode 100644 index 0000000..e8b913e --- /dev/null +++ b/front-urban/src/@core/theme/overrides/badges.ts @@ -0,0 +1,19 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const badges: Theme['components'] = { + MuiBadge: { + styleOverrides: { + standard: ({ theme }) => ({ + height: 22, + minWidth: 22, + borderRadius: 20, + fontSize: theme.typography.subtitle2.fontSize, + lineHeight: 1.07, + padding: theme.spacing(1, 2) + }) + } + } +} + +export default badges diff --git a/front-urban/src/@core/theme/overrides/breadcrumbs.ts b/front-urban/src/@core/theme/overrides/breadcrumbs.ts new file mode 100644 index 0000000..01fd338 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/breadcrumbs.ts @@ -0,0 +1,29 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const breadcrumbs: Theme['components'] = { + MuiBreadcrumbs: { + styleOverrides: { + root: { + '& svg, & i': { + fontSize: '1.25rem' + }, + '& a': { + textDecoration: 'none', + color: 'var(--mui-palette-text-secondary)', + '&:hover': { + color: 'var(--mui-palette-text-primary)' + } + } + }, + li: ({ theme }) => ({ + lineHeight: theme.typography.body1.lineHeight, + '& > *:not(a)': { + color: 'var(--mui-palette-text-primary)' + } + }) + } + } +} + +export default breadcrumbs diff --git a/front-urban/src/@core/theme/overrides/button-group.ts b/front-urban/src/@core/theme/overrides/button-group.ts new file mode 100644 index 0000000..869e890 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/button-group.ts @@ -0,0 +1,73 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +const buttonGroup: Theme['components'] = { + MuiButtonGroup: { + defaultProps: { + disableRipple: themeConfig.disableRipple + }, + styleOverrides: { + contained: ({ ownerState }) => ({ + boxShadow: 'var(--mui-customShadows-xs)', + ...(ownerState.disabled && { + boxShadow: 'none' + }) + }) + }, + variants: [ + { + props: { variant: 'text', color: 'primary' }, + style: { + '& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': { + borderColor: 'var(--mui-palette-primary-main)' + } + } + }, + { + props: { variant: 'text', color: 'secondary' }, + style: { + '& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': { + borderColor: 'var(--mui-palette-secondary-main)' + } + } + }, + { + props: { variant: 'text', color: 'error' }, + style: { + '& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': { + borderColor: 'var(--mui-palette-error-main)' + } + } + }, + { + props: { variant: 'text', color: 'warning' }, + style: { + '& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': { + borderColor: 'var(--mui-palette-warning-main)' + } + } + }, + { + props: { variant: 'text', color: 'info' }, + style: { + '& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': { + borderColor: 'var(--mui-palette-info-main)' + } + } + }, + { + props: { variant: 'text', color: 'success' }, + style: { + '& .MuiButtonGroup-firstButton, & .MuiButtonGroup-middleButton': { + borderColor: 'var(--mui-palette-success-main)' + } + } + } + ] + } +} + +export default buttonGroup diff --git a/front-urban/src/@core/theme/overrides/button.ts b/front-urban/src/@core/theme/overrides/button.ts new file mode 100644 index 0000000..d43a3c9 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/button.ts @@ -0,0 +1,377 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +const iconStyles = (size?: string) => ({ + '& > *:nth-of-type(1)': { + ...(size === 'small' + ? { + fontSize: '14px' + } + : { + ...(size === 'medium' + ? { + fontSize: '16px' + } + : { + fontSize: '20px' + }) + }) + } +}) + +const button: Theme['components'] = { + MuiButtonBase: { + defaultProps: { + disableRipple: themeConfig.disableRipple + } + }, + MuiButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + ...(ownerState.variant === 'text' + ? { + ...(ownerState.size === 'small' && { + padding: theme.spacing(2, 2.5) + }), + ...(ownerState.size === 'medium' && { + padding: theme.spacing(2, 3.5) + }), + ...(ownerState.size === 'large' && { + padding: theme.spacing(2, 4.5) + }) + } + : { + ...(ownerState.variant === 'outlined' + ? { + ...(ownerState.size === 'small' && { + padding: theme.spacing(1.75, 3.25) + }), + ...(ownerState.size === 'medium' && { + padding: theme.spacing(1.75, 4.25) + }), + ...(ownerState.size === 'large' && { + padding: theme.spacing(1.75, 5.25) + }) + } + : { + ...(ownerState.size === 'small' && { + padding: theme.spacing(2, 3.5) + }), + ...(ownerState.size === 'medium' && { + padding: theme.spacing(2, 4.5) + }), + ...(ownerState.size === 'large' && { + padding: theme.spacing(2, 5.5) + }) + }) + }) + }), + contained: ({ ownerState }) => ({ + boxShadow: 'var(--mui-customShadows-xs)', + ...(!ownerState.disabled && { + '&:hover, &.Mui-focusVisible': { + boxShadow: 'var(--mui-customShadows-xs)' + }, + '&:active': { + boxShadow: 'none' + } + }) + }), + sizeSmall: ({ theme }) => ({ + lineHeight: 1.38462, + fontSize: theme.typography.body2.fontSize, + borderRadius: 'var(--mui-shape-customBorderRadius-sm)' + }), + sizeLarge: { + fontSize: '1.0625rem', + lineHeight: 1.529412, + borderRadius: 'var(--mui-shape-customBorderRadius-lg)' + }, + startIcon: ({ theme, ownerState }) => ({ + ...(ownerState.size === 'small' + ? { + marginInlineEnd: theme.spacing(1.5) + } + : { + ...(ownerState.size === 'medium' + ? { + marginInlineEnd: theme.spacing(2) + } + : { + marginInlineEnd: theme.spacing(2.5) + }) + }), + ...iconStyles(ownerState.size) + }), + endIcon: ({ theme, ownerState }) => ({ + ...(ownerState.size === 'small' + ? { + marginInlineStart: theme.spacing(1.5) + } + : { + ...(ownerState.size === 'medium' + ? { + marginInlineStart: theme.spacing(2) + } + : { + marginInlineStart: theme.spacing(2.5) + }) + }), + ...iconStyles(ownerState.size) + }) + }, + variants: [ + { + props: { variant: 'text', color: 'primary' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-primary-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-primary-main)' + } + } + }, + { + props: { variant: 'text', color: 'secondary' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-secondary-main)' + } + } + }, + { + props: { variant: 'text', color: 'error' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-error-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-error-main)' + } + } + }, + { + props: { variant: 'text', color: 'warning' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-warning-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-warning-main)' + } + } + }, + { + props: { variant: 'text', color: 'info' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-info-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-info-main)' + } + } + }, + { + props: { variant: 'text', color: 'success' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-success-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-success-main)' + } + } + }, + { + props: { variant: 'outlined', color: 'primary' }, + style: { + borderColor: 'var(--mui-palette-primary-main)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-primary-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-primary-main)', + borderColor: 'var(--mui-palette-primary-main)' + } + } + }, + { + props: { variant: 'outlined', color: 'secondary' }, + style: { + borderColor: 'var(--mui-palette-secondary-main)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-secondary-main)', + borderColor: 'var(--mui-palette-secondary-main)' + } + } + }, + { + props: { variant: 'outlined', color: 'error' }, + style: { + borderColor: 'var(--mui-palette-error-main)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-error-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-error-main)', + borderColor: 'var(--mui-palette-error-main)' + } + } + }, + { + props: { variant: 'outlined', color: 'warning' }, + style: { + borderColor: 'var(--mui-palette-warning-main)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-warning-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-warning-main)', + borderColor: 'var(--mui-palette-warning-main)' + } + } + }, + { + props: { variant: 'outlined', color: 'info' }, + style: { + borderColor: 'var(--mui-palette-info-main)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-info-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-info-main)', + borderColor: 'var(--mui-palette-info-main)' + } + } + }, + { + props: { variant: 'outlined', color: 'success' }, + style: { + borderColor: 'var(--mui-palette-success-main)', + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': + { + backgroundColor: 'var(--mui-palette-success-lighterOpacity)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-success-main)', + borderColor: 'var(--mui-palette-success-main)' + } + } + }, + { + props: { variant: 'contained', color: 'primary' }, + style: { + '&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-primary-dark)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-primary-contrastText)', + backgroundColor: 'var(--mui-palette-primary-main)' + } + } + }, + { + props: { variant: 'contained', color: 'secondary' }, + style: { + '&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-secondary-dark)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-secondary-contrastText)', + backgroundColor: 'var(--mui-palette-secondary-main)' + } + } + }, + { + props: { variant: 'contained', color: 'error' }, + style: { + '&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-error-dark)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-error-contrastText)', + backgroundColor: 'var(--mui-palette-error-main)' + } + } + }, + { + props: { variant: 'contained', color: 'warning' }, + style: { + '&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-warning-dark)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-warning-contrastText)', + backgroundColor: 'var(--mui-palette-warning-main)' + } + } + }, + { + props: { variant: 'contained', color: 'info' }, + style: { + '&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-info-dark)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-info-contrastText)', + backgroundColor: 'var(--mui-palette-info-main)' + } + } + }, + { + props: { variant: 'contained', color: 'success' }, + style: { + '&:not(.Mui-disabled):active, &.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-success-dark)' + }, + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-success-contrastText)', + backgroundColor: 'var(--mui-palette-success-main)' + } + } + } + ] + } +} + +export default button diff --git a/front-urban/src/@core/theme/overrides/card.ts b/front-urban/src/@core/theme/overrides/card.ts new file mode 100644 index 0000000..393ffa8 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/card.ts @@ -0,0 +1,91 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const card = (skin: Skin): Theme['components'] => { + return { + MuiCard: { + defaultProps: { + ...(skin === 'bordered' && { + variant: 'outlined' + }) + }, + styleOverrides: { + root: ({ ownerState }) => ({ + ...(ownerState.variant !== 'outlined' && { + boxShadow: 'var(--mui-customShadows-md)' + }) + }) + } + }, + MuiCardHeader: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(5), + '& + .MuiCardContent-root, & + .MuiCardActions-root': { + paddingBlockStart: 0 + }, + '& + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child': + { + paddingBlockStart: 0 + } + }), + subheader: ({ theme }) => ({ + ...theme.typography.subtitle1, + color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' + }), + action: ({ theme }) => ({ + ...theme.typography.body1, + color: 'var(--mui-palette-text-disabled)', + marginBlock: 0, + marginInlineEnd: 0, + '& .MuiIconButton-root': { + color: 'inherit' + } + }) + } + }, + MuiCardContent: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(5), + color: 'var(--mui-palette-text-secondary)', + '&:last-child': { + paddingBlockEnd: theme.spacing(5) + }, + '& + .MuiCardHeader-root, & + .MuiCardContent-root, & + .MuiCardActions-root': { + paddingBlockStart: 0 + }, + '& + .MuiCollapse-root .MuiCardHeader-root:first-child, & + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child': + { + paddingBlockStart: 0 + } + }) + } + }, + MuiCardActions: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(5), + '&:where(.card-actions-dense)': { + padding: theme.spacing(2.5), + '& .MuiButton-text': { + paddingInline: theme.spacing(2.5) + } + }, + '& + .MuiCardHeader-root, & + .MuiCardContent-root, & + .MuiCardActions-root': { + paddingBlockStart: 0 + }, + '& + .MuiCollapse-root .MuiCardHeader-root:first-child, & + .MuiCollapse-root .MuiCardContent-root:first-child, & + .MuiCollapse-root .MuiCardActions-root:first-child': + { + paddingBlockStart: 0 + } + }) + } + } + } +} + +export default card diff --git a/front-urban/src/@core/theme/overrides/checkbox.tsx b/front-urban/src/@core/theme/overrides/checkbox.tsx new file mode 100644 index 0000000..058cad1 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/checkbox.tsx @@ -0,0 +1,94 @@ +// React Imports +import React from 'react' + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const Icon = () => { + return ( + + + + ) +} + +const IndeterminateIcon = () => { + return ( + + + + + ) +} + +const CheckedIcon = () => { + return ( + + + + + ) +} + +const checkbox: Theme['components'] = { + MuiCheckbox: { + defaultProps: { + icon: , + indeterminateIcon: , + checkedIcon: + }, + styleOverrides: { + root: ({ theme, ownerState }) => ({ + ...(ownerState.size === 'small' + ? { + padding: theme.spacing(1), + '& svg': { + fontSize: '1.25rem' + } + } + : { + padding: theme.spacing(1.5), + '& svg': { + fontSize: '1.5rem' + } + }), + '&.Mui-checked:not(.Mui-disabled) svg': { + filter: 'drop-shadow(var(--mui-customShadows-xs))' + }, + '&.Mui-disabled': { + opacity: 0.45, + '&:not(.Mui-checked)': { + color: 'var(--mui-palette-text-secondary)' + }, + '&.Mui-checked.MuiCheckbox-colorPrimary': { + color: 'var(--mui-palette-primary-main)' + }, + '&.Mui-checked.MuiCheckbox-colorSecondary': { + color: 'var(--mui-palette-secondary-main)' + }, + '&.Mui-checked.MuiCheckbox-colorError': { + color: 'var(--mui-palette-error-main)' + }, + '&.Mui-checked.MuiCheckbox-colorWarning': { + color: 'var(--mui-palette-warning-main)' + }, + '&.Mui-checked.MuiCheckbox-colorInfo': { + color: 'var(--mui-palette-info-main)' + }, + '&.Mui-checked.MuiCheckbox-colorSuccess': { + color: 'var(--mui-palette-success-main)' + } + } + }) + } + } +} + +export default checkbox diff --git a/front-urban/src/@core/theme/overrides/chip.ts b/front-urban/src/@core/theme/overrides/chip.ts new file mode 100644 index 0000000..f7e1e8c --- /dev/null +++ b/front-urban/src/@core/theme/overrides/chip.ts @@ -0,0 +1,190 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const chip: Theme['components'] = { + MuiChip: { + variants: [ + { + props: { variant: 'tonal', color: 'primary' }, + style: { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)', + '&.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-primary-mainOpacity)' + }, + '& .MuiChip-deleteIcon': { + color: 'rgb(var(--mui-palette-primary-mainChannel) / 0.7)', + '&:hover': { + color: 'var(--mui-palette-primary-main)' + } + }, + '&.MuiChip-clickable:hover': { + backgroundColor: 'var(--mui-palette-primary-main)', + color: 'var(--mui-palette-common-white)' + } + } + }, + { + props: { variant: 'tonal', color: 'secondary' }, + style: { + backgroundColor: 'var(--mui-palette-secondary-lightOpacity)', + color: 'var(--mui-palette-secondary-main)', + '&.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-secondary-mainOpacity)' + }, + '& .MuiChip-deleteIcon': { + color: 'rgb(var(--mui-palette-secondary-mainChannel) / 0.7)', + '&:hover': { + color: 'var(--mui-palette-secondary-main)' + } + }, + '&.MuiChip-clickable:hover': { + backgroundColor: 'var(--mui-palette-secondary-main)', + color: 'var(--mui-palette-common-white)' + } + } + }, + { + props: { variant: 'tonal', color: 'error' }, + style: { + backgroundColor: 'var(--mui-palette-error-lightOpacity)', + color: 'var(--mui-palette-error-main)', + '&.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-error-mainOpacity)' + }, + '& .MuiChip-deleteIcon': { + color: 'rgb(var(--mui-palette-error-mainChannel) / 0.7)', + '&:hover': { + color: 'var(--mui-palette-error-main)' + } + }, + '&.MuiChip-clickable:hover': { + backgroundColor: 'var(--mui-palette-error-main)', + color: 'var(--mui-palette-common-white)' + } + } + }, + { + props: { variant: 'tonal', color: 'warning' }, + style: { + backgroundColor: 'var(--mui-palette-warning-lightOpacity)', + color: 'var(--mui-palette-warning-main)', + '&.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-warning-mainOpacity)' + }, + '& .MuiChip-deleteIcon': { + color: 'rgb(var(--mui-palette-warning-mainChannel) / 0.7)', + '&:hover': { + color: 'var(--mui-palette-warning-main)' + } + }, + '&.MuiChip-clickable:hover': { + backgroundColor: 'var(--mui-palette-warning-main)', + color: 'var(--mui-palette-common-white)' + } + } + }, + { + props: { variant: 'tonal', color: 'info' }, + style: { + backgroundColor: 'var(--mui-palette-info-lightOpacity)', + color: 'var(--mui-palette-info-main)', + '&.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-info-mainOpacity)' + }, + '& .MuiChip-deleteIcon': { + color: 'rgb(var(--mui-palette-info-mainChannel) / 0.7)', + '&:hover': { + color: 'var(--mui-palette-info-main)' + } + }, + '&.MuiChip-clickable:hover': { + backgroundColor: 'var(--mui-palette-info-main)', + color: 'var(--mui-palette-common-white)' + } + } + }, + { + props: { variant: 'tonal', color: 'success' }, + style: { + backgroundColor: 'var(--mui-palette-success-lightOpacity)', + color: 'var(--mui-palette-success-main)', + '&.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-success-mainOpacity)' + }, + '& .MuiChip-deleteIcon': { + color: 'rgb(var(--mui-palette-success-mainChannel) / 0.7)', + '&:hover': { + color: 'var(--mui-palette-success-main)' + } + }, + '&.MuiChip-clickable:hover': { + backgroundColor: 'var(--mui-palette-success-main)', + color: 'var(--mui-palette-common-white)' + } + } + } + ], + styleOverrides: { + root: ({ ownerState, theme }) => ({ + ...theme.typography.body2, + fontWeight: theme.typography.fontWeightMedium, + + '& .MuiChip-deleteIcon': { + ...(ownerState.size === 'small' + ? { + fontSize: '1rem', + marginInlineEnd: theme.spacing(1), + marginInlineStart: theme.spacing(-2) + } + : { + fontSize: '1.25rem', + marginInlineEnd: theme.spacing(2), + marginInlineStart: theme.spacing(-3) + }) + }, + '& .MuiChip-avatar, & .MuiChip-icon': { + '& i, & svg': { + ...(ownerState.size === 'small' + ? { + fontSize: 13 + } + : { + fontSize: 15 + }) + }, + ...(ownerState.size === 'small' + ? { + height: 16, + width: 16, + marginInlineStart: theme.spacing(1), + marginInlineEnd: theme.spacing(-2) + } + : { + height: 20, + width: 20, + marginInlineStart: theme.spacing(2), + marginInlineEnd: theme.spacing(-3) + }) + } + }), + label: ({ ownerState, theme }) => ({ + ...(ownerState.size === 'small' + ? { + paddingInline: theme.spacing(3) + } + : { + paddingInline: theme.spacing(4) + }) + }), + iconMedium: { + fontSize: '1.25rem' + }, + iconSmall: { + fontSize: '1rem' + } + } + } +} + +export default chip diff --git a/front-urban/src/@core/theme/overrides/dialog.ts b/front-urban/src/@core/theme/overrides/dialog.ts new file mode 100644 index 0000000..9287879 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/dialog.ts @@ -0,0 +1,67 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const dialog = (skin: Skin): Theme['components'] => ({ + MuiDialog: { + styleOverrides: { + paper: ({ theme }) => ({ + ...(skin !== 'bordered' + ? { + boxShadow: 'var(--mui-customShadows-xl)' + } + : { + boxShadow: 'none' + }), + [theme.breakpoints.down('sm')]: { + '&:not(.MuiDialog-paperFullScreen)': { + margin: theme.spacing(6) + } + } + }) + } + }, + MuiDialogTitle: { + defaultProps: { + variant: 'h5' + }, + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(5), + '& + .MuiDialogActions-root': { + paddingTop: 0 + } + }) + } + }, + MuiDialogContent: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(5), + '& + .MuiDialogContent-root, & + .MuiDialogActions-root': { + paddingTop: 0 + } + }) + } + }, + MuiDialogActions: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(5), + '& .MuiButtonBase-root:not(:first-of-type)': { + marginInlineStart: theme.spacing(4) + }, + '&:where(.dialog-actions-dense)': { + padding: theme.spacing(2.5), + '& .MuiButton-text': { + paddingInline: theme.spacing(2.5) + } + } + }) + } + } +}) + +export default dialog diff --git a/front-urban/src/@core/theme/overrides/drawer.ts b/front-urban/src/@core/theme/overrides/drawer.ts new file mode 100644 index 0000000..6a90b55 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/drawer.ts @@ -0,0 +1,26 @@ +// MUI Imports +import type { Theme } from '@mui/material' + +// Type Imports +import type { Skin } from '@core/types' + +const drawer = (skin: Skin): Theme['components'] => ({ + MuiDrawer: { + defaultProps: { + ...(skin === 'bordered' && { + PaperProps: { + elevation: 0 + } + }) + }, + styleOverrides: { + paper: { + ...(skin !== 'bordered' && { + boxShadow: 'var(--mui-customShadows-lg)' + }) + } + } + } +}) + +export default drawer diff --git a/front-urban/src/@core/theme/overrides/fab.ts b/front-urban/src/@core/theme/overrides/fab.ts new file mode 100644 index 0000000..b081721 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/fab.ts @@ -0,0 +1,68 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const fab: Theme['components'] = { + MuiFab: { + variants: [ + { + props: { color: 'default' }, + style: { + color: 'rgb(var(--mui-mainColorChannels-light) / 0.9)', + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-grey-A100)' + } + } + }, + { + props: { color: 'primary' }, + style: { + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-primary-dark)' + } + } + }, + { + props: { color: 'secondary' }, + style: { + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-secondary-dark)' + } + } + }, + { + props: { color: 'error' }, + style: { + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-error-dark)' + } + } + }, + { + props: { color: 'warning' }, + style: { + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-warning-dark)' + } + } + }, + { + props: { color: 'info' }, + style: { + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-info-dark)' + } + } + }, + { + props: { color: 'success' }, + style: { + '&.Mui-focusVisible:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'var(--mui-palette-success-dark)' + } + } + } + ] + } +} + +export default fab diff --git a/front-urban/src/@core/theme/overrides/form-control-label.ts b/front-urban/src/@core/theme/overrides/form-control-label.ts new file mode 100644 index 0000000..fb6a503 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/form-control-label.ts @@ -0,0 +1,22 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const formControlLabel: Theme['components'] = { + MuiFormControlLabel: { + styleOverrides: { + root: ({ theme }) => ({ + marginInlineStart: theme.spacing(-2) + }), + label: { + '&, &.Mui-disabled': { + color: 'var(--mui-palette-text-primary)' + }, + '&.Mui-disabled': { + opacity: 0.45 + } + } + } + } +} + +export default formControlLabel diff --git a/front-urban/src/@core/theme/overrides/icon-button.ts b/front-urban/src/@core/theme/overrides/icon-button.ts new file mode 100644 index 0000000..18f9975 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/icon-button.ts @@ -0,0 +1,140 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +const iconButton: Theme['components'] = { + MuiIconButton: { + styleOverrides: { + root: { + '& .MuiSvgIcon-root, & i, & svg': { + fontSize: 'inherit' + } + }, + sizeSmall: ({ theme }) => ({ + padding: theme.spacing(1.75), + fontSize: '1.25rem' + }), + sizeMedium: ({ theme }) => ({ + padding: theme.spacing(2), + fontSize: '1.375rem' + }), + sizeLarge: ({ theme }) => ({ + padding: theme.spacing(2.25), + fontSize: '1.5rem' + }) + }, + variants: [ + { + props: { color: 'default' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { + backgroundColor: 'rgb(var(--mui-palette-text-primaryChannel) / 0.08)' + } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-action-active)' + } + } + }, + { + props: { color: 'primary' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'var(--mui-palette-primary-lighterOpacity)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-primary-lighterOpacity)' } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-primary-main)' + } + } + }, + { + props: { color: 'secondary' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-secondary-lighterOpacity)' } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-secondary-main)' + } + } + }, + { + props: { color: 'error' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'var(--mui-palette-error-lighterOpacity)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-error-lighterOpacity)' } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-error-main)' + } + } + }, + { + props: { color: 'warning' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'var(--mui-palette-warning-lighterOpacity)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-warning-lighterOpacity)' } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-warning-main)' + } + } + }, + { + props: { color: 'info' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'var(--mui-palette-info-lighterOpacity)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-info-lighterOpacity)' } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-info-main)' + } + } + }, + { + props: { color: 'success' }, + style: { + '&:not(.Mui-disabled):hover, &:not(.Mui-disabled):active': { + backgroundColor: 'var(--mui-palette-success-lighterOpacity)' + }, + ...(themeConfig.disableRipple && { + '&.Mui-focusVisible:not(.Mui-disabled)': { backgroundColor: 'var(--mui-palette-success-lighterOpacity)' } + }), + '&.Mui-disabled': { + opacity: 0.45, + color: 'var(--mui-palette-success-main)' + } + } + } + ] + } +} + +export default iconButton diff --git a/front-urban/src/@core/theme/overrides/index.ts b/front-urban/src/@core/theme/overrides/index.ts new file mode 100644 index 0000000..bfa7f9f --- /dev/null +++ b/front-urban/src/@core/theme/overrides/index.ts @@ -0,0 +1,83 @@ +// Override Imports +import Accordion from './accordion' +import Alerts from './alerts' +import Autocomplete from './autocomplete' +import avatar from './avatar' +import backdrop from './backdrop' +import badges from './badges' +import breadcrumbs from './breadcrumbs' +import button from './button' +import buttonGroup from './button-group' +import card from './card' +import Checkbox from './checkbox' +import chip from './chip' +import dialog from './dialog' +import drawer from './drawer' +import fab from './fab' +import formControlLabel from './form-control-label' +import iconButton from './icon-button' +import input from './input' +import list from './list' +import menu from './menu' +import pagination from './pagination' +import paper from './paper' +import popover from './popover' +import progress from './progress' +import Radio from './radio' +import Rating from './rating' +import Select from './select' +import slider from './slider' +import snackbar from './snackbar' +import switchOverrides from './switch' +import tablePagination from './table-pagination' +import tabs from './tabs' +import timeline from './timeline' +import toggleButton from './toggle-button' +import tooltip from './tooltip' +import typography from './typography' + +const overrides = () => { + const skin = 'default' + + return Object.assign( + {}, + Accordion(skin), + Alerts, + Autocomplete(skin), + avatar, + backdrop, + badges, + breadcrumbs, + button, + buttonGroup, + card(skin), + Checkbox, + chip, + dialog(skin), + drawer(skin), + fab, + formControlLabel, + iconButton, + input, + list, + menu(skin), + pagination, + paper, + popover(skin), + progress, + Radio, + Rating, + Select, + slider, + snackbar(skin), + switchOverrides, + tablePagination, + tabs, + timeline, + toggleButton, + tooltip, + typography + ) +} + +export default overrides diff --git a/front-urban/src/@core/theme/overrides/input.ts b/front-urban/src/@core/theme/overrides/input.ts new file mode 100644 index 0000000..1fc22c6 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/input.ts @@ -0,0 +1,112 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const input: Theme['components'] = { + MuiFormControl: { + styleOverrides: { + root: { + '&:has(.MuiRadio-root) .MuiFormHelperText-root, &:has(.MuiCheckbox-root) .MuiFormHelperText-root, &:has(.MuiSwitch-root) .MuiFormHelperText-root': + { + marginInline: 0 + } + } + } + }, + MuiInputBase: { + styleOverrides: { + root: { + lineHeight: 1.6, + '&.MuiInput-underline': { + '&:before': { + borderColor: 'var(--mui-palette-customColors-inputBorder)' + }, + '&:not(.Mui-disabled, .Mui-error):hover:before': { + borderColor: 'var(--mui-palette-action-active)' + } + }, + '&.Mui-disabled .MuiInputAdornment-root, &.Mui-disabled .MuiInputAdornment-root > *': { + color: 'var(--mui-palette-action-disabled)' + } + } + } + }, + MuiFilledInput: { + styleOverrides: { + root: { + '&:before': { + borderBottom: '1px solid var(--mui-palette-text-secondary)' + }, + '&.Mui-disabled:before': { + borderBottomStyle: 'solid' + } + } + } + }, + MuiInputLabel: { + styleOverrides: { + shrink: ({ ownerState }) => ({ + ...(ownerState.variant === 'outlined' && { + color: 'var(--mui-palette-text-secondary)', + transform: 'translate(14px, -8px) scale(0.867)' + }), + ...(ownerState.variant === 'filled' && { + transform: 'translate(12px, 7px) scale(0.867)' + }), + ...(ownerState.variant === 'standard' && { + transform: 'translate(0, -1.5px) scale(0.867)' + }) + }) + } + }, + MuiOutlinedInput: { + styleOverrides: { + root: { + '&:not(.Mui-focused):not(.Mui-error):not(.Mui-disabled):hover .MuiOutlinedInput-notchedOutline': { + borderColor: 'var(--mui-palette-action-active)' + }, + '&.Mui-disabled .MuiOutlinedInput-notchedOutline': { + borderColor: 'var(--mui-palette-action-disabledBackground)' + } + }, + input: ({ theme, ownerState }) => ({ + ...(ownerState?.size === 'medium' && { + '&:not(.MuiInputBase-inputMultiline, .MuiInputBase-inputAdornedStart)': { + paddingBlock: theme.spacing(4) + }, + height: '1.5em' + }), + '& ~ .MuiOutlinedInput-notchedOutline': { + borderColor: 'var(--mui-palette-customColors-inputBorder)' + } + }), + notchedOutline: { + '& legend': { + fontSize: '0.867em' + } + } + } + }, + MuiInputAdornment: { + styleOverrides: { + root: { + color: 'var(--mui-palette-text-primary)', + '& i, & svg': { + fontSize: '1.25rem' + }, + '& *': { + color: 'inherit !important' + } + } + } + }, + MuiFormHelperText: { + styleOverrides: { + root: { + lineHeight: 1, + letterSpacing: 'unset' + } + } + } +} + +export default input diff --git a/front-urban/src/@core/theme/overrides/list.ts b/front-urban/src/@core/theme/overrides/list.ts new file mode 100644 index 0000000..7ea45ae --- /dev/null +++ b/front-urban/src/@core/theme/overrides/list.ts @@ -0,0 +1,81 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const list: Theme['components'] = { + MuiListItem: { + styleOverrides: { + root: ({ theme }) => ({ + gap: theme.spacing(4) + }), + padding: ({ theme, ownerState }) => ({ + ...(!ownerState.dense && { + paddingBlock: theme.spacing(2), + paddingInlineStart: theme.spacing(5) + }) + }) + } + }, + MuiListItemAvatar: { + styleOverrides: { + root: { + minWidth: 'unset' + } + } + }, + MuiListItemIcon: { + styleOverrides: { + root: { + minWidth: 0, + color: 'var(--mui-palette-text-primary)', + fontSize: '1.375rem', + '& > svg, & > i': { + fontSize: 'inherit' + } + } + } + }, + MuiListItemButton: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + gap: theme.spacing(4), + ...(!ownerState.dense && { + paddingBlock: theme.spacing(2) + }), + paddingInlineStart: theme.spacing(5), + '&.Mui-selected': { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + '&:hover, &.Mui-focused, &.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-primary-mainOpacity)' + }, + '& .MuiTypography-root': { + color: 'var(--mui-palette-primary-main)' + }, + '& + .MuiListItemSecondaryAction-root .MuiIconButton-root': { + color: 'var(--mui-palette-primary-main)' + } + } + }) + } + }, + MuiListItemText: { + styleOverrides: { + root: { + margin: 0 + }, + primary: { + color: 'var(--mui-palette-text-primary)' + } + } + }, + MuiListSubheader: { + styleOverrides: { + root: ({ theme }) => ({ + ...theme.typography.subtitle2, + paddingBlock: 10, + paddingInline: theme.spacing(5) + }) + } + } +} + +export default list diff --git a/front-urban/src/@core/theme/overrides/menu.ts b/front-urban/src/@core/theme/overrides/menu.ts new file mode 100644 index 0000000..644e974 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/menu.ts @@ -0,0 +1,57 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const menu = (skin: Skin): Theme['components'] => ({ + MuiMenu: { + defaultProps: { + ...(skin === 'bordered' && { + slotProps: { + paper: { + elevation: 0 + } + } + }) + }, + styleOverrides: { + paper: ({ theme }) => ({ + marginBlockStart: theme.spacing(0.5), + ...(skin !== 'bordered' && { + boxShadow: 'var(--mui-customShadows-lg)' + }) + }) + } + }, + MuiMenuItem: { + styleOverrides: { + root: ({ theme }) => ({ + paddingBlock: theme.spacing(2), + color: 'var(--mui-palette-text-primary)', + '& i, & svg': { + fontSize: '1.375rem' + }, + '& .MuiListItemIcon-root': { + minInlineSize: 0 + }, + '&.Mui-selected': { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)', + '& .MuiListItemIcon-root': { + color: 'var(--mui-palette-primary-main)' + }, + '&:hover, &.Mui-focused, &.Mui-focusVisible': { + backgroundColor: 'var(--mui-palette-primary-mainOpacity)' + } + }, + '&.Mui-disabled': { + color: 'var(--mui-palette-text-disabled)', + opacity: 1 + } + }) + } + } +}) + +export default menu diff --git a/front-urban/src/@core/theme/overrides/pagination.ts b/front-urban/src/@core/theme/overrides/pagination.ts new file mode 100644 index 0000000..79f99ac --- /dev/null +++ b/front-urban/src/@core/theme/overrides/pagination.ts @@ -0,0 +1,172 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const pagination: Theme['components'] = { + MuiPagination: { + styleOverrides: { + ul: { + rowGap: 6 + } + }, + variants: [ + { + props: { variant: 'text', color: 'primary' }, + style: { + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + backgroundColor: 'var(--mui-palette-primary-main)', + color: 'var(--mui-palette-primary-contrastText)' + } + } + }, + { + props: { variant: 'text', color: 'secondary' }, + style: { + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + backgroundColor: 'var(--mui-palette-secondary-main)', + color: 'var(--mui-palette-secondary-contrastText)' + } + } + }, + { + props: { variant: 'outlined', color: 'standard' }, + style: { + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + borderColor: 'var(--mui-palette-action-selected)' + } + } + }, + { + props: { variant: 'outlined', color: 'primary' }, + style: { + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + color: 'var(--mui-palette-primary-main)', + backgroundColor: 'rgb(var(--mui-palette-primary-mainChannel) / var(--mui-palette-action-activatedOpacity))', + borderColor: 'rgba(var(--mui-palette-primary-mainChannel) / 0.5)' + } + } + }, + { + props: { variant: 'outlined', color: 'secondary' }, + style: { + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + color: 'var(--mui-palette-secondary-main)', + backgroundColor: + 'rgb(var(--mui-palette-secondary-mainChannel) / var(--mui-palette-action-activatedOpacity))', + borderColor: 'rgba(var(--mui-palette-secondary-mainChannel) / 0.5)' + } + } + }, + { + props: { variant: 'tonal' }, + style: { + '& .MuiPaginationItem-root:not(.MuiPaginationItem-ellipsis)': { + backgroundColor: 'var(--mui-palette-action-selected)' + } + } + }, + { + props: { variant: 'tonal', color: 'standard' }, + style: { + '& .MuiPaginationItem-root.Mui-selected': { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)', + '&:hover': { + backgroundColor: 'var(--mui-palette-primary-mainOpacity)' + } + }, + '& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': { + backgroundColor: 'var(--mui-palette-action-focus)' + }, + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)' + } + } + }, + { + props: { variant: 'tonal', color: 'primary' }, + style: { + '& .MuiPaginationItem-root.Mui-selected': { + backgroundColor: 'var(--mui-palette-primary-main)', + color: 'var(--mui-palette-primary-contrastText)', + '&:not(.Mui-disabled)': { + boxShadow: 'var(--mui-customShadows-xs)' + }, + '&:hover': { + backgroundColor: 'var(--mui-palette-primary-dark)' + } + }, + '& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)' + }, + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + backgroundColor: 'var(--mui-palette-primary-main)', + color: 'var(--mui-palette-primary-contrastText)' + } + } + }, + { + props: { variant: 'tonal', color: 'secondary' }, + style: { + '& .MuiPaginationItem-root.Mui-selected': { + backgroundColor: 'var(--mui-palette-secondary-main)', + color: 'var(--mui-palette-secondary-contrastText)', + '&:not(.Mui-disabled)': { + boxShadow: 'var(--mui-customShadows-xs)' + }, + '&:hover': { + backgroundColor: 'var(--mui-palette-secondary-dark)' + } + }, + '& .MuiPaginationItem-root:hover:not(.Mui-selected):not(.MuiPaginationItem-ellipsis)': { + backgroundColor: 'var(--mui-palette-secondary-mainOpacity)', + color: 'var(--mui-palette-secondary-main)' + }, + '& .MuiPaginationItem-root.Mui-selected.Mui-disabled': { + backgroundColor: 'var(--mui-palette-secondary-main)', + color: 'var(--mui-palette-secondary-contrastText)' + } + } + } + ] + }, + MuiPaginationItem: { + styleOverrides: { + root: ({ ownerState }) => ({ + ...(ownerState.size === 'medium' && { + height: '2.375rem', + minWidth: '2.375rem' + }), + ...(ownerState.shape !== 'rounded' && { + borderRadius: '50px' + }), + '&.Mui-selected.Mui-disabled': { + color: 'var(--mui-palette-text-primary)', + opacity: 0.45 + }, + '&.Mui-disabled': { + opacity: 0.45 + }, + ...(ownerState.shape === 'rounded' && + ownerState.size === 'small' && { + borderRadius: 'var(--mui-shape-customBorderRadius-sm)' + }), + ...(ownerState.shape === 'rounded' && + ownerState.size === 'large' && { + borderRadius: 'var(--mui-shape-customBorderRadius-lg)' + }) + }), + sizeSmall: { + height: '2.125rem', + minWidth: '2.125rem' + }, + sizeLarge: { + height: '2.625rem', + minWidth: '2.625rem' + } + } + } +} + +export default pagination diff --git a/front-urban/src/@core/theme/overrides/paper.ts b/front-urban/src/@core/theme/overrides/paper.ts new file mode 100644 index 0000000..8a0a6ef --- /dev/null +++ b/front-urban/src/@core/theme/overrides/paper.ts @@ -0,0 +1,14 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const paper: Theme['components'] = { + MuiPaper: { + styleOverrides: { + root: { + backgroundImage: 'none' + } + } + } +} + +export default paper diff --git a/front-urban/src/@core/theme/overrides/popover.ts b/front-urban/src/@core/theme/overrides/popover.ts new file mode 100644 index 0000000..0db70cd --- /dev/null +++ b/front-urban/src/@core/theme/overrides/popover.ts @@ -0,0 +1,21 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const popover = (skin: Skin): Theme['components'] => ({ + MuiPopover: { + styleOverrides: { + paper: { + ...(skin === 'bordered' + ? { boxShadow: 'none', border: '1px solid var(--mui-palette-divider)' } + : { + boxShadow: 'var(--mui-customShadows-sm)' + }) + } + } + } +}) + +export default popover diff --git a/front-urban/src/@core/theme/overrides/progress.ts b/front-urban/src/@core/theme/overrides/progress.ts new file mode 100644 index 0000000..1e0e2ec --- /dev/null +++ b/front-urban/src/@core/theme/overrides/progress.ts @@ -0,0 +1,18 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const progress: Theme['components'] = { + MuiLinearProgress: { + styleOverrides: { + root: ({ theme }) => ({ + height: 6, + borderRadius: theme.shape.borderRadius, + '& .MuiLinearProgress-bar': { + borderRadius: theme.shape.borderRadius + } + }) + } + } +} + +export default progress diff --git a/front-urban/src/@core/theme/overrides/radio.tsx b/front-urban/src/@core/theme/overrides/radio.tsx new file mode 100644 index 0000000..067ef95 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/radio.tsx @@ -0,0 +1,81 @@ +// React Imports +import React from 'react' + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const IconChecked = () => { + return ( + + + + ) +} + +const UncheckedIcon = () => { + return ( + + + + ) +} + +const radio: Theme['components'] = { + MuiRadio: { + defaultProps: { + icon: , + checkedIcon: + }, + styleOverrides: { + root: ({ theme, ownerState }) => ({ + ...(ownerState.size === 'small' + ? { + padding: theme.spacing(1), + '& svg': { + fontSize: '1.25rem' + } + } + : { + padding: theme.spacing(1.5), + '& svg': { + fontSize: '1.5rem' + } + }), + '&.Mui-checked:not(.Mui-disabled) svg': { + filter: 'drop-shadow(var(--mui-customShadows-xs))' + }, + '&.Mui-disabled': { + opacity: 0.45, + '&:not(.Mui-checked)': { + color: 'var(--mui-palette-text-secondary)' + }, + '&.Mui-checked.MuiRadio-colorPrimary': { + color: 'var(--mui-palette-primary-main)' + }, + '&.Mui-checked.MuiRadio-colorSecondary': { + color: 'var(--mui-palette-secondary-main)' + }, + '&.Mui-checked.MuiRadio-colorError': { + color: 'var(--mui-palette-error-main)' + }, + '&.Mui-checked.MuiRadio-colorWarning': { + color: 'var(--mui-palette-warning-main)' + }, + '&.Mui-checked.MuiRadio-colorInfo': { + color: 'var(--mui-palette-info-main)' + }, + '&.Mui-checked.MuiRadio-colorSuccess': { + color: 'var(--mui-palette-success-main)' + } + } + }) + } + } +} + +export default radio diff --git a/front-urban/src/@core/theme/overrides/rating.tsx b/front-urban/src/@core/theme/overrides/rating.tsx new file mode 100644 index 0000000..e08b8f4 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/rating.tsx @@ -0,0 +1,35 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const rating: Theme['components'] = { + MuiRating: { + defaultProps: { + emptyIcon: , + icon: + }, + styleOverrides: { + root: { + gap: '2px', + color: 'var(--mui-palette-warning-main)', + '& i, & svg': { + flexShrink: 0 + }, + '& .MuiRating-decimal > label:first-of-type, & .MuiRating-decimal > span:first-of-type': { + zIndex: 1 + } + }, + sizeSmall: { + '& .MuiRating-icon i, & .MuiRating-icon svg': { + fontSize: '1.25rem' + } + }, + sizeLarge: { + '& .MuiRating-icon i, & .MuiRating-icon svg': { + fontSize: '1.75rem' + } + } + } + } +} + +export default rating diff --git a/front-urban/src/@core/theme/overrides/select.tsx b/front-urban/src/@core/theme/overrides/select.tsx new file mode 100644 index 0000000..b38fcef --- /dev/null +++ b/front-urban/src/@core/theme/overrides/select.tsx @@ -0,0 +1,61 @@ +// React Imports +import React from 'react' + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const SelectIcon = () => { + return +} + +const iconStyles = (theme: Theme) => ({ + userSelect: 'none', + display: 'inline-block', + fill: 'currentColor', + flexShrink: 0, + transition: theme.transitions.create('fill', { + duration: theme.transitions.duration.shorter + }), + fontSize: '1.25rem', + position: 'absolute', + right: '1rem', + top: 'calc(50% - 0.5em)', + pointerEvents: 'none' +}) + +const select: Theme['components'] = { + MuiSelect: { + defaultProps: { + IconComponent: SelectIcon + }, + styleOverrides: { + select: ({ theme, ownerState }) => ({ + ...(ownerState.variant === 'outlined' && { + minHeight: '1.5em' + }), + '&[aria-expanded="true"] ~ i, &[aria-expanded="true"] ~ svg': { + transform: 'rotate(180deg)' + }, + '& ~ i, & ~ svg': iconStyles(theme as Theme), + '&.MuiInputBase-inputSizeSmall': { + '& ~ i, & ~ svg': { + height: '1.375rem', + width: '1.375rem' + } + }, + '&:not(aria-label="Without label") ~ .MuiOutlinedInput-notchedOutline > legend > span': { + paddingInline: '5px' + } + }) + } + }, + MuiNativeSelect: { + styleOverrides: { + select: ({ theme }) => ({ + '& + i, & + svg': iconStyles(theme as Theme) + }) + } + } +} + +export default select diff --git a/front-urban/src/@core/theme/overrides/slider.ts b/front-urban/src/@core/theme/overrides/slider.ts new file mode 100644 index 0000000..d49bb7f --- /dev/null +++ b/front-urban/src/@core/theme/overrides/slider.ts @@ -0,0 +1,100 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const slider: Theme['components'] = { + MuiSlider: { + styleOverrides: { + root: ({ ownerState }) => ({ + boxSizing: 'border-box', + ...(ownerState.orientation === 'horizontal' + ? ownerState.size !== 'small' + ? { height: 6 } + : { height: 4 } + : ownerState.size !== 'small' + ? { width: 6 } + : { width: 4 }), + '&.Mui-disabled': { + opacity: 0.45, + color: `var(--mui-palette-${ownerState.color}-main)` + } + }), + thumb: ({ ownerState }) => ({ + ...(ownerState.size === 'small' + ? { + height: 14, + width: 14, + border: '2px solid currentColor', + '&:hover, &.Mui-focusVisible': { + boxShadow: `0 0 0 7px var(--mui-palette-${ownerState.color}-lightOpacity)` + }, + '&.Mui-active.Mui-focusVisible': { + boxShadow: `0 0 0 10px var(--mui-palette-${ownerState.color}-lightOpacity)` + } + } + : { + height: 22, + width: 22, + border: '4px solid currentColor' + }), + backgroundColor: 'var(--mui-palette-common-white)', + ...(!ownerState.disabled && { + boxShadow: 'var(--mui-customShadows-sm)' + }), + '&:before': { + boxShadow: 'none' + }, + '&:after': { + ...(ownerState.size === 'small' + ? { + height: 28, + width: 28 + } + : { + height: 38, + width: 38 + }) + }, + '&:hover, &.Mui-focusVisible': { + boxShadow: `0 0 0 8px var(--mui-palette-${ownerState.color}-lightOpacity)` + }, + '&.Mui-active.Mui-focusVisible': { + boxShadow: `0 0 0 13px var(--mui-palette-${ownerState.color}-lightOpacity)` + } + }), + rail: ({ ownerState }) => ({ + opacity: 1, + color: `var(--mui-palette-${ownerState.color}-lightOpacity)`, + ...(ownerState.track === 'inverted' && { + backgroundColor: `var(--mui-palette-${ownerState.color}-main)` + }) + }), + valueLabel: ({ theme, ownerState }) => ({ + ...(ownerState.size === 'small' + ? { + ...theme.typography.caption, + borderRadius: 'var(--mui-shape-customBorderRadius-sm)', + padding: theme.spacing(1, 2) + } + : { + ...theme.typography.body2, + fontWeight: theme.typography.fontWeightMedium, + borderRadius: 'var(--mui-shape-borderRadius)', + padding: theme.spacing(1, 2.5) + }), + color: 'var(--mui-palette-customColors-tooltipText)', + backgroundColor: 'var(--mui-palette-Tooltip-bg)', + '&:before': { + display: 'none' + } + }), + track: ({ theme, ownerState }) => ({ + ...(ownerState.track === 'inverted' && { + backgroundColor: `color-mix(in srgb, ${theme.palette[ownerState.color || 'primary'].main} 16%, var(--mui-palette-background-paper))`, + borderColor: `color-mix(in srgb, ${theme.palette[ownerState.color || 'primary'].main} 16%, var(--mui-palette-background-paper))` + }) + }) + } + } +} + +export default slider diff --git a/front-urban/src/@core/theme/overrides/snackbar.ts b/front-urban/src/@core/theme/overrides/snackbar.ts new file mode 100644 index 0000000..6ac0481 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/snackbar.ts @@ -0,0 +1,27 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Skin } from '@core/types' + +const snackbar = (skin: Skin): Theme['components'] => ({ + MuiSnackbarContent: { + styleOverrides: { + root: ({ theme }) => ({ + padding: theme.spacing(0, 4), + ...(skin !== 'bordered' + ? { + boxShadow: 'var(--mui-customShadows-xs)' + } + : { + boxShadow: 'none' + }), + '& .MuiSnackbarContent-message': { + paddingBlock: theme.spacing(3) + } + }) + } + } +}) + +export default snackbar diff --git a/front-urban/src/@core/theme/overrides/switch.ts b/front-urban/src/@core/theme/overrides/switch.ts new file mode 100644 index 0000000..ef3b367 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/switch.ts @@ -0,0 +1,69 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const switchOverrides: Theme['components'] = { + MuiSwitch: { + defaultProps: { + disableRipple: true + }, + styleOverrides: { + root: ({ theme, ownerState }) => ({ + '&:has(.Mui-disabled)': { + opacity: 0.45 + }, + ...(ownerState.size !== 'small' + ? { + width: 46, + height: 36, + padding: theme.spacing(2.25, 2) + } + : { + width: 42, + height: 30, + padding: theme.spacing(1.75, 2), + '& .MuiSwitch-thumb': { + width: 12, + height: 12 + }, + '& .MuiSwitch-switchBase': { + padding: 7, + left: 3, + '&.Mui-checked': { + left: -3 + } + } + }) + }), + switchBase: { + top: 2, + left: 1, + '&.Mui-checked': { + left: -7, + color: 'var(--mui-palette-common-white)', + '& + .MuiSwitch-track': { + opacity: 1 + } + }, + '&.Mui-disabled + .MuiSwitch-track': { + opacity: 1 + }, + '&:hover:not(:has(span.MuiTouchRipple-root))': { + backgroundColor: 'transparent' + } + }, + thumb: { + width: 14, + height: 14, + boxShadow: 'var(--mui-customShadows-xs)' + }, + track: { + opacity: 1, + borderRadius: 10, + backgroundColor: 'var(--mui-palette-action-focus)', + boxShadow: `0 0 4px rgb(0 0 0 / 0.16) inset` + } + } + } +} + +export default switchOverrides diff --git a/front-urban/src/@core/theme/overrides/table-pagination.ts b/front-urban/src/@core/theme/overrides/table-pagination.ts new file mode 100644 index 0000000..9170280 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/table-pagination.ts @@ -0,0 +1,42 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const tablePagination: Theme['components'] = { + MuiTablePagination: { + styleOverrides: { + toolbar: ({ theme }) => ({ + paddingInlineEnd: `${theme.spacing(3)} !important` + }), + select: ({ theme }) => ({ + ...theme.typography.body1, + paddingInlineStart: 0, + '& ~ i, & ~ svg': { + fontSize: 20, + right: '2px !important', + color: 'var(--mui-palette-action-active)' + } + }), + selectLabel: ({ theme }) => ({ + ...theme.typography.body1, + color: 'var(--mui-palette-text-secondary)' + }), + input: ({ theme }) => ({ + marginInlineEnd: theme.spacing(6) + }), + displayedRows: ({ theme }) => ({ + ...theme.typography.body1 + }), + actions: ({ theme }) => ({ + marginInlineStart: theme.spacing(6), + '& .Mui-disabled': { + color: 'var(--mui-palette-action-active)' + }, + '& .MuiIconButton-root:last-of-type': { + marginInlineStart: theme.spacing(2) + } + }) + } + } +} + +export default tablePagination diff --git a/front-urban/src/@core/theme/overrides/tabs.ts b/front-urban/src/@core/theme/overrides/tabs.ts new file mode 100644 index 0000000..33cadfb --- /dev/null +++ b/front-urban/src/@core/theme/overrides/tabs.ts @@ -0,0 +1,92 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const tabs: Theme['components'] = { + MuiTabs: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + minBlockSize: 38, + ...(ownerState.orientation === 'horizontal' + ? { + borderBlockEnd: '1px solid var(--mui-palette-divider)' + } + : { + borderInlineEnd: '1px solid var(--mui-palette-divider)' + }), + '& .MuiTab-root:hover': { + ...(ownerState.orientation === 'horizontal' + ? { + paddingBlockEnd: theme.spacing(1.5), + ...(ownerState.textColor === 'secondary' + ? { + color: 'var(--mui-palette-secondary-main)', + borderBlockEnd: '2px solid var(--mui-palette-secondary-lightOpacity)' + } + : { + color: 'var(--mui-palette-primary-main)', + borderBlockEnd: '2px solid var(--mui-palette-primary-lightOpacity)' + }) + } + : { + paddingInlineEnd: theme.spacing(5), + ...(ownerState.textColor === 'secondary' + ? { + color: 'var(--mui-palette-secondary-main)', + borderInlineEnd: '2px solid var(--mui-palette-secondary-mainOpacity)' + } + : { + color: 'var(--mui-palette-primary-main)', + borderInlineEnd: '2px solid var(--mui-palette-primary-mainOpacity)' + }) + }), + '& .MuiTabScrollButton-root': { + borderRadius: theme.shape.borderRadius + } + }, + '& ~ .MuiTabPanel-root': { + ...(ownerState.orientation === 'horizontal' + ? { + paddingBlockStart: theme.spacing(5) + } + : { + paddingInlineStart: theme.spacing(5) + }) + } + }), + vertical: { + minWidth: 131, + '& .MuiTab-root': { + minWidth: 130 + } + } + } + }, + MuiTab: { + styleOverrides: { + root: ({ theme, ownerState }) => ({ + lineHeight: 1.4667, + padding: theme.spacing(2, 5.5), + minBlockSize: 38, + color: 'var(--mui-palette-text-primary)', + '& > .MuiTab-iconWrapper': { + fontSize: '1.125rem', + ...(ownerState.iconPosition === 'start' && { + marginInlineEnd: theme.spacing(1.5) + }), + ...(ownerState.iconPosition === 'end' && { + marginInlineStart: theme.spacing(1.5) + }) + } + }) + } + }, + MuiTabPanel: { + styleOverrides: { + root: { + padding: 0 + } + } + } +} + +export default tabs diff --git a/front-urban/src/@core/theme/overrides/timeline.ts b/front-urban/src/@core/theme/overrides/timeline.ts new file mode 100644 index 0000000..d4e759b --- /dev/null +++ b/front-urban/src/@core/theme/overrides/timeline.ts @@ -0,0 +1,161 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const timeline: Theme['components'] = { + MuiTimeline: { + styleOverrides: { + root: { + padding: 0 + } + } + }, + MuiTimelineDot: { + styleOverrides: { + root: ({ theme }) => ({ + margin: theme.spacing(3, 0), + boxShadow: 'none', + '&:has(> i), &:has(> svg)': { + padding: 6 + }, + '& > svg, & > i': { + fontSize: '1.25rem' + }, + '&:has(svg)': { + width: 32, + height: 32, + alignItems: 'center', + justifyContent: 'center' + } + }) + }, + variants: [ + { + props: { variant: 'outlined' }, + style: { + padding: 5, + '& + .MuiTimelineConnector-root': { + backgroundColor: 'transparent', + borderInlineStart: '1px dashed var(--mui-palette-divider)' + }, + '&:has(+ .MuiTimelineConnector-root)': { + marginBlock: '0.625rem' + } + } + }, + { + props: { variant: 'filled', color: 'grey' }, + style: { + boxShadow: '0 0 0 3px rgb(var(--mui-mainColorChannels-light) / 0.04)' + } + }, + { + props: { variant: 'filled', color: 'primary' }, + style: { + boxShadow: '0 0 0 3px var(--mui-palette-primary-lightOpacity)' + } + }, + { + props: { variant: 'filled', color: 'secondary' }, + style: { + boxShadow: '0 0 0 3px var(--mui-palette-secondary-lightOpacity)' + } + }, + { + props: { variant: 'filled', color: 'error' }, + style: { + boxShadow: '0 0 0 3px var(--mui-palette-error-lightOpacity)' + } + }, + { + props: { variant: 'filled', color: 'warning' }, + style: { + boxShadow: '0 0 0 3px var(--mui-palette-warning-lightOpacity)' + } + }, + { + props: { variant: 'filled', color: 'info' }, + style: { + boxShadow: '0 0 0 3px var(--mui-palette-info-lightOpacity)' + } + }, + { + props: { variant: 'filled', color: 'success' }, + style: { + boxShadow: '0 0 0 3px var(--mui-palette-success-lightOpacity)' + } + }, + { + props: { variant: 'tonal' }, + style: { + border: 0 + } + }, + { + props: { variant: 'tonal', color: 'grey' }, + style: { + backgroundColor: 'var(--mui-palette-action-selected)', + color: 'var(--mui-palette-text-primary)' + } + }, + { + props: { variant: 'tonal', color: 'primary' }, + style: { + backgroundColor: 'var(--mui-palette-primary-lightOpacity)', + color: 'var(--mui-palette-primary-main)' + } + }, + { + props: { variant: 'tonal', color: 'secondary' }, + style: { + backgroundColor: 'var(--mui-palette-secondary-lightOpacity)', + color: 'var(--mui-palette-secondary-main)' + } + }, + { + props: { variant: 'tonal', color: 'error' }, + style: { + backgroundColor: 'var(--mui-palette-error-lightOpacity)', + color: 'var(--mui-palette-error-main)' + } + }, + { + props: { variant: 'tonal', color: 'warning' }, + style: { + backgroundColor: 'var(--mui-palette-warning-lightOpacity)', + color: 'var(--mui-palette-warning-main)' + } + }, + { + props: { variant: 'tonal', color: 'info' }, + style: { + backgroundColor: 'var(--mui-palette-info-lightOpacity)', + color: 'var(--mui-palette-info-main)' + } + }, + { + props: { variant: 'tonal', color: 'success' }, + style: { + backgroundColor: 'var(--mui-palette-success-lightOpacity)', + color: 'var(--mui-palette-success-main)' + } + } + ] + }, + MuiTimelineConnector: { + styleOverrides: { + root: { + width: 1, + backgroundColor: 'var(--mui-palette-divider)' + } + } + }, + MuiTimelineContent: { + styleOverrides: { + root: { + paddingBottom: '1rem' + } + } + } +} + +export default timeline diff --git a/front-urban/src/@core/theme/overrides/toggle-button.ts b/front-urban/src/@core/theme/overrides/toggle-button.ts new file mode 100644 index 0000000..1d49d2f --- /dev/null +++ b/front-urban/src/@core/theme/overrides/toggle-button.ts @@ -0,0 +1,34 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const toggleButton: Theme['components'] = { + MuiToggleButtonGroup: { + styleOverrides: { + root: ({ ownerState }) => ({ + ...(ownerState.size === 'small' && { + borderRadius: 'var(--mui-shape-customBorderRadius-sm)' + }), + ...(ownerState.size === 'large' && { + borderRadius: 'var(--mui-shape-customBorderRadius-lg)' + }) + }) + } + }, + MuiToggleButton: { + styleOverrides: { + root: { + '&:not(.Mui-selected):not(.Mui-disabled)': { + color: 'var(--mui-palette-text-secondary)' + } + }, + sizeSmall: { + borderRadius: 'var(--mui-shape-customBorderRadius-sm)' + }, + sizeLarge: { + borderRadius: 'var(--mui-shape-customBorderRadius-lg)' + } + } + } +} + +export default toggleButton diff --git a/front-urban/src/@core/theme/overrides/tooltip.ts b/front-urban/src/@core/theme/overrides/tooltip.ts new file mode 100644 index 0000000..d270401 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/tooltip.ts @@ -0,0 +1,32 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const tooltip: Theme['components'] = { + MuiTooltip: { + styleOverrides: { + popper: { + '&[data-popper-placement*="bottom"] .MuiTooltip-tooltip': { + marginTop: '6px !important' + }, + '&[data-popper-placement*="top"] .MuiTooltip-tooltip': { + marginBottom: '6px !important' + }, + '&[data-popper-placement*="left"] .MuiTooltip-tooltip': { + marginRight: '6px !important' + }, + '&[data-popper-placement*="right"] .MuiTooltip-tooltip': { + marginLeft: '6px !important' + } + }, + tooltip: ({ theme }) => ({ + borderRadius: 'var(--mui-shape-customBorderRadius-sm)', + fontSize: theme.typography.subtitle2.fontSize, + lineHeight: 1.539, + color: 'var(--mui-palette-customColors-tooltipText)', + paddingInline: theme.spacing(3) + }) + } + } +} + +export default tooltip diff --git a/front-urban/src/@core/theme/overrides/typography.ts b/front-urban/src/@core/theme/overrides/typography.ts new file mode 100644 index 0000000..0d23df9 --- /dev/null +++ b/front-urban/src/@core/theme/overrides/typography.ts @@ -0,0 +1,68 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const typography: Theme['components'] = { + MuiTypography: { + styleOverrides: { + gutterBottom: ({ theme }) => ({ + marginBottom: theme.spacing(2) + }) + }, + variants: [ + { + props: { variant: 'h1' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'h2' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'h3' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'h4' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'h5' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'h6' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'subtitle1' }, + style: { color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' } + }, + { + props: { variant: 'subtitle2' }, + style: { color: 'rgb(var(--mui-palette-text-primaryChannel) / 0.55)' } + }, + { + props: { variant: 'body1' }, + style: { color: 'var(--mui-palette-text-secondary)' } + }, + { + props: { variant: 'body2' }, + style: { color: 'var(--mui-palette-text-secondary)' } + }, + { + props: { variant: 'button' }, + style: { color: 'var(--mui-palette-text-primary)' } + }, + { + props: { variant: 'caption' }, + style: { color: 'var(--mui-palette-text-disabled)', display: 'inline-block' } + }, + { + props: { variant: 'overline' }, + style: { color: 'var(--mui-palette-text-primary)', display: 'inline-block' } + } + ] + } +} + +export default typography diff --git a/front-urban/src/@core/theme/shadows.ts b/front-urban/src/@core/theme/shadows.ts new file mode 100644 index 0000000..9a8f785 --- /dev/null +++ b/front-urban/src/@core/theme/shadows.ts @@ -0,0 +1,39 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { SystemMode } from '@core/types' + +const shadows = (mode: SystemMode): Theme['shadows'] => { + const color = `var(--mui-mainColorChannels-${mode}Shadow)` + + return [ + 'none', + `0px 2px 1px -1px rgb(${color} / 0.2),0px 1px 1px 0px rgb(${color} / 0.14),0px 1px 3px 0px rgb(${color} / 0.12)`, + `0px 3px 1px -2px rgb(${color} / 0.2),0px 2px 2px 0px rgb(${color} / 0.14),0px 1px 5px 0px rgb(${color} / 0.12)`, + `0px 3px 3px -2px rgb(${color} / 0.2),0px 3px 4px 0px rgb(${color} / 0.14),0px 1px 8px 0px rgb(${color} / 0.12)`, + `0px 2px 4px -1px rgb(${color} / 0.2),0px 4px 5px 0px rgb(${color} / 0.14),0px 1px 10px 0px rgb(${color} / 0.12)`, + `0px 3px 5px -1px rgb(${color} / 0.2),0px 5px 8px 0px rgb(${color} / 0.14),0px 1px 14px 0px rgb(${color} / 0.12)`, + `0px 3px 5px -1px rgb(${color} / 0.2),0px 6px 10px 0px rgb(${color} / 0.14),0px 1px 18px 0px rgb(${color} / 0.12)`, + `0px 4px 5px -2px rgb(${color} / 0.2),0px 7px 10px 1px rgb(${color} / 0.14),0px 2px 16px 1px rgb(${color} / 0.12)`, + `0px 5px 5px -3px rgb(${color} / 0.2),0px 8px 10px 1px rgb(${color} / 0.14),0px 3px 14px 2px rgb(${color} / 0.12)`, + `0px 5px 6px -3px rgb(${color} / 0.2),0px 9px 12px 1px rgb(${color} / 0.14),0px 3px 16px 2px rgb(${color} / 0.12)`, + `0px 6px 6px -3px rgb(${color} / 0.2),0px 10px 14px 1px rgb(${color} / 0.14),0px 4px 18px 3px rgb(${color} / 0.12)`, + `0px 6px 7px -4px rgb(${color} / 0.2),0px 11px 15px 1px rgb(${color} / 0.14),0px 4px 20px 3px rgb(${color} / 0.12)`, + `0px 7px 8px -4px rgb(${color} / 0.2),0px 12px 17px 2px rgb(${color} / 0.14),0px 5px 22px 4px rgb(${color} / 0.12)`, + `0px 7px 8px -4px rgb(${color} / 0.2),0px 13px 19px 2px rgb(${color} / 0.14),0px 5px 24px 4px rgb(${color} / 0.12)`, + `0px 7px 9px -4px rgb(${color} / 0.2),0px 14px 21px 2px rgb(${color} / 0.14),0px 5px 26px 4px rgb(${color} / 0.12)`, + `0px 8px 9px -5px rgb(${color} / 0.2),0px 15px 22px 2px rgb(${color} / 0.14),0px 6px 28px 5px rgb(${color} / 0.12)`, + `0px 8px 10px -5px rgb(${color} / 0.2),0px 16px 24px 2px rgb(${color} / 0.14),0px 6px 30px 5px rgb(${color} / 0.12)`, + `0px 8px 11px -5px rgb(${color} / 0.2),0px 17px 26px 2px rgb(${color} / 0.14),0px 6px 32px 5px rgb(${color} / 0.12)`, + `0px 9px 11px -5px rgb(${color} / 0.2),0px 18px 28px 2px rgb(${color} / 0.14),0px 7px 34px 6px rgb(${color} / 0.12)`, + `0px 9px 12px -6px rgb(${color} / 0.2),0px 19px 29px 2px rgb(${color} / 0.14),0px 7px 36px 6px rgb(${color} / 0.12)`, + `0px 10px 13px -6px rgb(${color} / 0.2),0px 20px 31px 3px rgb(${color} / 0.14),0px 8px 38px 7px rgb(${color} / 0.12)`, + `0px 10px 13px -6px rgb(${color} / 0.2),0px 21px 33px 3px rgb(${color} / 0.14),0px 8px 40px 7px rgb(${color} / 0.12)`, + `0px 10px 14px -6px rgb(${color} / 0.2),0px 22px 35px 3px rgb(${color} / 0.14),0px 8px 42px 7px rgb(${color} / 0.12)`, + `0px 11px 14px -7px rgb(${color} / 0.2),0px 23px 36px 3px rgb(${color} / 0.14),0px 9px 44px 8px rgb(${color} / 0.12)`, + `0px 11px 15px -7px rgb(${color} / 0.2),0px 24px 38px 3px rgb(${color} / 0.14),0px 9px 46px 8px rgb(${color} / 0.12)` + ] +} + +export default shadows diff --git a/front-urban/src/@core/theme/spacing.ts b/front-urban/src/@core/theme/spacing.ts new file mode 100644 index 0000000..c40a168 --- /dev/null +++ b/front-urban/src/@core/theme/spacing.ts @@ -0,0 +1,5 @@ +const spacing = { + spacing: (factor: number) => `${0.25 * factor}rem` +} + +export default spacing diff --git a/front-urban/src/@core/theme/typography.ts b/front-urban/src/@core/theme/typography.ts new file mode 100644 index 0000000..fd7e49a --- /dev/null +++ b/front-urban/src/@core/theme/typography.ts @@ -0,0 +1,88 @@ +// MUI Imports +import type { Theme } from '@mui/material/styles' + +const typography = (fontFamily: string): Theme['typography'] => + ({ + fontFamily: + typeof fontFamily === 'undefined' || fontFamily === '' + ? [ + 'Inter', + 'sans-serif', + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"' + ].join(',') + : fontFamily, + fontSize: 13.125, + h1: { + fontSize: '2.875rem', + fontWeight: 500, + lineHeight: 1.478261 + }, + h2: { + fontSize: '2.375rem', + fontWeight: 500, + lineHeight: 1.47368421 + }, + h3: { + fontSize: '1.75rem', + fontWeight: 500, + lineHeight: 1.5 + }, + h4: { + fontSize: '1.5rem', + fontWeight: 500, + lineHeight: 1.58334 + }, + h5: { + fontSize: '1.125rem', + fontWeight: 500, + lineHeight: 1.5556 + }, + h6: { + fontSize: '0.9375rem', + fontWeight: 500, + lineHeight: 1.46667 + }, + subtitle1: { + fontSize: '0.9375rem', + lineHeight: 1.46667 + }, + subtitle2: { + fontSize: '0.8125rem', + fontWeight: 400, + lineHeight: 1.53846154 + }, + body1: { + fontSize: '0.9375rem', + lineHeight: 1.46667 + }, + body2: { + fontSize: '0.8125rem', + lineHeight: 1.53846154 + }, + button: { + fontSize: '0.9375rem', + lineHeight: 1.46667, + textTransform: 'none' + }, + caption: { + fontSize: '0.8125rem', + lineHeight: 1.38462, + letterSpacing: '0.4px' + }, + overline: { + fontSize: '0.75rem', + lineHeight: 1.16667, + letterSpacing: '0.8px' + } + }) as Theme['typography'] + +export default typography diff --git a/front-urban/src/@core/types.ts b/front-urban/src/@core/types.ts new file mode 100644 index 0000000..bbfa61f --- /dev/null +++ b/front-urban/src/@core/types.ts @@ -0,0 +1,16 @@ +// React Imports +import type { ReactNode } from 'react' + +export type Skin = 'default' | 'bordered' + +export type Mode = 'light' | 'dark' + +export type SystemMode = 'light' | 'dark' + +export type Direction = 'ltr' | 'rtl' + +export type ChildrenType = { + children: ReactNode +} + +export type ThemeColor = 'primary' | 'secondary' | 'error' | 'warning' | 'info' | 'success' diff --git a/front-urban/src/@core/types/system-config.ts b/front-urban/src/@core/types/system-config.ts new file mode 100644 index 0000000..c4aae26 --- /dev/null +++ b/front-urban/src/@core/types/system-config.ts @@ -0,0 +1,18 @@ +export type SystemConfig = { + id: string; + sessionCleanupIntervalMinutes: number; + invoiceGenerationDayOfMonth: number; + tokenExpirationMinutes: number; + tokenCleanupIntervalMinutes: number; + profilePictureUpdateIntervalDays: number; + createdAt: string; + updatedAt: string; +}; + +export type UpdateSystemConfigDto = { + sessionCleanupIntervalMinutes?: number; + invoiceGenerationDayOfMonth?: number; + tokenExpirationMinutes?: number; + tokenCleanupIntervalMinutes?: number; + profilePictureUpdateIntervalDays?: number; +}; diff --git a/front-urban/src/@core/utils/serverHelpers.ts b/front-urban/src/@core/utils/serverHelpers.ts new file mode 100644 index 0000000..462b804 --- /dev/null +++ b/front-urban/src/@core/utils/serverHelpers.ts @@ -0,0 +1,40 @@ +import 'server-only' + +// Next Imports +import { cookies } from 'next/headers' + +// Type Imports +import type { Settings } from '@core/contexts/settingsContext' +import type { SystemMode } from '@core/types' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +export const getSettingsFromCookie = (): Settings => { + const cookieStore = cookies() + + const cookieName = themeConfig.settingsCookieName + + return JSON.parse(cookieStore.get(cookieName)?.value || '{}') +} + +export const getMode = () => { + const settingsCookie = getSettingsFromCookie() + + // Get mode from cookie or fallback to theme config + const _mode = settingsCookie.mode || themeConfig.mode + + return _mode +} + +export const getSystemMode = (): SystemMode => { + const mode = getMode() + + return mode +} + +export const getServerMode = () => { + const mode = getMode() + + return mode +} diff --git a/front-urban/src/@layouts/BlankLayout.tsx b/front-urban/src/@layouts/BlankLayout.tsx new file mode 100644 index 0000000..5a95552 --- /dev/null +++ b/front-urban/src/@layouts/BlankLayout.tsx @@ -0,0 +1,16 @@ +'use client' + +// Third-party Imports +import classnames from 'classnames' + +// Type Imports +import type { ChildrenType } from '@core/types' + +// Util Imports +import { blankLayoutClasses } from './utils/layoutClasses' + +const BlankLayout = ({ children }: ChildrenType) => { + return
{children}
+} + +export default BlankLayout diff --git a/front-urban/src/@layouts/LayoutWrapper.tsx b/front-urban/src/@layouts/LayoutWrapper.tsx new file mode 100644 index 0000000..964e93e --- /dev/null +++ b/front-urban/src/@layouts/LayoutWrapper.tsx @@ -0,0 +1,11 @@ +'use client' + +// React Imports +import type { ReactElement } from 'react' + +const LayoutWrapper = ({ verticalLayout }: { verticalLayout: ReactElement }) => { + // Return the layout based on the layout context + return
{verticalLayout}
+} + +export default LayoutWrapper diff --git a/front-urban/src/@layouts/VerticalLayout.tsx b/front-urban/src/@layouts/VerticalLayout.tsx new file mode 100644 index 0000000..1c953f3 --- /dev/null +++ b/front-urban/src/@layouts/VerticalLayout.tsx @@ -0,0 +1,39 @@ +// React Imports +import type { ReactNode } from 'react' + +// Third-party Imports +import classnames from 'classnames' + +// Type Imports +import type { ChildrenType } from '@core/types' + +// Component Imports +import LayoutContent from './components/vertical/LayoutContent' + +// Util Imports +import { verticalLayoutClasses } from './utils/layoutClasses' + +type VerticalLayoutProps = ChildrenType & { + navigation?: ReactNode + navbar?: ReactNode + footer?: ReactNode +} + +const VerticalLayout = (props: VerticalLayoutProps) => { + // Props + const { navbar, footer, navigation, children } = props + + return ( +
+ {navigation || null} +
+ {navbar || null} + {/* Content */} + {children} + {footer || null} +
+
+ ) +} + +export default VerticalLayout diff --git a/front-urban/src/@layouts/components/vertical/Footer.tsx b/front-urban/src/@layouts/components/vertical/Footer.tsx new file mode 100644 index 0000000..ffb649c --- /dev/null +++ b/front-urban/src/@layouts/components/vertical/Footer.tsx @@ -0,0 +1,40 @@ +'use client' + +// Third-party Imports +import classnames from 'classnames' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { ChildrenType } from '@core/types' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +// Styled Component Imports +import StyledFooter from '@layouts/styles/vertical/StyledFooter' + +type Props = ChildrenType & { + overrideStyles?: CSSObject +} + +const Footer = (props: Props) => { + // Props + const { children, overrideStyles } = props + + return ( + +
{children}
+
+ ) +} + +export default Footer diff --git a/front-urban/src/@layouts/components/vertical/LayoutContent.tsx b/front-urban/src/@layouts/components/vertical/LayoutContent.tsx new file mode 100644 index 0000000..cf3aad4 --- /dev/null +++ b/front-urban/src/@layouts/components/vertical/LayoutContent.tsx @@ -0,0 +1,26 @@ +'use client' + +// Third-party Imports +import classnames from 'classnames' + +// Type Imports +import type { ChildrenType } from '@core/types' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +// Styled Component Imports +import StyledMain from '@layouts/styles/shared/StyledMain' + +const LayoutContent = ({ children }: ChildrenType) => { + return ( + + {children} + + ) +} + +export default LayoutContent diff --git a/front-urban/src/@layouts/components/vertical/Navbar.tsx b/front-urban/src/@layouts/components/vertical/Navbar.tsx new file mode 100644 index 0000000..ebd4e96 --- /dev/null +++ b/front-urban/src/@layouts/components/vertical/Navbar.tsx @@ -0,0 +1,39 @@ +'use client' + +// Third-party Imports +import classnames from 'classnames' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { ChildrenType } from '@core/types' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +// Styled Component Imports +import StyledHeader from '@layouts/styles/vertical/StyledHeader' + +type Props = ChildrenType & { + overrideStyles?: CSSObject +} + +const Navbar = (props: Props) => { + // Props + const { children, overrideStyles } = props + + return ( + +
{children}
+
+ ) +} + +export default Navbar diff --git a/front-urban/src/@layouts/styles/shared/StyledMain.tsx b/front-urban/src/@layouts/styles/shared/StyledMain.tsx new file mode 100644 index 0000000..8e95a28 --- /dev/null +++ b/front-urban/src/@layouts/styles/shared/StyledMain.tsx @@ -0,0 +1,21 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +type StyledMainProps = { + isContentCompact: boolean +} + +const StyledMain = styled.main` + padding: ${themeConfig.layoutPadding}px; + ${({ isContentCompact }) => + isContentCompact && + ` + margin-inline: auto; + max-inline-size: ${themeConfig.compactContentWidth}px; + `} +` + +export default StyledMain diff --git a/front-urban/src/@layouts/styles/vertical/StyledFooter.tsx b/front-urban/src/@layouts/styles/vertical/StyledFooter.tsx new file mode 100644 index 0000000..8bfbd72 --- /dev/null +++ b/front-urban/src/@layouts/styles/vertical/StyledFooter.tsx @@ -0,0 +1,27 @@ +// Third-party Imports +import styled from '@emotion/styled' +import type { CSSObject } from '@emotion/styled' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +type StyledFooterProps = { + overrideStyles?: CSSObject +} + +const StyledFooter = styled.footer` + margin-inline: auto; + max-inline-size: ${themeConfig.compactContentWidth}px; + + & .${verticalLayoutClasses.footerContentWrapper} { + padding-block: 15px; + padding-inline: ${themeConfig.layoutPadding}px; + } + + ${({ overrideStyles }) => overrideStyles} +` + +export default StyledFooter diff --git a/front-urban/src/@layouts/styles/vertical/StyledHeader.tsx b/front-urban/src/@layouts/styles/vertical/StyledHeader.tsx new file mode 100644 index 0000000..3c72cad --- /dev/null +++ b/front-urban/src/@layouts/styles/vertical/StyledHeader.tsx @@ -0,0 +1,35 @@ +// Third-party Imports +import styled from '@emotion/styled' +import type { CSSObject } from '@emotion/styled' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +type StyledHeaderProps = { + overrideStyles?: CSSObject +} + +const StyledHeader = styled.header` + display: flex; + align-items: center; + justify-content: center; + inline-size: 100%; + flex-shrink: 0; + min-block-size: var(--header-height); + + .${verticalLayoutClasses.navbar} { + position: relative; + padding-block: 10px; + padding-inline: ${themeConfig.layoutPadding}px; + inline-size: 100%; + margin-inline: auto; + max-inline-size: ${themeConfig.compactContentWidth}px; + } + + ${({ overrideStyles }) => overrideStyles} +` + +export default StyledHeader diff --git a/front-urban/src/@layouts/utils/layoutClasses.ts b/front-urban/src/@layouts/utils/layoutClasses.ts new file mode 100644 index 0000000..3c5e78f --- /dev/null +++ b/front-urban/src/@layouts/utils/layoutClasses.ts @@ -0,0 +1,24 @@ +// Classes for vertical layout +export const verticalLayoutClasses = { + root: 'ts-vertical-layout', + contentWrapper: 'ts-vertical-layout-content-wrapper', + header: 'ts-vertical-layout-header', + headerStatic: 'ts-vertical-layout-header-static', + headerDetached: 'ts-vertical-layout-header-detached', + headerContentCompact: 'ts-vertical-layout-header-content-compact', + navbar: 'ts-vertical-layout-navbar', + navbarContent: 'ts-vertical-layout-navbar-content', + content: 'ts-vertical-layout-content', + contentCompact: 'ts-vertical-layout-content-compact', + footer: 'ts-vertical-layout-footer', + footerStatic: 'ts-vertical-layout-footer-static', + footerDetached: 'ts-vertical-layout-footer-detached', + footerContentWrapper: 'ts-vertical-layout-footer-content-wrapper', + footerContent: 'ts-vertical-layout-footer-content', + footerContentCompact: 'ts-vertical-layout-footer-content-compact' +} + +// Classes for blank layout +export const blankLayoutClasses = { + root: 'ts-blank-layout' +} diff --git a/front-urban/src/@menu/components/RouterLink.tsx b/front-urban/src/@menu/components/RouterLink.tsx new file mode 100644 index 0000000..c42fe10 --- /dev/null +++ b/front-urban/src/@menu/components/RouterLink.tsx @@ -0,0 +1,27 @@ +'use client' + +// React Imports +import { forwardRef } from 'react' + +// Next Imports +import Link from 'next/link' +import type { LinkProps } from 'next/link' + +// Type Imports +import type { ChildrenType } from '../types' + +type RouterLinkProps = LinkProps & + Partial & { + className?: string + } + +export const RouterLink = forwardRef((props: RouterLinkProps, ref: any) => { + // Props + const { href, className, ...other } = props + + return ( + + {props.children} + + ) +}) diff --git a/front-urban/src/@menu/components/vertical-menu/Menu.tsx b/front-urban/src/@menu/components/vertical-menu/Menu.tsx new file mode 100644 index 0000000..05bfeae --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/Menu.tsx @@ -0,0 +1,193 @@ +'use client' + +// React Imports +import { createContext, forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import type { ForwardRefRenderFunction, MenuHTMLAttributes, MutableRefObject, ReactElement, ReactNode } from 'react' + +// Next Imports +import { usePathname } from 'next/navigation' + +// Third-party Imports +import classnames from 'classnames' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { + ChildrenType, + MenuItemStyles, + RootStylesType, + RenderExpandIconParams, + RenderExpandedMenuItemIcon +} from '../../types' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' + +// Styled Component Imports +import StyledVerticalMenu from '../../styles/vertical/StyledVerticalMenu' + +// Style Imports +import styles from '../../styles/styles.module.css' + +// Default Config Imports +import { verticalSubMenuToggleDuration } from '../../defaultConfigs' + +export type MenuSectionStyles = { + root?: CSSObject + label?: CSSObject + prefix?: CSSObject + suffix?: CSSObject + icon?: CSSObject +} + +export type OpenSubmenu = { + level: number + label: ReactNode + active: boolean + id: string +} + +export type VerticalMenuContextProps = { + transitionDuration?: number + menuSectionStyles?: MenuSectionStyles + menuItemStyles?: MenuItemStyles + subMenuOpenBehavior?: 'accordion' | 'collapse' + renderExpandIcon?: (params: RenderExpandIconParams) => ReactElement + renderExpandedMenuItemIcon?: RenderExpandedMenuItemIcon + textTruncate?: boolean + + /** + * @ignore + */ + openSubmenu?: OpenSubmenu[] + + /** + * @ignore + */ + openSubmenusRef?: MutableRefObject + + /** + * @ignore + */ + toggleOpenSubmenu?: (...submenus: { level: number; label: ReactNode; active?: boolean; id: string }[]) => void +} + +export type MenuProps = VerticalMenuContextProps & + RootStylesType & + Partial & + MenuHTMLAttributes + +export const VerticalMenuContext = createContext({} as VerticalMenuContextProps) + +const Menu: ForwardRefRenderFunction = (props, ref) => { + // Props + const { + children, + className, + rootStyles, + menuItemStyles, + renderExpandIcon, + renderExpandedMenuItemIcon, + menuSectionStyles, + subMenuOpenBehavior = 'accordion', // accordion, collapse + transitionDuration = verticalSubMenuToggleDuration, + textTruncate = true, + ...rest + } = props + + // States + const [openSubmenu, setOpenSubmenu] = useState([]) + + // Refs + const openSubmenusRef = useRef([]) + + // Hooks + const pathname = usePathname() + + const toggleOpenSubmenu = useCallback( + (...submenus: { level: number; label: ReactNode; active?: boolean; id: string }[]): void => { + if (!submenus.length) return + + const openSubmenuCopy = [...openSubmenu] + + submenus.forEach(({ level, label, active = false, id }) => { + const submenuIndex = openSubmenuCopy.findIndex(submenu => submenu.id === id) + const submenuExists = submenuIndex >= 0 + const isAccordion = subMenuOpenBehavior === 'accordion' + + const inactiveSubmenuIndex = openSubmenuCopy.findIndex(submenu => !submenu.active && submenu.level === 0) + + // Delete submenu if it exists + if (submenuExists) { + openSubmenuCopy.splice(submenuIndex, 1) + } + + if (isAccordion) { + // Add submenu if it doesn't exist + if (!submenuExists) { + if (inactiveSubmenuIndex >= 0 && !active && level === 0) { + openSubmenuCopy.splice(inactiveSubmenuIndex, 1, { level, label, active, id }) + } else { + openSubmenuCopy.push({ level, label, active, id }) + } + } + } else { + // Add submenu if it doesn't exist + if (!submenuExists) { + openSubmenuCopy.push({ level, label, active, id }) + } + } + }) + + setOpenSubmenu(openSubmenuCopy) + }, + [openSubmenu, subMenuOpenBehavior] + ) + + useEffect(() => { + setOpenSubmenu([...openSubmenusRef.current]) + openSubmenusRef.current = [] + }, [pathname]) + + const providerValue = useMemo( + () => ({ + transitionDuration, + menuItemStyles, + menuSectionStyles, + renderExpandIcon, + renderExpandedMenuItemIcon, + openSubmenu, + openSubmenusRef, + toggleOpenSubmenu, + subMenuOpenBehavior, + textTruncate + }), + [ + transitionDuration, + menuItemStyles, + menuSectionStyles, + renderExpandIcon, + renderExpandedMenuItemIcon, + openSubmenu, + openSubmenusRef, + toggleOpenSubmenu, + subMenuOpenBehavior, + textTruncate + ] + ) + + return ( + + +
    {children}
+
+
+ ) +} + +export default forwardRef(Menu) diff --git a/front-urban/src/@menu/components/vertical-menu/MenuButton.tsx b/front-urban/src/@menu/components/vertical-menu/MenuButton.tsx new file mode 100644 index 0000000..07636f9 --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/MenuButton.tsx @@ -0,0 +1,76 @@ +// React Imports +import { forwardRef } from 'react' +import type { ForwardRefRenderFunction } from 'react' + +// Third-party Imports +import { css } from '@emotion/react' + +// Type Imports +import type { ChildrenType, MenuButtonProps } from '../../types' + +// Component Imports +import { RouterLink } from '../RouterLink' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' + +type MenuButtonStylesProps = Partial & { + level: number + active?: boolean + disabled?: boolean +} + +export const menuButtonStyles = (props: MenuButtonStylesProps) => { + // Props + const { level, disabled, children } = props + + return css({ + display: 'flex', + alignItems: 'center', + minBlockSize: '30px', + textDecoration: 'none', + color: 'inherit', + boxSizing: 'border-box', + cursor: 'pointer', + paddingInlineEnd: '20px', + paddingInlineStart: `${level === 0 ? 20 : (level + 1) * 20}px`, + + '&:hover, &[aria-expanded="true"]': { + backgroundColor: '#f3f3f3' + }, + + '&:focus-visible': { + outline: 'none', + backgroundColor: '#f3f3f3' + }, + + ...(disabled && { + pointerEvents: 'none', + cursor: 'default', + color: '#adadad' + }), + + // All the active styles are applied to the button including menu items or submenu + [`&.${menuClasses.active}`]: { + ...(!children && { color: 'white' }), + backgroundColor: children ? '#f3f3f3' : '#765feb' + } + }) +} + +const MenuButton: ForwardRefRenderFunction = ( + { className, children, ...rest }, + ref +) => { + return rest.href ? ( + + {children} + + ) : ( + + {children} + + ) +} + +export default forwardRef(MenuButton) diff --git a/front-urban/src/@menu/components/vertical-menu/MenuItem.tsx b/front-urban/src/@menu/components/vertical-menu/MenuItem.tsx new file mode 100644 index 0000000..e91cb50 --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/MenuItem.tsx @@ -0,0 +1,186 @@ +'use client' + +// React Imports +import { forwardRef, useEffect, useState } from 'react' +import type { AnchorHTMLAttributes, ForwardRefRenderFunction, ReactElement, ReactNode } from 'react' + +// Next Imports +import { usePathname } from 'next/navigation' + +// Third-party Imports +import classnames from 'classnames' +import { useUpdateEffect } from 'react-use' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { ChildrenType, MenuItemElement, MenuItemExactMatchUrlProps, RootStylesType } from '../../types' + +// Component Imports +import MenuButton from './MenuButton' + +// Hook Imports +import useVerticalNav from '../../hooks/useVerticalNav' +import useVerticalMenu from '../../hooks/useVerticalMenu' + +// Util Imports +import { renderMenuIcon } from '../../utils/menuUtils' +import { menuClasses } from '../../utils/menuClasses' + +// Styled Component Imports +import StyledMenuLabel from '../../styles/StyledMenuLabel' +import StyledMenuPrefix from '../../styles/StyledMenuPrefix' +import StyledMenuSuffix from '../../styles/StyledMenuSuffix' +import StyledVerticalMenuItem from '../../styles/vertical/StyledVerticalMenuItem' + +export type MenuItemProps = Omit, 'prefix'> & + RootStylesType & + Partial & + MenuItemExactMatchUrlProps & { + icon?: ReactElement + prefix?: ReactNode + suffix?: ReactNode + disabled?: boolean + target?: string + rel?: string + onActiveChange?: (active: boolean) => void + + /** + * @ignore + */ + level?: number + } + +const MenuItem: ForwardRefRenderFunction = (props, ref) => { + // Props + const { + children, + icon, + className, + prefix, + suffix, + level = 0, + disabled = false, + exactMatch = true, + activeUrl, + onActiveChange, + rootStyles, + ...rest + } = props + + // States + const [active, setActive] = useState(false) + + // Hooks + const pathname = usePathname() + const { menuItemStyles, renderExpandedMenuItemIcon, textTruncate } = useVerticalMenu() + + const { toggleVerticalNav, isToggled, isBreakpointReached } = useVerticalNav() + + // Get the styles for the specified element. + const getMenuItemStyles = (element: MenuItemElement): CSSObject | undefined => { + // If the menuItemStyles prop is provided, get the styles for the specified element. + if (menuItemStyles) { + // Define the parameters that are passed to the style functions. + const params = { level, disabled, active, isSubmenu: false } + + // Get the style function for the specified element. + const styleFunction = menuItemStyles[element] + + if (styleFunction) { + // If the style function is a function, call it and return the result. + // Otherwise, return the style function itself. + return typeof styleFunction === 'function' ? styleFunction(params) : styleFunction + } + } + } + + // Handle the click event. + const handleClick = () => { + if (isToggled) { + toggleVerticalNav() + } + } + + // Change active state when the url changes + useEffect(() => { + const href = rest.href + + if (href) { + // Check if the current url matches any of the children urls + if (exactMatch ? pathname === href : activeUrl && pathname.includes(activeUrl)) { + setActive(true) + } else { + setActive(false) + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [pathname]) + + // Call the onActiveChange callback when the active state changes. + useUpdateEffect(() => { + onActiveChange?.(active) + }, [active]) + + return ( + + { + handleClick() + rest.onClick && rest.onClick(e) + }} + > + {/* Menu Item Icon */} + {renderMenuIcon({ + icon, + level, + active, + disabled, + renderExpandedMenuItemIcon, + styles: getMenuItemStyles('icon'), + isBreakpointReached + })} + + {/* Menu Item Prefix */} + {prefix && ( + + {prefix} + + )} + + {/* Menu Item Label */} + + {children} + + + {/* Menu Item Suffix */} + {suffix && ( + + {suffix} + + )} + + + ) +} + +export default forwardRef(MenuItem) diff --git a/front-urban/src/@menu/components/vertical-menu/MenuSection.tsx b/front-urban/src/@menu/components/vertical-menu/MenuSection.tsx new file mode 100644 index 0000000..5cd726a --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/MenuSection.tsx @@ -0,0 +1,121 @@ +'use client' + +// React Imports +import { forwardRef } from 'react' +import type { ForwardRefRenderFunction, CSSProperties, ReactElement, ReactNode } from 'react' + +// Third-party Imports +import classnames from 'classnames' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { MenuSectionStyles } from './Menu' +import type { ChildrenType, RootStylesType } from '../../types' + +// Hook Imports +import useVerticalMenu from '../../hooks/useVerticalMenu' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' + +// Styled Component Imports +import StyledMenuIcon from '../../styles/StyledMenuIcon' +import StyledMenuPrefix from '../../styles/StyledMenuPrefix' +import StyledMenuSuffix from '../../styles/StyledMenuSuffix' +import StyledMenuSectionLabel from '../../styles/StyledMenuSectionLabel' +import StyledVerticalMenuSection from '../../styles/vertical/StyledVerticalMenuSection' + +export type MenuSectionProps = Partial & + RootStylesType & { + label: ReactNode + icon?: ReactElement + prefix?: ReactNode + suffix?: ReactNode + + /** + * @ignore + */ + className?: string + } + +type MenuSectionElement = keyof MenuSectionStyles + +const menuSectionWrapperStyles: CSSProperties = { + display: 'inline-block', + inlineSize: '100%', + position: 'relative', + listStyle: 'none', + padding: 0, + overflow: 'hidden' +} + +const menuSectionContentStyles: CSSProperties = { + display: 'flex', + alignItems: 'center', + inlineSize: '100%', + position: 'relative', + paddingBlock: '0.75rem', + paddingInline: '1.25rem', + overflow: 'hidden' +} + +const MenuSection: ForwardRefRenderFunction = (props, ref) => { + // Props + const { children, icon, className, prefix, suffix, label, rootStyles, ...rest } = props + + // Hooks + const { menuSectionStyles, textTruncate } = useVerticalMenu() + + const getMenuSectionStyles = (element: MenuSectionElement): CSSObject | undefined => { + // If the menuSectionStyles prop is provided, get the styles for the element from the prop + if (menuSectionStyles) { + return menuSectionStyles[element] + } + } + + return ( + // eslint-disable-next-line lines-around-comment + // Menu Section + + {/* Menu Section Content Wrapper */} +
    + {/* Menu Section Content */} +
  • + {icon && ( + + {icon} + + )} + {prefix && ( + + {prefix} + + )} + {label && ( + + {label} + + )} + {suffix && ( + + {suffix} + + )} +
  • + {/* Render Child */} + {children} +
+
+ ) +} + +export default forwardRef(MenuSection) diff --git a/front-urban/src/@menu/components/vertical-menu/NavHeader.tsx b/front-urban/src/@menu/components/vertical-menu/NavHeader.tsx new file mode 100644 index 0000000..052a886 --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/NavHeader.tsx @@ -0,0 +1,22 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { ChildrenType } from '../../types' + +// Util Imports +import { verticalNavClasses } from '../../utils/menuClasses' + +const StyledNavHeader = styled.div` + padding: 15px; + padding-inline-start: 20px; + display: flex; + align-items: center; + justify-content: space-between; +` + +const NavHeader = ({ children }: ChildrenType) => { + return {children} +} + +export default NavHeader diff --git a/front-urban/src/@menu/components/vertical-menu/SubMenu.tsx b/front-urban/src/@menu/components/vertical-menu/SubMenu.tsx new file mode 100644 index 0000000..0d366ca --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/SubMenu.tsx @@ -0,0 +1,332 @@ +'use client' + +// React Imports +import { Children, cloneElement, forwardRef, useEffect, useId, useRef, useState } from 'react' +import type { + AnchorHTMLAttributes, + ForwardRefRenderFunction, + KeyboardEvent, + MouseEvent, + ReactElement, + ReactNode +} from 'react' + +// Next Imports +import { usePathname } from 'next/navigation' + +// Third-party Imports +import classnames from 'classnames' +import styled from '@emotion/styled' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { OpenSubmenu } from './Menu' +import type { MenuItemProps } from './MenuItem' +import type { ChildrenType, RootStylesType, SubMenuItemElement } from '../../types' + +// Component Imports +import SubMenuContent from './SubMenuContent' +import MenuButton, { menuButtonStyles } from './MenuButton' + +// Icon Imports +import ChevronRight from '../../svg/ChevronRight' + +// Hook Imports +import useVerticalNav from '../../hooks/useVerticalNav' +import useVerticalMenu from '../../hooks/useVerticalMenu' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' +import { confirmUrlInChildren, renderMenuIcon } from '../../utils/menuUtils' + +// Styled Component Imports +import StyledMenuLabel from '../../styles/StyledMenuLabel' +import StyledMenuPrefix from '../../styles/StyledMenuPrefix' +import StyledMenuSuffix from '../../styles/StyledMenuSuffix' +import StyledVerticalNavExpandIcon, { + StyledVerticalNavExpandIconWrapper +} from '../../styles/vertical/StyledVerticalNavExpandIcon' + +export type SubMenuProps = Omit, 'prefix'> & + RootStylesType & + Partial & { + label: ReactNode + icon?: ReactElement + prefix?: ReactNode + suffix?: ReactNode + defaultOpen?: boolean + disabled?: boolean + contentClassName?: string + onOpenChange?: (open: boolean) => void + + /** + * @ignore + */ + level?: number + } + +type StyledSubMenuProps = Pick & { + level: number + active?: boolean + menuItemStyles?: CSSObject + buttonStyles?: CSSObject +} + +const StyledSubMenu = styled.li` + position: relative; + inline-size: 100%; + margin-block-start: 4px; + + &.${menuClasses.open} > .${menuClasses.button} { + background-color: #f3f3f3; + } + + ${({ menuItemStyles }) => menuItemStyles}; + ${({ rootStyles }) => rootStyles}; + + > .${menuClasses.button} { + ${({ level, disabled, active, children }) => + menuButtonStyles({ + level, + active, + disabled, + children + })}; + ${({ buttonStyles }) => buttonStyles}; + } +` + +const SubMenu: ForwardRefRenderFunction = (props, ref) => { + // Props + const { + children, + className, + contentClassName, + label, + icon, + title, + prefix, + suffix, + defaultOpen, + level = 0, + disabled = false, + rootStyles, + onOpenChange, + onClick, + onKeyUp, + ...rest + } = props + + // States + const [active, setActive] = useState(false) + + // Refs + const contentRef = useRef(null) + + // Hooks + const id = useId() + const pathname = usePathname() + const { isBreakpointReached } = useVerticalNav() + + const { + renderExpandIcon, + renderExpandedMenuItemIcon, + menuItemStyles, + openSubmenu, + toggleOpenSubmenu, + transitionDuration, + openSubmenusRef, + textTruncate + } = useVerticalMenu() + + // Vars + // Filter out falsy values from children + const childNodes = Children.toArray(children).filter(Boolean) as [ReactElement] + + const isSubMenuOpen = openSubmenu?.some((item: OpenSubmenu) => item.id === id) ?? false + + const handleSlideToggle = (): void => { + toggleOpenSubmenu?.({ level, label, active, id }) + onOpenChange?.(!isSubMenuOpen) + if (openSubmenusRef?.current && openSubmenusRef?.current.length > 0) openSubmenusRef.current = [] + } + + const handleOnClick = (event: MouseEvent) => { + onClick?.(event) + handleSlideToggle() + } + + const handleOnKeyUp = (event: KeyboardEvent) => { + onKeyUp?.(event) + + if (event.key === 'Enter') { + handleSlideToggle() + } + } + + const getSubMenuItemStyles = (element: SubMenuItemElement): CSSObject | undefined => { + // If the menuItemStyles prop is provided, get the styles for the specified element. + if (menuItemStyles) { + // Define the parameters that are passed to the style functions. + const params = { + level, + disabled, + active, + isSubmenu: true, + open: isSubMenuOpen + } + + // Get the style function for the specified element. + const styleFunction = menuItemStyles[element] + + if (styleFunction) { + // If the style function is a function, call it and return the result. + // Otherwise, return the style function itself. + return typeof styleFunction === 'function' ? styleFunction(params) : styleFunction + } + } + } + + useEffect(() => { + if (confirmUrlInChildren(children, pathname)) { + openSubmenusRef?.current.push({ level, label, active: true, id }) + } else { + if (defaultOpen) { + openSubmenusRef?.current.push({ level, label, active: false, id }) + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + // Change active state when the url changes + useEffect(() => { + // Check if the current url matches any of the children urls + if (confirmUrlInChildren(children, pathname)) { + setActive(true) + + if (openSubmenusRef?.current.findIndex(submenu => submenu.id === id) === -1) { + openSubmenusRef?.current.push({ level, label, active: true, id }) + } + } else { + setActive(false) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [pathname]) + + /* useEffect(() => { + console.log(openSubmenu) + }, [openSubmenu]) */ + + const submenuContent = ( + + {childNodes.map(node => + cloneElement(node, { + level: level + 1 + }) + )} + + ) + + return ( + // eslint-disable-next-line lines-around-comment + /* Sub Menu */ + + {/* Menu Item */} + + {/* Sub Menu Icon */} + {renderMenuIcon({ + icon, + level, + active, + disabled, + renderExpandedMenuItemIcon, + styles: getSubMenuItemStyles('icon'), + isBreakpointReached + })} + + {/* Sub Menu Prefix */} + {prefix && ( + + {prefix} + + )} + + {/* Sub Menu Label */} + + {label} + + + {/* Sub Menu Suffix */} + {suffix && ( + + {suffix} + + )} + + {/* Sub Menu Toggle Icon Wrapper */} + { + + {renderExpandIcon ? ( + renderExpandIcon({ + level, + disabled, + active, + open: isSubMenuOpen + }) + ) : ( + // eslint-disable-next-line lines-around-comment + /* Expanded Arrow Icon */ + + + + )} + + } + + + {/* Sub Menu Content */} + {submenuContent} + + ) +} + +export default forwardRef(SubMenu) diff --git a/front-urban/src/@menu/components/vertical-menu/SubMenuContent.tsx b/front-urban/src/@menu/components/vertical-menu/SubMenuContent.tsx new file mode 100644 index 0000000..65e8f43 --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/SubMenuContent.tsx @@ -0,0 +1,84 @@ +// React Imports +import { forwardRef, useEffect, useState } from 'react' +import type { ForwardRefRenderFunction, HTMLAttributes, MutableRefObject } from 'react' + +// Type Imports +import type { VerticalMenuContextProps } from './Menu' +import type { ChildrenType, RootStylesType } from '../../types' + +// Styled Component Imports +import StyledSubMenuContent from '../../styles/StyledSubMenuContent' + +// Style Imports +import styles from '../../styles/styles.module.css' + +export type SubMenuContentProps = HTMLAttributes & + RootStylesType & + Partial & { + open?: boolean + transitionDuration?: VerticalMenuContextProps['transitionDuration'] + level?: number + } + +const SubMenuContent: ForwardRefRenderFunction = (props, ref) => { + // Props + const { children, open, level, transitionDuration, ...rest } = props + + // States + const [mounted, setMounted] = useState(false) + + // Refs + const SubMenuContentRef = ref as MutableRefObject + + useEffect(() => { + if (mounted) { + if (open) { + const target = SubMenuContentRef?.current + + if (target) { + target.style.display = 'block' + target.style.overflow = 'hidden' + target.style.blockSize = 'auto' + const height = target.offsetHeight + + target.style.blockSize = '0px' + target.offsetHeight + + target.style.blockSize = `${height}px` + + setTimeout(() => { + target.style.overflow = 'auto' + target.style.blockSize = 'auto' + }, transitionDuration) + } + } else { + const target = SubMenuContentRef?.current + + if (target) { + target.style.overflow = 'hidden' + target.style.blockSize = `${target.offsetHeight}px` + target.offsetHeight + target.style.blockSize = '0px' + + setTimeout(() => { + target.style.overflow = 'auto' + target.style.display = 'none' + }, transitionDuration) + } + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open, mounted, SubMenuContentRef]) + + useEffect(() => { + setMounted(true) + }, []) + + return ( + +
    {children}
+
+ ) +} + +export default forwardRef(SubMenuContent) diff --git a/front-urban/src/@menu/components/vertical-menu/VerticalNav.tsx b/front-urban/src/@menu/components/vertical-menu/VerticalNav.tsx new file mode 100644 index 0000000..1c96eb6 --- /dev/null +++ b/front-urban/src/@menu/components/vertical-menu/VerticalNav.tsx @@ -0,0 +1,138 @@ +'use client' + +// React Imports +import { useEffect } from 'react' +import type { HTMLAttributes } from 'react' + +// Third-party Imports +import classnames from 'classnames' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { BreakpointType } from '../../types' + +// Context Imports +import type { VerticalNavState } from '../../contexts/verticalNavContext' + +// Hook Imports +import useMediaQuery from '../../hooks/useMediaQuery' +import useVerticalNav from '../../hooks/useVerticalNav' + +// Util Imports +import { verticalNavClasses } from '../../utils/menuClasses' + +// Styled Component Imports +import StyledBackdrop from '../../styles/StyledBackdrop' +import StyledVerticalNav from '../../styles/vertical/StyledVerticalNav' +import StyledVerticalNavContainer from '../../styles/vertical/StyledVerticalNavContainer' +import StyledVerticalNavBgColorContainer from '../../styles/vertical/StyledVerticalNavBgColorContainer' + +// Default Config Imports +import { defaultBreakpoints, verticalNavToggleDuration } from '../../defaultConfigs' + +export type VerticalNavProps = HTMLAttributes & { + width?: VerticalNavState['width'] + breakpoint?: BreakpointType + customBreakpoint?: string + breakpoints?: Partial + transitionDuration?: VerticalNavState['transitionDuration'] + backdropColor?: string + customStyles?: CSSObject +} + +const VerticalNav = (props: VerticalNavProps) => { + // Props + const { + width = 260, + breakpoint = 'lg', + customBreakpoint, + breakpoints, + transitionDuration = verticalNavToggleDuration, + backdropColor, + className, + customStyles, + children, + ...rest + } = props + + // Vars + const mergedBreakpoints = { ...defaultBreakpoints, ...breakpoints } + + // Hooks + const { + updateVerticalNavState, + width: widthContext, + isBreakpointReached: isBreakpointReachedContext, + isToggled: isToggledContext, + transitionDuration: transitionDurationContext + } = useVerticalNav() + + // Find the breakpoint from which screen size responsive behavior should enable and if its reached or not + const breakpointReached = useMediaQuery(customBreakpoint ?? (breakpoint ? mergedBreakpoints[breakpoint] : breakpoint)) + + // UseEffect, update verticalNav state to set initial values and update values on change + useEffect(() => { + updateVerticalNavState({ + width, + transitionDuration, + isBreakpointReached: breakpointReached + }) + + if (!breakpointReached) { + updateVerticalNavState({ isToggled: false }) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [width, breakpointReached, updateVerticalNavState]) + + // Handle Backdrop(Content Overlay) Click + const handleBackdropClick = () => { + // Close the verticalNav + updateVerticalNavState({ isToggled: false }) + } + + return ( + + + {/* VerticalNav Container to apply styling like background */} + + {children} + + + + {/* When verticalNav is toggled on smaller screen, show/hide verticalNav backdrop */} + {isToggledContext && breakpointReached && ( + // eslint-disable-next-line lines-around-comment + /* VerticalNav Backdrop */ + + )} + + ) +} + +export default VerticalNav diff --git a/front-urban/src/@menu/contexts/verticalNavContext.tsx b/front-urban/src/@menu/contexts/verticalNavContext.tsx new file mode 100644 index 0000000..0a9fadc --- /dev/null +++ b/front-urban/src/@menu/contexts/verticalNavContext.tsx @@ -0,0 +1,54 @@ +'use client' + +// React Imports +import { createContext, useCallback, useMemo, useState } from 'react' + +// Type Imports +import type { ChildrenType } from '../types' + +export type VerticalNavState = { + width?: number + isToggled?: boolean + isBreakpointReached?: boolean + transitionDuration?: number +} + +export type VerticalNavContextProps = VerticalNavState & { + updateVerticalNavState: (values: VerticalNavState) => void + toggleVerticalNav: (value?: VerticalNavState['isToggled']) => void +} + +const VerticalNavContext = createContext({} as VerticalNavContextProps) + +export const VerticalNavProvider = ({ children }: ChildrenType) => { + // States + const [verticalNavState, setVerticalNavState] = useState() + + // Hooks + const updateVerticalNavState = useCallback((values: Partial) => { + setVerticalNavState(prevState => ({ + ...prevState, + ...values + })) + }, []) + + const toggleVerticalNav = useCallback((value?: boolean) => { + setVerticalNavState(prevState => ({ + ...prevState, + isToggled: value !== undefined ? Boolean(value) : !Boolean(prevState?.isToggled) + })) + }, []) + + const verticalNavProviderValue = useMemo( + () => ({ + ...verticalNavState, + updateVerticalNavState, + toggleVerticalNav + }), + [verticalNavState, updateVerticalNavState, toggleVerticalNav] + ) + + return {children} +} + +export default VerticalNavContext diff --git a/front-urban/src/@menu/defaultConfigs.ts b/front-urban/src/@menu/defaultConfigs.ts new file mode 100644 index 0000000..9ff98f8 --- /dev/null +++ b/front-urban/src/@menu/defaultConfigs.ts @@ -0,0 +1,15 @@ +// Type Imports +import type { BreakpointType } from './types' + +export const defaultBreakpoints: Record = { + xs: '480px', + sm: '600px', + md: '900px', + lg: '1200px', + xl: '1536px', + xxl: '1920px', + always: 'always' +} + +export const verticalNavToggleDuration = 300 +export const verticalSubMenuToggleDuration = 300 diff --git a/front-urban/src/@menu/hooks/useMediaQuery.tsx b/front-urban/src/@menu/hooks/useMediaQuery.tsx new file mode 100644 index 0000000..559e839 --- /dev/null +++ b/front-urban/src/@menu/hooks/useMediaQuery.tsx @@ -0,0 +1,29 @@ +'use client' + +// React Imports +import { useEffect, useState } from 'react' + +const useMediaQuery = (breakpoint?: string): boolean => { + // States + const [matches, setMatches] = useState(breakpoint === 'always') + + useEffect(() => { + if (breakpoint && breakpoint !== 'always') { + const media = window.matchMedia(`(max-width: ${breakpoint})`) + + if (media.matches !== matches) { + setMatches(media.matches) + } + + const listener = () => setMatches(media.matches) + + window.addEventListener('resize', listener) + + return () => window.removeEventListener('resize', listener) + } + }, [matches, breakpoint]) + + return matches +} + +export default useMediaQuery diff --git a/front-urban/src/@menu/hooks/useVerticalMenu.tsx b/front-urban/src/@menu/hooks/useVerticalMenu.tsx new file mode 100644 index 0000000..c9c09b8 --- /dev/null +++ b/front-urban/src/@menu/hooks/useVerticalMenu.tsx @@ -0,0 +1,21 @@ +// React Imports +import { useContext } from 'react' + +// Type Imports +import type { VerticalMenuContextProps } from '../components/vertical-menu/Menu' + +// Context Imports +import { VerticalMenuContext } from '../components/vertical-menu/Menu' + +const useVerticalMenu = (): VerticalMenuContextProps => { + // Hooks + const context = useContext(VerticalMenuContext) + + if (context === undefined) { + throw new Error('Menu Component is required!') + } + + return context +} + +export default useVerticalMenu diff --git a/front-urban/src/@menu/hooks/useVerticalNav.tsx b/front-urban/src/@menu/hooks/useVerticalNav.tsx new file mode 100644 index 0000000..21a01db --- /dev/null +++ b/front-urban/src/@menu/hooks/useVerticalNav.tsx @@ -0,0 +1,18 @@ +// React Imports +import { useContext } from 'react' + +// Context Imports +import VerticalNavContext from '../contexts/verticalNavContext' + +const useVerticalNav = () => { + // Hooks + const context = useContext(VerticalNavContext) + + if (context === undefined) { + throw new Error('VerticalNav Component is required!') + } + + return context +} + +export default useVerticalNav diff --git a/front-urban/src/@menu/styles/StyledBackdrop.tsx b/front-urban/src/@menu/styles/StyledBackdrop.tsx new file mode 100644 index 0000000..a4e94cd --- /dev/null +++ b/front-urban/src/@menu/styles/StyledBackdrop.tsx @@ -0,0 +1,20 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { VerticalNavProps } from '../vertical-menu' + +type StyledBackdropProps = Pick + +const StyledBackdrop = styled.div` + position: fixed; + inset-inline-start: 0; + inset-block-start: 0; + inset-inline-end: 0; + inset-block-end: 0; + z-index: 1; + background-color: ${({ backdropColor }) => backdropColor || 'rgba(0, 0, 0, 0.3)'}; + touch-action: none; +` + +export default StyledBackdrop diff --git a/front-urban/src/@menu/styles/StyledMenuIcon.tsx b/front-urban/src/@menu/styles/StyledMenuIcon.tsx new file mode 100644 index 0000000..efe30ea --- /dev/null +++ b/front-urban/src/@menu/styles/StyledMenuIcon.tsx @@ -0,0 +1,15 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { RootStylesType } from '../types' + +const StyledMenuIcon = styled.span` + display: flex; + align-items: center; + justify-content: center; + margin-inline-end: 10px; + ${({ rootStyles }) => rootStyles}; +` + +export default StyledMenuIcon diff --git a/front-urban/src/@menu/styles/StyledMenuLabel.tsx b/front-urban/src/@menu/styles/StyledMenuLabel.tsx new file mode 100644 index 0000000..5d66fd7 --- /dev/null +++ b/front-urban/src/@menu/styles/StyledMenuLabel.tsx @@ -0,0 +1,23 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { RootStylesType } from '../types' + +type StyledMenuLabelProps = RootStylesType & { + textTruncate?: boolean +} + +const StyledMenuLabel = styled.span` + flex-grow: 1; + ${({ textTruncate }) => + textTruncate && + ` + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + `}; + ${({ rootStyles }) => rootStyles}; +` + +export default StyledMenuLabel diff --git a/front-urban/src/@menu/styles/StyledMenuPrefix.tsx b/front-urban/src/@menu/styles/StyledMenuPrefix.tsx new file mode 100644 index 0000000..75af5ad --- /dev/null +++ b/front-urban/src/@menu/styles/StyledMenuPrefix.tsx @@ -0,0 +1,15 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { RootStylesType } from '../types' + +type StyledMenuPrefixProps = RootStylesType + +const StyledMenuPrefix = styled.span` + margin-inline-end: 5px; + display: flex; + ${({ rootStyles }) => rootStyles}; +` + +export default StyledMenuPrefix diff --git a/front-urban/src/@menu/styles/StyledMenuSectionLabel.tsx b/front-urban/src/@menu/styles/StyledMenuSectionLabel.tsx new file mode 100644 index 0000000..5b6994f --- /dev/null +++ b/front-urban/src/@menu/styles/StyledMenuSectionLabel.tsx @@ -0,0 +1,22 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { RootStylesType } from '../types' + +type StyledMenuSectionLabelProps = RootStylesType & { + textTruncate?: boolean +} + +const StyledMenuSectionLabel = styled.span` + ${({ textTruncate }) => + textTruncate && + ` + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + `}; + ${({ rootStyles }) => rootStyles}; +` + +export default StyledMenuSectionLabel diff --git a/front-urban/src/@menu/styles/StyledMenuSuffix.tsx b/front-urban/src/@menu/styles/StyledMenuSuffix.tsx new file mode 100644 index 0000000..8010870 --- /dev/null +++ b/front-urban/src/@menu/styles/StyledMenuSuffix.tsx @@ -0,0 +1,15 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { RootStylesType } from '../types' + +type StyledMenuSuffixProps = RootStylesType + +const StyledMenuSuffix = styled.span` + margin-inline-start: 5px; + display: flex; + ${({ rootStyles }) => rootStyles}; +` + +export default StyledMenuSuffix diff --git a/front-urban/src/@menu/styles/StyledSubMenuContent.tsx b/front-urban/src/@menu/styles/StyledSubMenuContent.tsx new file mode 100644 index 0000000..faac2e7 --- /dev/null +++ b/front-urban/src/@menu/styles/StyledSubMenuContent.tsx @@ -0,0 +1,19 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { SubMenuContentProps } from '../components/vertical-menu/SubMenuContent' + +const StyledSubMenuContent = styled.div` + display: none; + overflow: hidden; + z-index: 999; + transition: ${({ transitionDuration }) => `block-size ${transitionDuration}ms ease-in-out`}; + box-sizing: border-box; + position: static !important; + transform: none !important; + + ${({ rootStyles }) => rootStyles}; +` + +export default StyledSubMenuContent diff --git a/front-urban/src/@menu/styles/styles.module.css b/front-urban/src/@menu/styles/styles.module.css new file mode 100644 index 0000000..729a589 --- /dev/null +++ b/front-urban/src/@menu/styles/styles.module.css @@ -0,0 +1,5 @@ +.ul { + list-style-type: none; + padding: 0; + margin: 0; +} diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalMenu.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalMenu.tsx new file mode 100644 index 0000000..ca3977d --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalMenu.tsx @@ -0,0 +1,19 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { MenuProps } from '../../components/vertical-menu/Menu' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' + +const StyledVerticalMenu = styled.nav>` + & > ul > :first-of-type { + margin-block-start: 0; + } + &.${menuClasses.root} { + ${({ rootStyles }) => rootStyles} + } +` + +export default StyledVerticalMenu diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalMenuItem.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalMenuItem.tsx new file mode 100644 index 0000000..7fb9b6c --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalMenuItem.tsx @@ -0,0 +1,36 @@ +// Third-party Imports +import styled from '@emotion/styled' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { MenuItemProps } from '../../components/vertical-menu/MenuItem' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' + +// Style Imports +import { menuButtonStyles } from '../../components/vertical-menu/MenuButton' + +type StyledVerticalMenuItemProps = Pick & { + level: number + menuItemStyles?: CSSObject + buttonStyles?: CSSObject +} + +const StyledVerticalMenuItem = styled.li` + position: relative; + margin-block-start: 4px; + ${({ menuItemStyles }) => menuItemStyles}; + ${({ rootStyles }) => rootStyles}; + + > .${menuClasses.button} { + ${({ level, disabled }) => + menuButtonStyles({ + level, + disabled + })}; + ${({ buttonStyles }) => buttonStyles}; + } +` + +export default StyledVerticalMenuItem diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalMenuSection.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalMenuSection.tsx new file mode 100644 index 0000000..378c73c --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalMenuSection.tsx @@ -0,0 +1,31 @@ +// Third-party Imports +import styled from '@emotion/styled' +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { MenuSectionProps } from '../../components/vertical-menu/MenuSection' + +// Util Imports +import { menuClasses } from '../../utils/menuClasses' + +type StyledVerticalMenuSectionProps = Pick & { + menuSectionStyles?: CSSObject +} + +const StyledVerticalMenuSection = styled.li` + display: flex; + inline-size: 100%; + position: relative; + overflow: hidden; + margin-block-start: 15px; + + & .${menuClasses.menuSectionContent} { + font-size: 14px; + color: #aaaaaa; + } + + ${({ menuSectionStyles }) => menuSectionStyles}; + ${({ rootStyles }) => rootStyles}; +` + +export default StyledVerticalMenuSection diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalNav.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalNav.tsx new file mode 100644 index 0000000..f3bd6d6 --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalNav.tsx @@ -0,0 +1,53 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { VerticalNavState } from '../../contexts/verticalNavContext' +import type { VerticalNavProps } from '../../components/vertical-menu/VerticalNav' + +// Util Imports +import { verticalNavClasses } from '../../utils/menuClasses' + +type StyledVerticalNavProps = VerticalNavProps & Pick + +const StyledVerticalNav = styled.aside` + position: sticky; + inset-block-start: 0; + block-size: 100dvh; + z-index: 9; + + /* Transition */ + transition-property: inline-size, min-inline-size, margin-inline-start, inset-inline-start; + transition-duration: ${({ transitionDuration }) => `${transitionDuration}ms`}; + transition-timing-function: ease-in-out; + + /* Width & Min Width & Margin */ + inline-size: ${({ width }) => `${width}px`}; + min-inline-size: ${({ width }) => `${width}px`}; + + /* Toggled */ + &.${verticalNavClasses.breakpointReached} { + position: fixed; + block-size: 100%; + inset-block-start: 0; + inset-inline-start: ${({ width }) => `-${width}px`}; + z-index: 100; + margin: 0; + &.${verticalNavClasses.toggled} { + inset-inline-start: 0; + } + } + + ${({ width, isBreakpointReached }) => + !isBreakpointReached && + ` + &.${verticalNavClasses.toggled} { + margin-inline-start: -${width}px; + } + `} + + /* User Styles */ + ${({ customStyles }) => customStyles} +` + +export default StyledVerticalNav diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalNavBgColorContainer.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalNavBgColorContainer.tsx new file mode 100644 index 0000000..aae728d --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalNavBgColorContainer.tsx @@ -0,0 +1,15 @@ +// Third-party Imports +import styled from '@emotion/styled' + +const StyledVerticalNavBgColorContainer = styled.div` + position: relative; + block-size: 100%; + z-index: 3; + display: flex; + flex-direction: column; + overflow-y: auto; + overflow-x: hidden; + background-color: white; +` + +export default StyledVerticalNavBgColorContainer diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalNavContainer.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalNavContainer.tsx new file mode 100644 index 0000000..99a394b --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalNavContainer.tsx @@ -0,0 +1,21 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { VerticalNavProps } from '../../components/vertical-menu/VerticalNav' + +type StyledVerticalNavContainerProps = Pick + +const StyledVerticalNavContainer = styled.div` + position: relative; + block-size: 100%; + inline-size: 100%; + border-inline-end: 1px solid #efefef; + + /* Transition */ + transition-property: inline-size, inset-inline-start; + transition-duration: ${({ transitionDuration }) => `${transitionDuration}ms`}; + transition-timing-function: ease-in-out; +` + +export default StyledVerticalNavContainer diff --git a/front-urban/src/@menu/styles/vertical/StyledVerticalNavExpandIcon.tsx b/front-urban/src/@menu/styles/vertical/StyledVerticalNavExpandIcon.tsx new file mode 100644 index 0000000..46d610c --- /dev/null +++ b/front-urban/src/@menu/styles/vertical/StyledVerticalNavExpandIcon.tsx @@ -0,0 +1,34 @@ +// Third-party Imports +import styled from '@emotion/styled' + +// Type Imports +import type { RootStylesType } from '../../types' +import type { VerticalMenuContextProps } from '../../components/vertical-menu/Menu' + +type StyledVerticalNavExpandIconProps = { + open?: boolean + transitionDuration?: VerticalMenuContextProps['transitionDuration'] +} + +export const StyledVerticalNavExpandIconWrapper = styled.span` + display: flex; + margin-inline-start: 5px; + ${({ rootStyles }) => rootStyles}; +` + +const StyledVerticalNavExpandIcon = styled.span` + display: flex; + + & > i, + & > svg { + transition: ${({ transitionDuration }) => `transform ${transitionDuration}ms ease-in-out`}; + ${({ open }) => open && 'transform: rotate(90deg);'} + + [dir='rtl'] & { + transform: rotate(180deg); + ${({ open }) => open && 'transform: rotate(90deg);'} + } + } +` + +export default StyledVerticalNavExpandIcon diff --git a/front-urban/src/@menu/svg/ChevronRight.tsx b/front-urban/src/@menu/svg/ChevronRight.tsx new file mode 100644 index 0000000..33182c6 --- /dev/null +++ b/front-urban/src/@menu/svg/ChevronRight.tsx @@ -0,0 +1,12 @@ +// React Imports +import type { SVGAttributes } from 'react' + +const ChevronRight = (props: SVGAttributes) => { + return ( + + + + ) +} + +export default ChevronRight diff --git a/front-urban/src/@menu/svg/Close.tsx b/front-urban/src/@menu/svg/Close.tsx new file mode 100644 index 0000000..324eec4 --- /dev/null +++ b/front-urban/src/@menu/svg/Close.tsx @@ -0,0 +1,15 @@ +// React Imports +import type { SVGAttributes } from 'react' + +const Close = (props: SVGAttributes) => { + return ( + + + + ) +} + +export default Close diff --git a/front-urban/src/@menu/types.ts b/front-urban/src/@menu/types.ts new file mode 100644 index 0000000..8ee58fd --- /dev/null +++ b/front-urban/src/@menu/types.ts @@ -0,0 +1,92 @@ +// React Imports +import type { AnchorHTMLAttributes, ReactElement, ReactNode } from 'react' + +// Third-party Imports +import type { CSSObject } from '@emotion/styled' + +export type ChildrenType = { + children: ReactNode +} + +// Breakpoints +export type BreakpointType = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'always' + +// Exact match for active URL in menu item +export type MenuItemExactMatchUrlProps = + | { + exactMatch: true + activeUrl?: never + } + | { + exactMatch: false + activeUrl: string + } + | { + exactMatch?: never + activeUrl?: never + } + +// Menu Item Elements for styling +export type MenuItemElement = 'root' | 'button' | 'icon' | 'label' | 'prefix' | 'suffix' + +// Sub Menu Item Elements for styling +export type SubMenuItemElement = + | 'root' + | 'button' + | 'label' + | 'prefix' + | 'suffix' + | 'icon' + | 'subMenuStyles' + | 'subMenuContent' + | 'subMenuExpandIcon' + +// Menu Button Props +export type MenuButtonProps = Omit, 'prefix'> & Partial + +// Menu Item Styles Params Type +export type MenuItemStylesParams = { + level: number + disabled: boolean + active?: boolean + isSubmenu: boolean + open?: boolean +} + +// Menu Item Style Elements Type +export type ElementStyles = CSSObject | ((params: MenuItemStylesParams) => CSSObject | undefined) + +// Menu Item Styles Type +export type MenuItemStyles = { + root?: ElementStyles + button?: ElementStyles + label?: ElementStyles + prefix?: ElementStyles + suffix?: ElementStyles + icon?: ElementStyles + subMenuStyles?: ElementStyles + subMenuContent?: ElementStyles + subMenuExpandIcon?: ElementStyles +} + +// Expand Icon +export type RenderExpandIconParams = { + open: boolean + level: number + active: boolean + disabled: boolean +} + +// Icon for menu items in expanded submenu +export type RenderExpandedMenuItemIcon = { + icon: + | ReactElement + | ((params: { level?: number; active?: boolean; disabled?: boolean }) => ReactElement | null) + | null + level?: number +} + +// Root Styles +export type RootStylesType = { + rootStyles?: CSSObject +} diff --git a/front-urban/src/@menu/utils/menuClasses.ts b/front-urban/src/@menu/utils/menuClasses.ts new file mode 100644 index 0000000..0f187b3 --- /dev/null +++ b/front-urban/src/@menu/utils/menuClasses.ts @@ -0,0 +1,31 @@ +// Common classes for menu components +export const menuClasses = { + root: 'ts-menu-root', + menuSectionRoot: 'ts-menusection-root', + menuItemRoot: 'ts-menuitem-root', + subMenuRoot: 'ts-submenu-root', + button: 'ts-menu-button', + prefix: 'ts-menu-prefix', + suffix: 'ts-menu-suffix', + label: 'ts-menu-label', + icon: 'ts-menu-icon', + menuSectionWrapper: 'ts-menu-section-wrapper', + menuSectionContent: 'ts-menu-section-content', + menuSectionLabel: 'ts-menu-section-label', + subMenuContent: 'ts-submenu-content', + subMenuExpandIcon: 'ts-submenu-expand-icon', + disabled: 'ts-disabled', + active: 'ts-active', + open: 'ts-open' +} + +// Classes for vertical navigation menu +export const verticalNavClasses = { + root: 'ts-vertical-nav-root', + container: 'ts-vertical-nav-container', + bgColorContainer: 'ts-vertical-nav-bg-color-container', + header: 'ts-vertical-nav-header', + backdrop: 'ts-vertical-nav-backdrop', + toggled: 'ts-toggled', + breakpointReached: 'ts-breakpoint-reached' +} diff --git a/front-urban/src/@menu/utils/menuUtils.tsx b/front-urban/src/@menu/utils/menuUtils.tsx new file mode 100644 index 0000000..d573b4e --- /dev/null +++ b/front-urban/src/@menu/utils/menuUtils.tsx @@ -0,0 +1,93 @@ +// React Imports +import { isValidElement } from 'react' +import type { ReactElement, ReactNode } from 'react' + +// Third-party Imports +import type { CSSObject } from '@emotion/styled' + +// Type Imports +import type { ChildrenType, RenderExpandedMenuItemIcon } from '../types' + +// Util Imports +import { menuClasses } from './menuClasses' + +// Styled Component Imports +import StyledMenuIcon from '../styles/StyledMenuIcon' + +type RenderMenuIconParams = { + level?: number + active?: boolean + disabled?: boolean + styles?: CSSObject + icon?: ReactElement + renderExpandedMenuItemIcon?: RenderExpandedMenuItemIcon + isBreakpointReached?: boolean +} + +export const confirmUrlInChildren = (children: ChildrenType['children'], url: string): boolean => { + if (!children) { + return false + } + + if (Array.isArray(children)) { + return children.some((child: ReactNode) => confirmUrlInChildren(child, url)) + } + + if (isValidElement(children)) { + const { component, href, exactMatch, activeUrl, children: subChildren } = children.props + + if (component && component.props.href) { + return exactMatch === true || exactMatch === undefined + ? component.props.href === url + : activeUrl && url.includes(activeUrl) + } + + if (href) { + return exactMatch === true || exactMatch === undefined ? href === url : activeUrl && url.includes(activeUrl) + } + + if (subChildren) { + return confirmUrlInChildren(subChildren, url) + } + } + + return false +} + +/* + * Render all the icons for Menu Item and SubMenu components for all the levels more than 0 + */ +export const renderMenuIcon = (params: RenderMenuIconParams) => { + const { icon, level, active, disabled, styles, renderExpandedMenuItemIcon, isBreakpointReached } = params + + if (icon && (level === 0 || (!isBreakpointReached && level && level > 0))) { + return ( + + {icon} + + ) + } + + if ( + level && + level !== 0 && + renderExpandedMenuItemIcon && + renderExpandedMenuItemIcon.icon !== null && + (!renderExpandedMenuItemIcon.level || renderExpandedMenuItemIcon.level >= level) + ) { + const iconToRender = + typeof renderExpandedMenuItemIcon.icon === 'function' + ? renderExpandedMenuItemIcon.icon({ level, active, disabled }) + : renderExpandedMenuItemIcon.icon + + if (iconToRender) { + return ( + + {iconToRender} + + ) + } + } + + return null +} diff --git a/front-urban/src/@menu/vertical-menu/index.tsx b/front-urban/src/@menu/vertical-menu/index.tsx new file mode 100644 index 0000000..31b5284 --- /dev/null +++ b/front-urban/src/@menu/vertical-menu/index.tsx @@ -0,0 +1,16 @@ +// Import all Vertical Nav components and export them +import Menu from '../components/vertical-menu/Menu' +import SubMenu from '../components/vertical-menu/SubMenu' +import MenuItem from '../components/vertical-menu/MenuItem' +import NavHeader from '../components/vertical-menu/NavHeader' +import VerticalNav from '../components/vertical-menu/VerticalNav' +import MenuSection from '../components/vertical-menu/MenuSection' +import type { MenuProps } from '../components/vertical-menu/Menu' +import type { SubMenuProps } from '../components/vertical-menu/SubMenu' +import type { MenuItemProps } from '../components/vertical-menu/MenuItem' +import type { MenuSectionProps } from '../components/vertical-menu/MenuSection' +import type { VerticalNavProps } from '../components/vertical-menu/VerticalNav' + +export default VerticalNav +export { Menu, MenuItem, SubMenu, MenuSection, NavHeader } +export type { VerticalNavProps, MenuProps, MenuItemProps, SubMenuProps, MenuSectionProps } diff --git a/front-urban/src/app/(blank-layout-pages)/error/page.tsx b/front-urban/src/app/(blank-layout-pages)/error/page.tsx new file mode 100644 index 0000000..52e48c6 --- /dev/null +++ b/front-urban/src/app/(blank-layout-pages)/error/page.tsx @@ -0,0 +1,14 @@ +// Component Imports +import NotFound from '@views/NotFound' + +// Server Action Imports +import { getServerMode } from '@core/utils/serverHelpers' + +const Error = () => { + // Vars + const mode = getServerMode() + + return +} + +export default Error diff --git a/front-urban/src/app/(blank-layout-pages)/layout.tsx b/front-urban/src/app/(blank-layout-pages)/layout.tsx new file mode 100644 index 0000000..f6ae45a --- /dev/null +++ b/front-urban/src/app/(blank-layout-pages)/layout.tsx @@ -0,0 +1,19 @@ +// Type Imports +import type { ChildrenType } from '@core/types' + +// Component Imports +import Providers from '@components/Providers' +import BlankLayout from '@layouts/BlankLayout' + +const Layout = ({ children }: ChildrenType) => { + // Vars + const direction = 'ltr' + + return ( + + {children} + + ) +} + +export default Layout diff --git a/front-urban/src/app/(blank-layout-pages)/under-maintenance/page.tsx b/front-urban/src/app/(blank-layout-pages)/under-maintenance/page.tsx new file mode 100644 index 0000000..d9bff30 --- /dev/null +++ b/front-urban/src/app/(blank-layout-pages)/under-maintenance/page.tsx @@ -0,0 +1,14 @@ +// Component Imports +import UnderMaintenance from '@views/pages/misc/UnderMaintenance' + +// Server Action Imports +import { getServerMode } from '@core/utils/serverHelpers' + +const UnderMaintenancePage = () => { + // Vars + const mode = getServerMode() + + return +} + +export default UnderMaintenancePage diff --git a/front-urban/src/app/(dashboard)/account-settings/page.tsx b/front-urban/src/app/(dashboard)/account-settings/page.tsx new file mode 100644 index 0000000..cda6d0c --- /dev/null +++ b/front-urban/src/app/(dashboard)/account-settings/page.tsx @@ -0,0 +1,25 @@ +// React Imports +import type { ReactElement } from 'react' + +// Next Imports +import dynamic from 'next/dynamic' + +// Component Imports +import AccountSettings from '@views/account-settings' + +const AccountTab = dynamic(() => import('@views/account-settings/account')) +const NotificationsTab = dynamic(() => import('@views/account-settings/notifications')) +const ConnectionsTab = dynamic(() => import('@views/account-settings/connections')) + +// Vars +const tabContentList = (): { [key: string]: ReactElement } => ({ + account: , + notifications: , + connections: +}) + +const AccountSettingsPage = () => { + return +} + +export default AccountSettingsPage diff --git a/front-urban/src/app/(dashboard)/card-basic/page.tsx b/front-urban/src/app/(dashboard)/card-basic/page.tsx new file mode 100644 index 0000000..876dbbc --- /dev/null +++ b/front-urban/src/app/(dashboard)/card-basic/page.tsx @@ -0,0 +1,87 @@ +// MUI Imports +import Grid from '@mui/material/Grid' +import Typography from '@mui/material/Typography' +import Divider from '@mui/material/Divider' + +// Components Imports +import CardInfluencingInfluencerWithImg from '@views/card-basic/CardInfluencingInfluencerWithImg' +import CardUser from '@views/card-basic/CardUser' +import CardWithCollapse from '@views/card-basic/CardWithCollapse' +import CardMobile from '@views/card-basic/CardMobile' +import CardHorizontalRatings from '@views/card-basic/CardHorizontalRatings' +import CardWatch from '@views/card-basic/CardWatch' +import CardLifetimeMembership from '@views/card-basic/CardLifetimeMembership' +import CardInfluencingInfluencer from '@views/card-basic/CardInfluencingInfluencer' +import CardVerticalRatings from '@views/card-basic/CardVerticalRatings' +import CardSupport from '@views/card-basic/CardSupport' +import CardWithTabs from '@views/card-basic/CardWithTabs' +import CardWithTabsCenter from '@views/card-basic/CardWithTabsCenter' +import CardTwitter from '@views/card-basic/CardTwitter' +import CardFacebook from '@views/card-basic/CardFacebook' +import CardLinkedIn from '@views/card-basic/CardLinkedIn' + +const CardBasic = () => { + return ( + + + Basic Cards + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Navigation Cards + + + + + + + + + + Solid Cards + + + + + + + + + + + + + ) +} + +export default CardBasic diff --git a/front-urban/src/app/(dashboard)/clases/page.tsx b/front-urban/src/app/(dashboard)/clases/page.tsx new file mode 100644 index 0000000..223606b --- /dev/null +++ b/front-urban/src/app/(dashboard)/clases/page.tsx @@ -0,0 +1,12 @@ +import ClasesComponent from '@views/clases' + + + +const ClasesPage = () => { + + + return + +}; + +export default ClasesPage; diff --git a/front-urban/src/app/(dashboard)/configuracion/backup/page.tsx b/front-urban/src/app/(dashboard)/configuracion/backup/page.tsx new file mode 100644 index 0000000..c0f7315 --- /dev/null +++ b/front-urban/src/app/(dashboard)/configuracion/backup/page.tsx @@ -0,0 +1,426 @@ +'use client'; + +import React, { useState, useCallback, useEffect } from 'react'; +import { + Box, + Card, + CardContent, + Typography, + Button, + Divider, + Alert, + LinearProgress, + Chip, + IconButton, + Paper, + Dialog, + DialogTitle, + DialogContent, + CircularProgress, +} from '@mui/material'; +import { + CloudDownload as DownloadIcon, + CloudUpload as UploadIcon, + InsertDriveFile as FileIcon, + Delete as DeleteIcon, + Backup as BackupIcon, + Restore as RestoreIcon, +} from '@mui/icons-material'; +import { useDropzone } from 'react-dropzone'; +import { downloadDatabaseBackup, uploadBackup } from '@/utils/downloadBackup'; +import { useUserAuth } from '@/app/context/UserAuth'; + +const BackupComponent = () => { + const { token } = useUserAuth(); + + // Estado del diálogo de redirección post-restauración + const [redirectDialog, setRedirectDialog] = useState<{ open: boolean; url: string; countdown: number }>( + { open: false, url: '', countdown: 3 } + ); + + useEffect(() => { + if (!redirectDialog.open) return; + if (redirectDialog.countdown <= 0) { + window.location.replace(redirectDialog.url); + return; + } + const timer = setTimeout(() => { + setRedirectDialog(prev => ({ ...prev, countdown: prev.countdown - 1 })); + }, 1000); + return () => clearTimeout(timer); + }, [redirectDialog.open, redirectDialog.countdown, redirectDialog.url]); + + // Estados para descargar backup + const [downloadLoading, setDownloadLoading] = useState(false); + const [downloadStatus, setDownloadStatus] = useState<{ + type: 'success' | 'error' | null; + message: string; + }>({ type: null, message: '' }); + + // Estados para subir backup + const [uploadLoading, setUploadLoading] = useState(false); + const [uploadStatus, setUploadStatus] = useState<{ + type: 'success' | 'error' | null; + message: string; + }>({ type: null, message: '' }); + const [selectedFile, setSelectedFile] = useState(null); + + // Función para descargar backup + const handleDownloadBackup = async () => { + if (!token) { + setDownloadStatus({ + type: 'error', + message: 'No estás autenticado' + }); + return; + } + + setDownloadLoading(true); + setDownloadStatus({ type: null, message: '' }); + + try { + const result = await downloadDatabaseBackup(token); + setDownloadStatus({ + type: 'success', + message: `Backup descargado exitosamente: ${result.fileName}` + }); + } catch (error: any) { + setDownloadStatus({ + type: 'error', + message: error.message || 'Error al generar el backup' + }); + } finally { + setDownloadLoading(false); + } + }; + + // Función para manejar el drop de archivos + const onDrop = useCallback((acceptedFiles: File[]) => { + const file = acceptedFiles[0]; + if (file && file.name.endsWith('.sql')) { + setSelectedFile(file); + setUploadStatus({ type: null, message: '' }); + } else { + setUploadStatus({ + type: 'error', + message: 'Solo se permiten archivos .sql' + }); + } + }, []); + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + accept: { + 'application/sql': ['.sql'], + 'text/plain': ['.sql'] + }, + multiple: false + }); + + // Función para subir backup + const handleUploadBackup = async () => { + if (!selectedFile || !token) return; + + setUploadLoading(true); + setUploadStatus({ type: null, message: '' }); + + try { + const result = await uploadBackup(selectedFile); + setUploadStatus({ + type: 'success', + message: 'Backup restaurado exitosamente' + }); + setSelectedFile(null); + setRedirectDialog({ open: true, url: result.data?.urlCallback ?? '/', countdown: 3 }); + } catch (error: any) { + setUploadStatus({ + type: 'error', + message: error.message || 'Error al procesar el backup' + }); + } finally { + setUploadLoading(false); + } + }; + + // Función para remover archivo seleccionado + const handleRemoveFile = () => { + setSelectedFile(null); + setUploadStatus({ type: null, message: '' }); + }; + + return ( + + {/* Título principal */} + + + + Gestión de Backups + + + Genera respaldos de la base de datos o restaura desde un archivo + + + + {/* Card principal dividida */} + + + + {/* Lado izquierdo - Generar Backup */} + + + + + Generar Backup + + + Descarga una copia de seguridad completa de la base de datos + + + + + {downloadLoading && ( + + + + Generando backup... + + + )} + + {downloadStatus.type && ( + setDownloadStatus({ type: null, message: '' })} + > + {downloadStatus.message} + + )} + + + + + + 💡 El archivo incluirá toda la estructura y datos de la base de datos + + + + + + {/* Divider vertical */} + + + {/* Lado derecho - Subir Backup */} + + + + + Restaurar Backup + + + Sube un archivo .sql para restaurar la base de datos + + + + + {/* Dropzone */} + + + + + {isDragActive + ? 'Suelta el archivo aquí' + : 'Arrastra un archivo .sql o haz clic para seleccionar' + } + + + Formatos soportados: .sql + + + + {/* Archivo seleccionado */} + {selectedFile && ( + + + + + + + {selectedFile.name} + + + {(selectedFile.size / 1024 / 1024).toFixed(2)} MB + + + + + + + + + )} + + {/* Estado de carga para upload */} + {uploadLoading && ( + + + + Procesando backup... + + + )} + + {/* Mensajes de estado para upload */} + {uploadStatus.type && ( + setUploadStatus({ type: null, message: '' })} + > + {uploadStatus.message} + + )} + + {/* Botón de restaurar */} + + + + + ⚠️ Esta acción reemplazará completamente la base de datos actual + + + + + + + + {/* Información adicional */} + + + Importante: Solo los administradores pueden realizar operaciones de backup + + + + + + + + + {/* Diálogo de redirección post-restauración */} + + + + Backup restaurado + + + + + + Será redirigido para completar el proceso + + + + {redirectDialog.countdown} + + + + + + + ); +}; + +export default BackupComponent; diff --git a/front-urban/src/app/(dashboard)/configuracion/sistema/page.tsx b/front-urban/src/app/(dashboard)/configuracion/sistema/page.tsx new file mode 100644 index 0000000..2a93228 --- /dev/null +++ b/front-urban/src/app/(dashboard)/configuracion/sistema/page.tsx @@ -0,0 +1,489 @@ +'use client'; + +import React, { useState, useEffect } from 'react'; +import { + Box, + Card, + Typography, + TextField, + Button, + Alert, + LinearProgress, + Chip, + Paper, + Grid, + Snackbar, + Dialog, + DialogTitle, + DialogContent, + DialogActions, +} from '@mui/material'; +import { + Settings as SettingsIcon, + Save as SaveIcon, + Refresh as RefreshIcon, + Warning as WarningIcon, +} from '@mui/icons-material'; +import { useSystemConfig } from '@/@core/hooks/useSystemConfig'; +import { useUserAuth } from '@/app/context/UserAuth'; +import type { UpdateSystemConfigDto } from '@/@core/types/system-config'; + +const SystemConfigPage = () => { + const { user, token } = useUserAuth(); + const { data, loading, fetchConfig, updateConfig, reloadConfig, updating, reloading } = useSystemConfig(token ? { token } : {}); + + // Estados del formulario + const [formData, setFormData] = useState({ + sessionCleanupIntervalMinutes: 0, + invoiceGenerationDayOfMonth: 0, + tokenExpirationMinutes: 0, + tokenCleanupIntervalMinutes: 0, + profilePictureUpdateIntervalDays: 0, + }); + + // Estado para el snackbar + const [snackbar, setSnackbar] = useState<{ + open: boolean; + message: string; + severity: 'success' | 'error' | 'warning'; + }>({ + open: false, + message: '', + severity: 'success', + }); + + // Estado para el warning dialog + const [showTokenWarning, setShowTokenWarning] = useState(false); + const [pendingUpdate, setPendingUpdate] = useState(null); + + // Verificar permisos de admin + const isAdmin = user?.role === 'ADMIN'; + + // Cargar configuración al montar + useEffect(() => { + if (token) { + fetchConfig().catch((error) => { + console.log('error fetch ', error) + setSnackbar({ + open: true, + message: 'Error al cargar la configuración', + severity: 'error', + }); + }); + } + }, [token, fetchConfig]); + + // Actualizar formulario cuando se carga la data + useEffect(() => { + if (data) { + setFormData({ + sessionCleanupIntervalMinutes: data.sessionCleanupIntervalMinutes, + invoiceGenerationDayOfMonth: data.invoiceGenerationDayOfMonth, + tokenExpirationMinutes: data.tokenExpirationMinutes, + tokenCleanupIntervalMinutes: data.tokenCleanupIntervalMinutes, + profilePictureUpdateIntervalDays: data.profilePictureUpdateIntervalDays, + }); + } + }, [data]); + + // Verificar si hay cambios + const hasChanges = data + ? formData.sessionCleanupIntervalMinutes !== data.sessionCleanupIntervalMinutes || + formData.invoiceGenerationDayOfMonth !== data.invoiceGenerationDayOfMonth || + formData.tokenExpirationMinutes !== data.tokenExpirationMinutes || + formData.tokenCleanupIntervalMinutes !== data.tokenCleanupIntervalMinutes || + formData.profilePictureUpdateIntervalDays !== data.profilePictureUpdateIntervalDays + : false; + + // Validación - solo mostrar errores si el usuario ha modificado los valores + const showErrors = hasChanges || (!data); // Mostrar errores solo si hay cambios o no hay data cargada + + const errors = { + sessionCleanupIntervalMinutes: showErrors && formData.sessionCleanupIntervalMinutes < 1 ? 'Debe ser mínimo 1' : '', + invoiceGenerationDayOfMonth: + showErrors && (formData.invoiceGenerationDayOfMonth < 1 || formData.invoiceGenerationDayOfMonth > 28) + ? 'Debe estar entre 1 y 28' + : '', + tokenExpirationMinutes: showErrors && formData.tokenExpirationMinutes < 1 ? 'Debe ser mínimo 1' : '', + tokenCleanupIntervalMinutes: showErrors && formData.tokenCleanupIntervalMinutes < 1 ? 'Debe ser mínimo 1' : '', + profilePictureUpdateIntervalDays: showErrors && formData.profilePictureUpdateIntervalDays < 1 ? 'Debe ser mínimo 1' : '', + }; + + const hasErrors = Object.values(errors).some((error) => error !== ''); + + const handleChange = (field: keyof typeof formData) => (e: React.ChangeEvent) => { + const value = parseInt(e.target.value, 10) || 0; + setFormData((prev) => ({ ...prev, [field]: value })); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (!isAdmin || hasErrors || !hasChanges) return; + + // Construir DTO solo con campos modificados + const dto: UpdateSystemConfigDto = {}; + if (data) { + if (formData.sessionCleanupIntervalMinutes !== data.sessionCleanupIntervalMinutes) { + dto.sessionCleanupIntervalMinutes = formData.sessionCleanupIntervalMinutes; + } + if (formData.invoiceGenerationDayOfMonth !== data.invoiceGenerationDayOfMonth) { + dto.invoiceGenerationDayOfMonth = formData.invoiceGenerationDayOfMonth; + } + if (formData.tokenExpirationMinutes !== data.tokenExpirationMinutes) { + dto.tokenExpirationMinutes = formData.tokenExpirationMinutes; + } + if (formData.tokenCleanupIntervalMinutes !== data.tokenCleanupIntervalMinutes) { + dto.tokenCleanupIntervalMinutes = formData.tokenCleanupIntervalMinutes; + } + if (formData.profilePictureUpdateIntervalDays !== data.profilePictureUpdateIntervalDays) { + dto.profilePictureUpdateIntervalDays = formData.profilePictureUpdateIntervalDays; + } + } + + // Si se modificó tokenExpirationMinutes, mostrar warning + if (dto.tokenExpirationMinutes !== undefined) { + setPendingUpdate(dto); + setShowTokenWarning(true); + return; + } + + await performUpdate(dto); + }; + + const performUpdate = async (dto: UpdateSystemConfigDto) => { + try { + await updateConfig(dto); + setSnackbar({ + open: true, + message: 'Configuración actualizada exitosamente', + severity: 'success', + }); + } catch (error: any) { + setSnackbar({ + open: true, + message: error?.response?.data?.message || 'Error al actualizar la configuración', + severity: 'error', + }); + } + }; + + const handleConfirmUpdate = async () => { + setShowTokenWarning(false); + if (pendingUpdate) { + await performUpdate(pendingUpdate); + setPendingUpdate(null); + } + }; + + const handleReload = async () => { + try { + await reloadConfig(); + setSnackbar({ + open: true, + message: 'Configuración recargada desde la base de datos', + severity: 'success', + }); + } catch (error: any) { + setSnackbar({ + open: true, + message: error?.response?.data?.message || 'Error al recargar la configuración', + severity: 'error', + }); + } + }; + + const handleCloseSnackbar = () => { + setSnackbar((prev) => ({ ...prev, open: false })); + }; + + if (!isAdmin) { + return ( + + No tienes permisos para acceder a esta página + + ); + } + + return ( + + {/* Título principal */} + + + + Configuración del Sistema + + + Gestiona los parámetros de configuración de la aplicación + + + + {/* Card principal */} + + {loading && } + + +
+ + {/* Limpieza de sesiones */} + + + + Limpieza de Sesiones + + + + + + {/* Generación de facturas */} + + + + Generación de Facturas + + + + + + {/* Expiración de tokens */} + + + + + + Expiración de Tokens + + + + + + + {/* Limpieza de tokens */} + + + + Limpieza de Tokens + + + + + + {/* Actualización de fotos de perfil de WhatsApp */} + + + + Fotos de Perfil WhatsApp + + + + + + + {/* Botones de acción */} + + + + + + + {/* Info chips */} + {data && ( + + + Última actualización: {new Date(data.updatedAt).toLocaleString('es-AR')} + + + + + + + + )} +
+
+
+ + {/* Warning Dialog para cambio de token */} + setShowTokenWarning(false)}> + + + Advertencia: Cambio de Token + + + + El cambio en el tiempo de expiración de tokens requiere reiniciar la aplicación para + que tenga efecto. + + + Los usuarios que ya tienen tokens activos mantendrán su sesión hasta que expiren con el tiempo anterior. + + + + + + + + + {/* Snackbar para notificaciones */} + + + {snackbar.message} + + +
+ ); +}; + +export default SystemConfigPage; diff --git a/front-urban/src/app/(dashboard)/form-layouts/page.tsx b/front-urban/src/app/(dashboard)/form-layouts/page.tsx new file mode 100644 index 0000000..aa5848e --- /dev/null +++ b/front-urban/src/app/(dashboard)/form-layouts/page.tsx @@ -0,0 +1,25 @@ +// MUI Imports +import Grid from '@mui/material/Grid' + +// Component Imports +import FormLayoutsBasic from '@views/form-layouts/FormLayoutsBasic' +import FormLayoutsIcon from '@views/form-layouts/FormLayoutsIcons' +import FormLayoutsAlignment from '@views/form-layouts/FormLayoutsAlignment' + +const FormLayouts = () => { + return ( + + + + + + + + + + + + ) +} + +export default FormLayouts diff --git a/front-urban/src/app/(dashboard)/layout.tsx b/front-urban/src/app/(dashboard)/layout.tsx new file mode 100644 index 0000000..8b1e319 --- /dev/null +++ b/front-urban/src/app/(dashboard)/layout.tsx @@ -0,0 +1,32 @@ +// Type Imports +import type { ChildrenType } from '@core/types' + +// Layout Imports +import LayoutWrapper from '@layouts/LayoutWrapper' +import VerticalLayout from '@layouts/VerticalLayout' + +// Component Imports +import Providers from '@components/Providers' +import Navigation from '@components/layout/vertical/Navigation' +import Navbar from '@components/layout/vertical/Navbar' +import VerticalFooter from '@components/layout/vertical/Footer' + + +const Layout = async ({ children }: ChildrenType) => { + // Vars + const direction = 'ltr' + + return ( + + } navbar={} footer={}> + {children} + + } + /> + + ) +} + +export default Layout diff --git a/front-urban/src/app/(dashboard)/page.tsx b/front-urban/src/app/(dashboard)/page.tsx new file mode 100644 index 0000000..b19e256 --- /dev/null +++ b/front-urban/src/app/(dashboard)/page.tsx @@ -0,0 +1,367 @@ +'use client' + +// MUI Imports +import Grid from '@mui/material/Grid' + +// Components Imports +import CustomAvatar from '@/@core/components/mui/Avatar' +import { useDashboard } from '@/@core/hooks/useDashboard' +import CardAccess from '@/components/card-statistics/CardAccess' +import Link from '@/components/Link' +import { Snapshot } from '@/views/clases/FechasProgramadasAccordion' +import CardDashboardDetail from '@/views/dashboard/CardDashboardDetailProfesor' +import DashboardCharts from '@/views/dashboard/DashboardCharts' +import DialogAttendanceSnapshot from '@/views/dashboard/DialogAttendanceSnapshot' +import { alpha, Card, CardContent, CardHeader, Chip, IconButton, Tooltip, Typography } from '@mui/material' +import { useState } from 'react' +import { useUserAuth } from '../context/UserAuth' + +enum RoleDashboard { + ADMIN = 'ADMIN', + PROFESOR = 'PROFESOR' +} + +const DashboardAnalytics = () => { + const { user } = useUserAuth() + const { data, error, loading, refresh } = useDashboard() + + const { role, customId, dni, phone, birth, rfid, deleted, name } = user || {} + + const dashboardUser = { + 'ADMIN': , + 'INSTRUCTOR': + } + + return <>{dashboardUser[role as keyof typeof dashboardUser] ?? null} +} + +export default DashboardAnalytics + +// de profesor / admin +const DashboardAdmin = ({ data, loading }: { data: any; loading: boolean }) => { + const sessions = data?.sessions ?? [] + + // ---- estado del diálogo de asistencia + const [attDialogOpen, setAttDialogOpen] = useState(false) + const [attSnapshot, setAttSnapshot] = useState | null>(null) + + const handleOpenAttendance = (item: any) => { + // armamos un objeto Snapshot mínimo con los campos que usa el dialog + const snap: Partial = { + id: item.id, + // el tipo Snapshot real puede tener más campos; los no usados por el dialog se pueden omitir + substituteInstructors: [] + } + + setAttSnapshot(snap) + setAttDialogOpen(true) + } + + const handleCloseAttendance = () => { + setAttDialogOpen(false) + setAttSnapshot(null) + } + + if (loading) return
Loading...
+ + return ( + + + + + + + + + {/* Gráficos de torta */} + + + + + + + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}` + })} + > + ({ + fontWeight: 800, + letterSpacing: 0.2, + background: `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.55 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text' + })} + > + Clases futuras + + } + action={ + + Ver todas + + } + subheader={Próximas 10 sesiones} + /> + + {sessions.length === 0 ? ( + No hay clases próximas. + ) : ( + sessions.map((item: any) => ( +
+ + + + +
+
+ + {item.description} + + + {item.instructors || '—'} + +
+ +
+ + handleOpenAttendance(item)}> +
+ + + + + ({ + fontWeight: 700, + letterSpacing: 0.2, + border: `1px solid ${alpha(theme.palette.info.main, 0.5)}`, + transition: 'transform .15s ease, box-shadow .15s ease, filter .15s ease', + '&:hover': { + transform: 'scale(1.04)', + boxShadow: `0 8px 22px ${alpha(theme.palette.info.main, 0.35)}`, + filter: 'saturate(1.05)' + } + })} + /> + +
+
+
+ )) + )} + + + + + + {/* Dialog de asistencia */} + + + ) +} + + + +const DashboardInstructor = ({ data, loading }: { data: any; loading: boolean }) => { + const sessions = data?.sessions ?? [] + + // ---- estado del diálogo de asistencia + const [attDialogOpen, setAttDialogOpen] = useState(false) + const [attSnapshot, setAttSnapshot] = useState | null>(null) + + const handleOpenAttendance = (item: any) => { + // armamos un objeto Snapshot mínimo con los campos que usa el dialog + const snap: Partial = { + id: item.id, + // el tipo Snapshot real puede tener más campos; los no usados por el dialog se pueden omitir + substituteInstructors: [] + } + + setAttSnapshot(snap) + setAttDialogOpen(true) + } + + const handleCloseAttendance = () => { + setAttDialogOpen(false) + setAttSnapshot(null) + } + + if (loading) return
Loading...
+ + return ( + + + + + + + + + {/* Gráficos de torta */} + + + + + + + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}` + })} + > + ({ + fontWeight: 800, + letterSpacing: 0.2, + background: `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.55 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text' + })} + > + Clases futuras + + } + action={ + + Ver todas + + } + subheader={Próximas 10 sesiones} + /> + + {sessions.length === 0 ? ( + No hay clases próximas. + ) : ( + sessions.map((item: any) => ( +
+ + + + +
+
+ + {item.description} + + + {item.instructors || '—'} + +
+ +
+ + handleOpenAttendance(item)}> +
+ + + + + ({ + fontWeight: 700, + letterSpacing: 0.2, + border: `1px solid ${alpha(theme.palette.info.main, 0.5)}`, + transition: 'transform .15s ease, box-shadow .15s ease, filter .15s ease', + '&:hover': { + transform: 'scale(1.04)', + boxShadow: `0 8px 22px ${alpha(theme.palette.info.main, 0.35)}`, + filter: 'saturate(1.05)' + } + })} + /> + +
+
+
+ )) + )} + + + + + + {/* Dialog de asistencia */} + + + ) +} + + +const formatTime = (iso?: string) => { + if (!iso) return '—' + const d = new Date(iso) + if (Number.isNaN(d.getTime())) return '—' + return d.toLocaleTimeString('es-AR', { hour: '2-digit', minute: '2-digit' }) +} + +const formatDateTime = (iso?: string) => { + if (!iso) return '—' + const d = new Date(iso) + if (Number.isNaN(d.getTime())) return '—' + return d.toLocaleString('es-AR', { + weekday: 'long', + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit' + }) +} diff --git a/front-urban/src/app/(dashboard)/usuarios/page.tsx b/front-urban/src/app/(dashboard)/usuarios/page.tsx new file mode 100644 index 0000000..88c7812 --- /dev/null +++ b/front-urban/src/app/(dashboard)/usuarios/page.tsx @@ -0,0 +1,12 @@ +import UsuarioComponent from '@views/usuarios' + + + +const UsuarioPage = () => { + + + return + +}; + +export default UsuarioPage; diff --git a/front-urban/src/app/(dashboard)/whatsapp/notificar/page.tsx b/front-urban/src/app/(dashboard)/whatsapp/notificar/page.tsx new file mode 100644 index 0000000..879afa6 --- /dev/null +++ b/front-urban/src/app/(dashboard)/whatsapp/notificar/page.tsx @@ -0,0 +1,8 @@ + +const NotificarWhatsAppPage = () => { + return <> + asasd + +}; + +export default NotificarWhatsAppPage; diff --git a/front-urban/src/app/(dashboard)/whatsapp/page.tsx b/front-urban/src/app/(dashboard)/whatsapp/page.tsx new file mode 100644 index 0000000..53aaa58 --- /dev/null +++ b/front-urban/src/app/(dashboard)/whatsapp/page.tsx @@ -0,0 +1,7 @@ +import WhatsAppComponent from '@/views/whatsapp'; + +const WhatsAppPage = () => { + return +}; + +export default WhatsAppPage; diff --git a/front-urban/src/app/[...not-found]/page.tsx b/front-urban/src/app/[...not-found]/page.tsx new file mode 100644 index 0000000..1306735 --- /dev/null +++ b/front-urban/src/app/[...not-found]/page.tsx @@ -0,0 +1,23 @@ +// Component Imports +import Providers from '@components/Providers' +import BlankLayout from '@layouts/BlankLayout' +import NotFound from '@views/NotFound' + +// Util Imports +import { getServerMode } from '@core/utils/serverHelpers' + +const NotFoundPage = () => { + // Vars + const direction = 'ltr' + const mode = getServerMode() + + return ( + + + + + + ) +} + +export default NotFoundPage diff --git a/front-urban/src/app/api/auth/verify/route.ts b/front-urban/src/app/api/auth/verify/route.ts new file mode 100644 index 0000000..5687765 --- /dev/null +++ b/front-urban/src/app/api/auth/verify/route.ts @@ -0,0 +1,61 @@ +// app/api/auth/verify/route.ts +import { NextResponse } from 'next/server'; + +export const runtime = 'nodejs'; +export const dynamic = 'force-dynamic'; + +export async function GET(req: Request) { + try { + const { searchParams } = new URL(req.url); + const t = searchParams.get('t'); + + if (!t) { + return NextResponse.json({ autorizado: false }, { status: 400 }); + } + + // timeout 10s + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), 10_000); + + let upstream: Response; + try { + upstream = await fetch( + `${process.env.BACKEND_URL}/auth/verify?t=${encodeURIComponent(t)}`, + { + method: 'GET', + cache: 'no-store', + signal: controller.signal, + } + ); + } catch { + clearTimeout(timer); + return NextResponse.json({ autorizado: false }, { status: 502 }); + } finally { + clearTimeout(timer); + } + + let data: any = null; + try { + data = await upstream.json(); + } catch { + return NextResponse.json({ autorizado: false }, { status: 502 }); + } + + const autorizado = Boolean(data?.autorizado); + const user = autorizado ? data?.user : undefined; + const redirectUrl = autorizado ? (data?.redirectUrl as string | undefined) : undefined; + + if (!upstream.ok) { + const status = upstream.status === 401 || upstream.status === 403 ? 401 : 502; + return NextResponse.json({ autorizado: false }, { status }); + } + + if (!autorizado) { + return NextResponse.json({ autorizado: false }, { status: 401 }); + } + + return NextResponse.json({ autorizado: true, user, redirectUrl }, { status: 200 }); + } catch { + return NextResponse.json({ autorizado: false }, { status: 500 }); + } +} diff --git a/front-urban/src/app/context/UserAuth.tsx b/front-urban/src/app/context/UserAuth.tsx new file mode 100644 index 0000000..4c28e31 --- /dev/null +++ b/front-urban/src/app/context/UserAuth.tsx @@ -0,0 +1,353 @@ +'use client'; + +import { + createContext, + useContext, + useMemo, + useEffect, + useRef, + useState, +} from 'react'; +import { useRouter, useSearchParams } from 'next/navigation'; + +// Type del usuario retornado del backend +export type User = { + id: string; + createdAt: Date; + name: string; + customId: string; + dni: string | null; + phone: string | null; + birth: Date | null; + rfid: string | null; + deleted: Date | null; + role: string; // $Enums.UserRole +}; + +type Ctx = { + user: User | null; + token?: string; + isAuthorized: boolean; + loading: boolean; + redirectUrl?: string; +}; + +// Loader simple (reemplazalo por el tuyo si querés) +function LoadingScreen() { + return ( +
+
+ Validando acceso… + +
+ ); +} + +const UserAuthContext = createContext({ + user: null, + isAuthorized: false, + loading: true, +}); + +// utils auth storage (localStorage) +function getLocalAuth(): (CookiePayload & { expiresAt?: number }) | null { + if (typeof window === 'undefined') return null; + try { + const raw = localStorage.getItem('authToken'); + if (!raw) return null; + const parsed = JSON.parse(raw) as CookiePayload & { expiresAt?: number }; + if (parsed.expiresAt && Date.now() > parsed.expiresAt) { + localStorage.removeItem('authToken'); + return null; + } + return parsed; + } catch { + return null; + } +} +function setLocalAuth(payload: CookiePayload, maxAgeSec: number) { + if (typeof window === 'undefined') return; + localStorage.setItem('authToken', JSON.stringify({ ...payload, expiresAt: Date.now() + maxAgeSec * 1000 })); +} +function deleteLocalAuth() { + if (typeof window === 'undefined') return; + localStorage.removeItem('authToken'); +} + +// Mapeo de redirects del backend +const REDIRECT_MAP: Record = { + FRONT: '/', + SESSION: '/clases', + USER: '/usuarios', + WHATSAPP: '/whatsapp', +}; + +// Resuelve redirect a un path interno seguro +function resolveRedirect(input?: string): string | null { + if (!input) return null; + + // 1) token enum → path + const upper = input.toUpperCase(); + if (upper in REDIRECT_MAP) return REDIRECT_MAP[upper]; + + // 2) path interno + if (input.startsWith('/')) return input; + + // 3) URL absoluta same-origin → devolver path + try { + const u = new URL(input, typeof window !== 'undefined' ? window.location.origin : 'http://localhost'); + if (typeof window !== 'undefined' && u.origin === window.location.origin) { + return u.pathname + u.search + u.hash; + } + return null; // externo → ignorar + } catch { + return null; + } +} + +type CookiePayload = { + token: string; + validatedAt: number; + user?: User | null; + redirectUrl?: string; // puede venir enum o path +}; + +export function UserAuthProvider({ children }: { children: React.ReactNode }) { + const router = useRouter(); + const searchParams = useSearchParams(); + + const tParam = searchParams?.get('t') ?? null; + + const [token, setToken] = useState(); + const [authorized, setAuthorized] = useState(false); + const [loading, setLoading] = useState(true); + const [user, setUser] = useState(null); + const [redirectUrl, setRedirectUrl] = useState(); + + // ------ Guards / control de concurrencia ------ + const processedTokenRef = useRef(null); // evita validar 2 veces el mismo t + const requestIdRef = useRef(0); // ignora respuestas viejas + const justCleanedUrlRef = useRef(false); // evita revalidar tras limpiar ?t= + + // limpiar ?t= sin navegar (no cancela requests) + const cleanQueryToken = () => { + const url = new URL(window.location.href); + if (url.searchParams.has('t')) { + url.searchParams.delete('t'); + window.history.replaceState(null, '', url.pathname + (url.search || '') + url.hash); + justCleanedUrlRef.current = true; + } + }; + + useEffect(() => { + const pathname = typeof window !== 'undefined' ? window.location.pathname : '/'; + + // no validar dentro de /unauthorized (evita ping-pong) + if (pathname === '/unauthorized') { + setAuthorized(false); + setToken(undefined); + setUser(null); + setRedirectUrl(undefined); + setLoading(false); + return; + } + + // si recién limpiamos la URL, no revalidar otra vez + if (justCleanedUrlRef.current) { + justCleanedUrlRef.current = false; + setLoading(false); + return; + } + + // --------- PRIORIDAD: token en URL ----------- + if (tParam) { + if (processedTokenRef.current === tParam) { + // si quedó el query, limpiarlo + cleanQueryToken(); + setLoading(false); + return; + } + + processedTokenRef.current = tParam; + + const myId = ++requestIdRef.current; + (async () => { + setLoading(true); + let ok = false; + let serverUser: User | null = null; + let serverRedirect: string | undefined; + + try { + const res = await fetch(`/api/auth/verify?t=${encodeURIComponent(tParam)}`, { cache: 'no-store' }); + const data = await res.json().catch(() => ({ autorizado: false })); + ok = !!data?.autorizado; + if (ok) { + serverUser = data?.user || null; + serverRedirect = data?.redirectUrl || undefined; + } + } catch { + ok = false; + } + + if (myId !== requestIdRef.current) return; + + if (!ok) { + deleteLocalAuth(); + setAuthorized(false); + setToken(undefined); + setUser(null); + setRedirectUrl(undefined); + setLoading(false); + router.replace('/unauthorized'); + return; + } + + // persistir en localStorage 1h + const payload: CookiePayload = { + token: tParam, + validatedAt: Date.now(), + ...(serverUser ? { user: serverUser } : {}), + ...(serverRedirect ? { redirectUrl: serverRedirect } : {}), + }; + setLocalAuth(payload, 60 * 60); + + // estado ok + setToken(tParam); + setUser(serverUser); + setRedirectUrl(serverRedirect); + setAuthorized(true); + setLoading(false); + + // Redirect con full reload: el token ya está guardado en localStorage, + // así que el nuevo mount lo leerá sin race condition. + const path = resolveRedirect(serverRedirect); + if (path && path !== pathname) { + window.location.replace(path); + } else { + // mismo path → limpiar ?t= de la URL sin navegar + cleanQueryToken(); + } + })(); + + return; // no continuar con rama de cookie si hay t + } + + // --------- SIN t: usar localStorage ----------- + const parsed = getLocalAuth(); + if (!parsed?.token) { + deleteLocalAuth(); + setAuthorized(false); + setToken(undefined); + setUser(null); + setRedirectUrl(undefined); + setLoading(false); + router.replace('/unauthorized'); + return; + } + + const ageMs = Date.now() - parsed.validatedAt; + const shouldRevalidate = ageMs > 5 * 60 * 1000; // 5 min + + if (!shouldRevalidate) { + setToken(parsed.token); + setUser(parsed.user || null); + setRedirectUrl(parsed.redirectUrl); + setAuthorized(true); + setLoading(false); + + // REDIRECT mapeado si hubiera en cookie + const path = resolveRedirect(parsed.redirectUrl); + if (path && path !== pathname) { + router.replace(path); + } + return; + } + + // cookie vieja → revalidar una vez + const myId = ++requestIdRef.current; + (async () => { + setLoading(true); + let ok = false; + let serverUser: User | null = null; + let serverRedirect: string | undefined; + + try { + const res = await fetch(`/api/auth/verify?t=${encodeURIComponent(parsed!.token)}`, { cache: 'no-store' }); + const data = await res.json().catch(() => ({ autorizado: false })); + ok = !!data?.autorizado; + if (ok) { + serverUser = data?.user || null; + serverRedirect = data?.redirectUrl || undefined; + } + } catch { + ok = false; + } + + if (myId !== requestIdRef.current) return; + + if (!ok) { + deleteLocalAuth(); + setAuthorized(false); + setToken(undefined); + setUser(null); + setRedirectUrl(undefined); + setLoading(false); + router.replace('/unauthorized'); + return; + } + + const finalUser = serverUser ?? parsed!.user ?? null; + const finalRedirect = serverRedirect ?? parsed!.redirectUrl; + + const payload: CookiePayload = { + token: parsed!.token, + validatedAt: Date.now(), + ...(finalUser ? { user: finalUser } : {}), + ...(finalRedirect ? { redirectUrl: finalRedirect } : {}), + }; + setLocalAuth( + payload, + // NEXT_PUBLIC_MIN_AUTH está en minutos → convertir a segundos + process.env.NEXT_PUBLIC_MIN_AUTH !== undefined + ? +process.env.NEXT_PUBLIC_MIN_AUTH * 60 + : 30 * 60 + ); + + setToken(parsed!.token); + setUser(finalUser); + setRedirectUrl(finalRedirect); + setAuthorized(true); + setLoading(false); + + const path = resolveRedirect(finalRedirect); + if (path && path !== pathname) { + router.replace(path); + } + })(); + }, [tParam, router]); + + const value = useMemo(() => { + return { + user, + token, + isAuthorized: authorized, + loading, + redirectUrl, + }; + }, [token, authorized, loading, user, redirectUrl]); + + // Gate: loader mientras valida; oculta children si no autorizado + if (loading) { + return ; + } + const pathname = typeof window !== 'undefined' ? window.location.pathname : '/'; + if (!authorized && pathname !== '/unauthorized') { + return {null}; + } + + return {children}; +} + +export function useUserAuth() { + return useContext(UserAuthContext); +} diff --git a/front-urban/src/app/context/userauth.txt b/front-urban/src/app/context/userauth.txt new file mode 100644 index 0000000..df2caa4 --- /dev/null +++ b/front-urban/src/app/context/userauth.txt @@ -0,0 +1,53 @@ +"use client"; + +import { createContext, useContext, useMemo, useEffect, useState } from "react"; +import { usePathname, useRouter } from "next/navigation"; +import { getAuthTokenFromCookie } from "@/utils/getAuthToken"; + +type User = { role: string }; +type Ctx = { user: User; token?: string; isAuthorized: boolean }; + +const UserAuthContext = createContext({ user: { role: "ADMIN" }, isAuthorized: false }); + +export function UserAuthProvider({ children }: { children: React.ReactNode }) { + const router = useRouter(); + const pathname = usePathname(); + + // ⚠️ Lea sólo strings estables para deps + const tParam = searchParams?.get("t") ?? null; + + const [token, setToken] = useState(undefined); + const [authorized, setAuthorized] = useState(false); + const [hydrated, setHydrated] = useState(false); + + useEffect(() => { + const raw = getAuthTokenFromCookie("authToken"); + let tok: string | undefined = undefined; + if (raw) { + try { + const parsed = JSON.parse(raw); + tok = parsed?.token ?? undefined; + } catch { + tok = raw || undefined; + } + } + setToken(tok); + setAuthorized(!!tok); + setHydrated(true); + if (!tok && pathname !== "/unauthorized") router.replace("/unauthorized"); + }, [pathname, router]); + + console.log("UserAuthContext value:", token); + + const value = useMemo(() => ({ user: { role: "ADMIN" }, token, isAuthorized: authorized }), [token, authorized]); + + return ( + + {hydrated ? children : null} + + ); +} + +export function useUserAuth() { + return useContext(UserAuthContext); +} diff --git a/front-urban/src/app/favicon.ico b/front-urban/src/app/favicon.ico new file mode 100644 index 0000000..91e6db8 Binary files /dev/null and b/front-urban/src/app/favicon.ico differ diff --git a/front-urban/src/app/globals.css b/front-urban/src/app/globals.css new file mode 100644 index 0000000..db086cb --- /dev/null +++ b/front-urban/src/app/globals.css @@ -0,0 +1,113 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --border-radius: var(--mui-shape-borderRadius); + --border-color: var(--mui-palette-divider); + --primary-color: var(--mui-palette-primary-main); + --background-color: var(--mui-palette-background-default); + --header-height: 64px; + --header-z-index: var(--mui-zIndex-appBar); + --footer-z-index: 10; + --customizer-z-index: var(--mui-zIndex-drawer); + --search-z-index: var(--mui-zIndex-tooltip); + --drawer-z-index: var(--mui-zIndex-drawer); + --backdrop-color: rgb(var(--mui-mainColorChannels-light) / 0.5); +} + +[data-mui-color-scheme='dark'] { + --backdrop-color: rgb(21 16 43 / 0.6); +} + +*, +::before, +::after { + box-sizing: border-box; + padding: 0; + margin: 0; + border-width: 0; + border-style: solid; + border-color: theme('borderColor.DEFAULT', currentColor); +} + +html { + display: flex; + inline-size: 100%; + min-block-size: 100%; +} + +a { + color: inherit; + text-decoration: none; +} + +ul:not([class]) { + margin-block: 1rem; + padding-inline-start: 40px; +} + +.ps__rail-y { + inset-inline-end: 0 !important; + inset-inline-start: auto !important; + & .ps__thumb-y { + inset-inline-end: 3px !important; + inset-inline-start: auto !important; + background-color: var(--mui-palette-divider); + inline-size: 6px; + &:hover, + &:focus, + &.ps--clicking { + background-color: var(--mui-palette-action-disabled) !important; + } + } + &:hover, + &:focus, + &.ps--clicking { + background-color: var(--mui-palette-action-hover) !important; + } + &:hover, + &:focus, + &.ps--clicking { + .ps__thumb-y { + background-color: var(--mui-palette-action-disabled) !important; + } + } +} + +.ts-vertical-nav-root { + .ps__thumb-y { + inline-size: 4px; + &:hover, + &:focus, + &.ps--clicking { + inline-size: 6px; + } + } + .ps__rail-y { + inline-size: 10px; + &:hover, + &:focus, + &.ps--clicking { + background-color: transparent !important; + .ps__thumb-y { + inline-size: 6px; + } + } + } +} + +:where([class^='ri-']) { + font-size: 1.5rem; +} + +code { + font-family: inherit; + padding-block: 2px; + padding-inline: 4px; + border-radius: 4px; + font-size: 90%; + color: var(--mui-palette-info-main); + background-color: rgb(var(--mui-palette-info-mainChannel) / 0.08); + border: 0; +} diff --git a/front-urban/src/app/layout.tsx b/front-urban/src/app/layout.tsx new file mode 100644 index 0000000..8df66e0 --- /dev/null +++ b/front-urban/src/app/layout.tsx @@ -0,0 +1,40 @@ +// Third-party Imports +import 'react-perfect-scrollbar/dist/css/styles.css' + +// Type Imports +import type { ChildrenType } from '@core/types' + +// Style Imports +import '@/app/globals.css' + +// Generated Icon CSS Imports +import '@assets/iconify-icons/generated-icons.css' +import { UserAuthProvider } from './context/UserAuth' +import { AxiosInterceptorProvider } from '@/lib/AxiosInterceptorProvider' +import { Suspense } from 'react' + +export const metadata = { + title: 'Urban dance', + description: 'Gestión de clases y usuarios de Urban Dance' +} + +const RootLayout = ({ children }: ChildrenType) => { + // Vars + const direction = 'ltr' + + return ( + + + + + + {children} + + + + + + ) +} + +export default RootLayout diff --git a/front-urban/src/app/modules/clases/dto/sessionType.dto.ts b/front-urban/src/app/modules/clases/dto/sessionType.dto.ts new file mode 100644 index 0000000..c078fe8 --- /dev/null +++ b/front-urban/src/app/modules/clases/dto/sessionType.dto.ts @@ -0,0 +1,4 @@ +export enum SessionType { + RECURRING = 'RECURRING', // Clase regular (indefinida o acotada) + ONE_TIME = 'ONE_TIME', // Workshop o evento puntual +} diff --git a/front-urban/src/app/modules/users/dto/instructor.dto.ts b/front-urban/src/app/modules/users/dto/instructor.dto.ts new file mode 100644 index 0000000..ac98d70 --- /dev/null +++ b/front-urban/src/app/modules/users/dto/instructor.dto.ts @@ -0,0 +1,6 @@ +export type Instructor = { + id: string; + name: string; + customId: string; + dni: string; +}; diff --git a/front-urban/src/app/unauthorized/page.tsx b/front-urban/src/app/unauthorized/page.tsx new file mode 100644 index 0000000..cb72baa --- /dev/null +++ b/front-urban/src/app/unauthorized/page.tsx @@ -0,0 +1,106 @@ +'use client'; + +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import Button from '@mui/material/Button'; +import Stack from '@mui/material/Stack'; +import LockIcon from '@mui/icons-material/LockOutlined'; +import WhatsAppIcon from '@mui/icons-material/WhatsApp'; + +const WA_LINK = `https://wa.me/${process.env.NEXT_PUBLIC_WHATSAPP_NUMBER || '5493435077510'}`; + +export default function UnauthorizedPage() { + return ( + + + {/* Icono minimalista */} + + + + + {/* Título */} + + + Acceso no autorizado + + + Tu token ha expirado o no es válido. Solicita uno nuevo para continuar. + + + + {/* Botones */} + + + + + + + ); +} diff --git a/front-urban/src/assets/iconify-icons/bundle-icons-css.ts b/front-urban/src/assets/iconify-icons/bundle-icons-css.ts new file mode 100644 index 0000000..530e3c9 --- /dev/null +++ b/front-urban/src/assets/iconify-icons/bundle-icons-css.ts @@ -0,0 +1,258 @@ +/** + * This is an advanced example for creating icon bundles for Iconify SVG Framework. + * + * It creates a bundle from: + * - All SVG files in a directory. + * - Custom JSON files. + * - Iconify icon sets. + * - SVG framework. + * + * This example uses Iconify Tools to import and clean up icons. + * For Iconify Tools documentation visit https://docs.iconify.design/tools/tools2/ + */ +import { promises as fs } from 'node:fs' +import { dirname, join } from 'node:path' + +// Installation: npm install --save-dev @iconify/tools @iconify/utils @iconify/json @iconify/iconify +import { cleanupSVG, importDirectory, isEmptyColor, parseColors, runSVGO } from '@iconify/tools' +import type { IconifyJSON } from '@iconify/types' +import { getIcons, getIconsCSS, stringToIcon } from '@iconify/utils' + +/** + * Script configuration + */ +interface BundleScriptCustomSVGConfig { + // eslint-disable-next-line lines-around-comment + // Path to SVG files + dir: string + + // True if icons should be treated as monotone: colors replaced with currentColor + monotone: boolean + + // Icon set prefix + prefix: string +} + +interface BundleScriptCustomJSONConfig { + // eslint-disable-next-line lines-around-comment + // Path to JSON file + filename: string + + // List of icons to import. If missing, all icons will be imported + icons?: string[] +} + +interface BundleScriptConfig { + // eslint-disable-next-line lines-around-comment + // Custom SVG to import and bundle + svg?: BundleScriptCustomSVGConfig[] + + // Icons to bundled from @iconify/json packages + icons?: string[] + + // List of JSON files to bundled + // Entry can be a string, pointing to filename or a BundleScriptCustomJSONConfig object (see type above) + // If entry is a string or object without 'icons' property, an entire JSON file will be bundled + json?: (string | BundleScriptCustomJSONConfig)[] +} + +const sources: BundleScriptConfig = { + json: [ + // Iconify JSON file (@iconify/json is a package name, /json/ is directory where files are, then filename) + require.resolve('@iconify/json/json/ri.json'), + + // Custom file with only few icons + { + filename: require.resolve('@iconify/json/json/line-md.json'), + icons: ['home-twotone-alt', 'github', 'document-list', 'document-code', 'image-twotone'] + } + + // Custom JSON file + // 'json/gg.json' + ], + + icons: [ + 'bx-basket', + 'bi-airplane-engines', + 'tabler-anchor', + 'uit-adobe-alt', + + // 'fa6-regular-comment', + 'twemoji-auto-rickshaw' + ], + + svg: [ + /* { + dir: 'src/assets/iconify-icons/svg', + monotone: false, + prefix: 'custom' + } */ + /* { + dir: 'src/assets/iconify-icons/emojis', + monotone: false, + prefix: 'emoji' + } */ + ] +} + +// File to save bundle to +const target = join(__dirname, 'generated-icons.css') + +/** + * Do stuff! + */ + +;(async function () { + // Create directory for output if missing + const dir = dirname(target) + + try { + await fs.mkdir(dir, { + recursive: true + }) + } catch (err) { + // + } + + const allIcons: IconifyJSON[] = [] + + /** + * Convert sources.icons to sources.json + */ + if (sources.icons) { + const sourcesJSON = sources.json ? sources.json : (sources.json = []) + + // Sort icons by prefix + const organizedList = organizeIconsList(sources.icons) + + for (const prefix in organizedList) { + const filename = require.resolve(`@iconify/json/json/${prefix}.json`) + + sourcesJSON.push({ + filename, + icons: organizedList[prefix] + }) + } + } + + /** + * Bundle JSON files and collect icons + */ + if (sources.json) { + for (let i = 0; i < sources.json.length; i++) { + const item = sources.json[i] + + // Load icon set + const filename = typeof item === 'string' ? item : item.filename + const content = JSON.parse(await fs.readFile(filename, 'utf8')) as IconifyJSON + + // Filter icons + if (typeof item !== 'string' && item.icons?.length) { + const filteredContent = getIcons(content, item.icons) + + if (!filteredContent) throw new Error(`Cannot find required icons in ${filename}`) + + // Collect filtered icons + allIcons.push(filteredContent) + } else { + // Collect all icons from the JSON file + allIcons.push(content) + } + } + } + + /** + * Bundle custom SVG icons and collect icons + */ + if (sources.svg) { + for (let i = 0; i < sources.svg.length; i++) { + const source = sources.svg[i] + + // Import icons + const iconSet = await importDirectory(source.dir, { + prefix: source.prefix + }) + + // Validate, clean up, fix palette, etc. + await iconSet.forEach(async (name, type) => { + if (type !== 'icon') return + + // Get SVG instance for parsing + const svg = iconSet.toSVG(name) + + if (!svg) { + // Invalid icon + iconSet.remove(name) + + return + } + + // Clean up and optimise icons + try { + // Clean up icon code + await cleanupSVG(svg) + + if (source.monotone) { + // Replace color with currentColor, add if missing + // If icon is not monotone, remove this code + await parseColors(svg, { + defaultColor: 'currentColor', + callback: (attr, colorStr, color) => { + return !color || isEmptyColor(color) ? colorStr : 'currentColor' + } + }) + } + + // Optimise + await runSVGO(svg) + } catch (err) { + // Invalid icon + console.error(`Error parsing ${name} from ${source.dir}:`, err) + iconSet.remove(name) + + return + } + + // Update icon from SVG instance + iconSet.fromSVG(name, svg) + }) + + // Collect the SVG icon + allIcons.push(iconSet.export()) + } + } + + // Generate CSS from collected icons + const cssContent = allIcons + .map(iconSet => getIconsCSS(iconSet, Object.keys(iconSet.icons), { iconSelector: '.{prefix}-{name}' })) + .join('\n') + + // Save the CSS to a file + await fs.writeFile(target, cssContent, 'utf8') + + console.log(`Saved CSS to ${target}!`) +})().catch(err => { + console.error(err) +}) + +/** + * Sort icon names by prefix + */ +function organizeIconsList(icons: string[]): Record { + const sorted: Record = Object.create(null) + + icons.forEach(icon => { + const item = stringToIcon(icon) + + if (!item) return + + const prefix = item.prefix + const prefixList = sorted[prefix] ? sorted[prefix] : (sorted[prefix] = []) + + const name = item.name + + if (!prefixList.includes(name)) prefixList.push(name) + }) + + return sorted +} diff --git a/front-urban/src/components/DirectionalIcon.tsx b/front-urban/src/components/DirectionalIcon.tsx new file mode 100644 index 0000000..2da845f --- /dev/null +++ b/front-urban/src/components/DirectionalIcon.tsx @@ -0,0 +1,35 @@ +'use client' + +// MUI Imports +import { useTheme } from '@mui/material/styles' + +// Third-party Imports +import classnames from 'classnames' + +type Props = { + ltrIconClass: string + rtlIconClass: string + className?: string +} + +const DirectionalIcon = (props: Props) => { + // Props + const { ltrIconClass, rtlIconClass, className } = props + + // Hooks + const theme = useTheme() + + return ( + + ) +} + +export default DirectionalIcon diff --git a/front-urban/src/components/Form.tsx b/front-urban/src/components/Form.tsx new file mode 100644 index 0000000..19c4823 --- /dev/null +++ b/front-urban/src/components/Form.tsx @@ -0,0 +1,15 @@ +'use client' + +// React Imports +import type { DetailedHTMLProps, FormHTMLAttributes } from 'react' + +type Props = DetailedHTMLProps, HTMLFormElement> + +const FormComponent = (props: Props) => { + // Props + const { onSubmit, ...rest } = props + + return
onSubmit(e) : e => e.preventDefault()} /> +} + +export default FormComponent diff --git a/front-urban/src/components/Illustrations.tsx b/front-urban/src/components/Illustrations.tsx new file mode 100644 index 0000000..7918034 --- /dev/null +++ b/front-urban/src/components/Illustrations.tsx @@ -0,0 +1,99 @@ +'use client' + +// React Imports +import type { ReactNode } from 'react' + +// MUI Components +import useMediaQuery from '@mui/material/useMediaQuery' +import { styled, useTheme } from '@mui/material/styles' + +// Type Imports +import type { Mode } from '@core/types' + +// Hook Imports +import { useImageVariant } from '@core/hooks/useImageVariant' + +type ImageObj = { + src: string + alt?: string + className?: string + height?: number + width?: number +} + +type IllustrationsProp = { + image1?: ReactNode | ImageObj + image2?: ReactNode | ImageObj + maskImg?: ReactNode | ImageObj + mode?: Mode +} + +// Styled Components +const MaskImg = styled('img')({ + inlineSize: '100%', + position: 'absolute', + insetBlockEnd: 0, + zIndex: -1 +}) + +const Illustrations = (props: IllustrationsProp) => { + // Props + const { image1, image2, maskImg, mode } = props + + // Vars + const darkImg = '/images/pages/misc-mask-dark.png' + const lightImg = '/images/pages/misc-mask-light.png' + + // Hook + const theme = useTheme() + const hidden = useMediaQuery(theme.breakpoints.down('md')) + const maskBackground = useImageVariant(mode as Mode, lightImg, darkImg) + + function isImageObj(obj: any): obj is ImageObj { + return obj && typeof obj === 'object' && 'src' in obj + } + + if (!hidden) { + return ( + <> + {typeof image1 === 'undefined' || isImageObj(image1) ? ( + {image1?.alt + ) : ( + image1 + )} + {typeof maskImg === 'undefined' || isImageObj(maskImg) ? ( + + ) : ( + maskImg + )} + {typeof image2 === 'undefined' || isImageObj(image2) ? ( + {image2?.alt + ) : ( + image2 + )} + + ) + } else { + return null + } +} + +export default Illustrations diff --git a/front-urban/src/components/Link.tsx b/front-urban/src/components/Link.tsx new file mode 100644 index 0000000..dcfcafe --- /dev/null +++ b/front-urban/src/components/Link.tsx @@ -0,0 +1,29 @@ +'use client' + +// React Imports +import { forwardRef } from 'react' +import type { ComponentProps, ForwardedRef, MouseEvent } from 'react' + +// Next Imports +import NextLink from 'next/link' + +type Props = Omit, 'href' | 'onClick'> & { + href?: string + onClick?: (event: MouseEvent) => void +} + +const Link = (props: Props, ref: ForwardedRef) => { + // Props + const { href, onClick, ...rest } = props + + return ( + onClick(e) : !href ? e => e.preventDefault() : undefined} + /> + ) +} + +export default forwardRef(Link) diff --git a/front-urban/src/components/Providers.tsx b/front-urban/src/components/Providers.tsx new file mode 100644 index 0000000..894c175 --- /dev/null +++ b/front-urban/src/components/Providers.tsx @@ -0,0 +1,37 @@ +// Type Imports +import type { ChildrenType, Direction } from '@core/types' + +// Context Imports +import { VerticalNavProvider } from '@menu/contexts/verticalNavContext' +import { SettingsProvider } from '@core/contexts/settingsContext' +import ThemeProvider from '@components/theme' + +// Component Imports + +// Util Imports +import { getMode, getSettingsFromCookie } from '@core/utils/serverHelpers' + +type Props = ChildrenType & { + direction: Direction +} + +const Providers = (props: Props) => { + // Props + const { children, direction } = props + + // Vars + const mode = getMode() + const settingsCookie = getSettingsFromCookie() + + return ( + + + + {children} + + + + ) +} + +export default Providers diff --git a/front-urban/src/components/card-statistics/CardAccess.tsx b/front-urban/src/components/card-statistics/CardAccess.tsx new file mode 100644 index 0000000..202c67e --- /dev/null +++ b/front-urban/src/components/card-statistics/CardAccess.tsx @@ -0,0 +1,141 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Chip from '@mui/material/Chip' +import Tooltip from '@mui/material/Tooltip' +import Box from '@mui/material/Box' +import { alpha } from '@mui/material/styles' +import AccessTimeIcon from '@mui/icons-material/AccessTime' +import WarningAmberRoundedIcon from '@mui/icons-material/WarningAmberRounded' + +// Tus componentes +import CustomAvatar from '@core/components/mui/Avatar' +import OptionMenu from '@core/components/option-menu' + +type Props = { + accessLog: { + currentAccess: string + lastAccess: string + } +} + +// helpers +const isNoLog = (s?: string) => !s || s === 'Sin registro' + +const formatTime = (s: string) => { + if (isNoLog(s)) return null + const d = new Date(s) + if (Number.isNaN(d.getTime())) return null + return d.toLocaleTimeString('es-AR', { hour: '2-digit', minute: '2-digit' }) +} + +const formatDateTime = (s: string) => { + if (isNoLog(s)) return 'Sin registro' + const d = new Date(s) + if (Number.isNaN(d.getTime())) return 'Sin registro' + return d.toLocaleString('es-AR', { + day: '2-digit', + month: '2-digit', + year: 'numeric', + hour: '2-digit', + minute: '2-digit' + }) +} + +const CardAccess = ({ accessLog }: Props) => { + const timeToday = formatTime(accessLog?.currentAccess) + const isWarning = !timeToday + + const chipLabel = isWarning ? 'Sin registro' : `${timeToday} hs` + const chipColor: 'success' | 'warning' = isWarning ? 'warning' : 'success' + const chipIcon = isWarning ? : + + const tooltipText = isWarning + ? 'No tenemos registro de tu acceso hoy.' + : `Primer ingreso de hoy: ${timeToday} hs` + + return ( + + `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.7 + )} 100%)`, + boxShadow: theme => `0 10px 30px ${alpha(theme.palette.common.black, 0.25)}` + }} + > + +
+ + + + + {/* */} +
+ +
+ + Reloj de acceso + + + + + `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.6 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text', + letterSpacing: 0.2 + }} + > + Hoy: + + + + ({ + px: 1, + fontWeight: 700, + letterSpacing: 0.2, + color: theme.palette[chipColor].contrastText, + border: `1px solid ${alpha(theme.palette[chipColor].main, 0.6)}`, + transition: 'transform .15s ease, box-shadow .15s ease, filter .15s ease', + willChange: 'transform', + '&:hover': { + transform: 'scale(1.04)', + boxShadow: `0 8px 22px ${alpha(theme.palette[chipColor].main, 0.35)}`, + filter: 'saturate(1.05)' + } + })} + /> + + + + + Último acceso: {formatDateTime(accessLog?.lastAccess)} + +
+
+
+ ) +} + +export default CardAccess diff --git a/front-urban/src/components/layout/shared/Logo.tsx b/front-urban/src/components/layout/shared/Logo.tsx new file mode 100644 index 0000000..75013a1 --- /dev/null +++ b/front-urban/src/components/layout/shared/Logo.tsx @@ -0,0 +1,38 @@ +'use client' + +// React Imports +import type { CSSProperties } from 'react' + +// Third-party Imports +import styled from '@emotion/styled' + +// Component Imports +import MaterioLogo from '@core/svg/Logo' + +// Config Imports +import themeConfig from '@configs/themeConfig' + +type LogoTextProps = { + color?: CSSProperties['color'] +} + +const LogoText = styled.span` + color: ${({ color }) => color ?? 'var(--mui-palette-text-primary)'}; + font-size: 1.25rem; + line-height: 1.2; + font-weight: 600; + letter-spacing: 0.15px; + text-transform: uppercase; + margin-inline-start: 10px; +` + +const Logo = ({ color }: { color?: CSSProperties['color'] }) => { + return ( +
+ + {themeConfig.templateName} +
+ ) +} + +export default Logo diff --git a/front-urban/src/components/layout/shared/ModeDropdown.tsx b/front-urban/src/components/layout/shared/ModeDropdown.tsx new file mode 100644 index 0000000..c7da858 --- /dev/null +++ b/front-urban/src/components/layout/shared/ModeDropdown.tsx @@ -0,0 +1,58 @@ +'use client' + +// React Imports +import { useRef, useState } from 'react' + +// MUI Imports +import Tooltip from '@mui/material/Tooltip' +import IconButton from '@mui/material/IconButton' + +// Hook Imports +import { useSettings } from '@core/hooks/useSettings' + +const ModeDropdown = () => { + // States + const [tooltipOpen, setTooltipOpen] = useState(false) + + // Refs + const anchorRef = useRef(null) + + // Hooks + const { settings, updateSettings } = useSettings() + + const handleToggle = () => { + if (settings.mode === 'dark') { + updateSettings({ mode: 'light' }) + } + + if (settings.mode === 'light') { + updateSettings({ mode: 'dark' }) + } + } + + const getModeIcon = () => { + if (settings.mode === 'dark') { + return 'ri-moon-clear-line' + } else { + return 'ri-sun-line' + } + } + + return ( + <> + setTooltipOpen(true)} + onClose={() => setTooltipOpen(false)} + open={tooltipOpen} + PopperProps={{ className: 'capitalize' }} + > + + + + + + ) +} + +export default ModeDropdown diff --git a/front-urban/src/components/layout/shared/UserDropdown.tsx b/front-urban/src/components/layout/shared/UserDropdown.tsx new file mode 100644 index 0000000..85e9672 --- /dev/null +++ b/front-urban/src/components/layout/shared/UserDropdown.tsx @@ -0,0 +1,140 @@ +'use client' + +// React Imports +import { useRef, useState } from 'react' +import type { MouseEvent } from 'react' + +// Next Imports +import { useRouter } from 'next/navigation' + +// MUI Imports +import { styled } from '@mui/material/styles' +import Badge from '@mui/material/Badge' +import Avatar from '@mui/material/Avatar' +import Popper from '@mui/material/Popper' +import Fade from '@mui/material/Fade' +import Paper from '@mui/material/Paper' +import ClickAwayListener from '@mui/material/ClickAwayListener' +import MenuList from '@mui/material/MenuList' +import Typography from '@mui/material/Typography' +import Divider from '@mui/material/Divider' +import MenuItem from '@mui/material/MenuItem' +import Button from '@mui/material/Button' +import { useUserAuth } from '@/app/context/UserAuth' +import { useProfilePicture } from '@/@core/hooks/useProfilePicture' + +// Styled component for badge content +const BadgeContentSpan = styled('span')({ + width: 8, + height: 8, + borderRadius: '50%', + cursor: 'pointer', + backgroundColor: 'var(--mui-palette-success-main)', + boxShadow: '0 0 0 2px var(--mui-palette-background-paper)' +}) + +const UserDropdown = () => { + const { user, token } = useUserAuth() + const { id } = user || {} + + // Hook para obtener la foto de perfil + const { profilePicture } = useProfilePicture(id || '', { auto: !!id }) + + // States + const [open, setOpen] = useState(false) + + // Refs + const anchorRef = useRef(null) + + // Hooks + const router = useRouter() + + const handleDropdownOpen = () => { + !open ? setOpen(true) : setOpen(false) + } + + const handleDropdownClose = (event?: MouseEvent | (MouseEvent | TouchEvent), url?: string) => { + if (url) { + router.push(url) + } + + if (anchorRef.current && anchorRef.current.contains(event?.target as HTMLElement)) { + return + } + + setOpen(false) + } + + const handleLogout = () => { + // Recargar la página completa para limpiar el estado del context + window.location.reload() + } + return ( + <> + } + anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} + className='mis-2' + > + + + + {({ TransitionProps, placement }) => ( + + + handleDropdownClose(e as MouseEvent | TouchEvent)}> + +
+ +
+ + {user?.name || 'Usuario'} + + {user?.role || 'User'} +
+
+ +
+ +
+
+
+
+
+ )} +
+ + ) +} + +export default UserDropdown diff --git a/front-urban/src/components/layout/vertical/Footer.tsx b/front-urban/src/components/layout/vertical/Footer.tsx new file mode 100644 index 0000000..32138dc --- /dev/null +++ b/front-urban/src/components/layout/vertical/Footer.tsx @@ -0,0 +1,13 @@ +// Component Imports +import LayoutFooter from '@layouts/components/vertical/Footer' +import FooterContent from './FooterContent' + +const Footer = () => { + return ( + + + + ) +} + +export default Footer diff --git a/front-urban/src/components/layout/vertical/FooterContent.tsx b/front-urban/src/components/layout/vertical/FooterContent.tsx new file mode 100644 index 0000000..6d6789e --- /dev/null +++ b/front-urban/src/components/layout/vertical/FooterContent.tsx @@ -0,0 +1,33 @@ +'use client' + +// Next Imports + +// Third-party Imports +import classnames from 'classnames' + +// Hook Imports +import useVerticalNav from '@menu/hooks/useVerticalNav' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +const FooterContent = () => { + // Hooks + const { isBreakpointReached } = useVerticalNav() + + return ( +
+

+ {`© ${new Date().getFullYear()}`} +

+ {!isBreakpointReached && ( +
+
+ )} +
+ ) +} + +export default FooterContent diff --git a/front-urban/src/components/layout/vertical/NavToggle.tsx b/front-urban/src/components/layout/vertical/NavToggle.tsx new file mode 100644 index 0000000..72e618e --- /dev/null +++ b/front-urban/src/components/layout/vertical/NavToggle.tsx @@ -0,0 +1,23 @@ +'use client' + +// Hook Imports +import useVerticalNav from '@menu/hooks/useVerticalNav' + +const NavToggle = () => { + // Hooks + const { toggleVerticalNav, isBreakpointReached } = useVerticalNav() + + const handleClick = () => { + toggleVerticalNav() + } + + return ( + <> + {/* */} + {/* Comment following code and uncomment above code in order to toggle menu on desktop screens as well */} + {isBreakpointReached && } + + ) +} + +export default NavToggle diff --git a/front-urban/src/components/layout/vertical/Navbar.tsx b/front-urban/src/components/layout/vertical/Navbar.tsx new file mode 100644 index 0000000..7146c4f --- /dev/null +++ b/front-urban/src/components/layout/vertical/Navbar.tsx @@ -0,0 +1,13 @@ +// Component Imports +import LayoutNavbar from '@layouts/components/vertical/Navbar' +import NavbarContent from './NavbarContent' + +const Navbar = () => { + return ( + + + + ) +} + +export default Navbar diff --git a/front-urban/src/components/layout/vertical/NavbarContent.tsx b/front-urban/src/components/layout/vertical/NavbarContent.tsx new file mode 100644 index 0000000..d7ff38c --- /dev/null +++ b/front-urban/src/components/layout/vertical/NavbarContent.tsx @@ -0,0 +1,26 @@ +// Third-party Imports +import classnames from 'classnames' + +// Component Imports +import ModeDropdown from '@components/layout/shared/ModeDropdown' +import UserDropdown from '@components/layout/shared/UserDropdown' +import NavToggle from './NavToggle' + +// Util Imports +import { verticalLayoutClasses } from '@layouts/utils/layoutClasses' + +const NavbarContent = () => { + return ( +
+
+ +
+
+ + +
+
+ ) +} + +export default NavbarContent diff --git a/front-urban/src/components/layout/vertical/Navigation.tsx b/front-urban/src/components/layout/vertical/Navigation.tsx new file mode 100644 index 0000000..99cce88 --- /dev/null +++ b/front-urban/src/components/layout/vertical/Navigation.tsx @@ -0,0 +1,79 @@ +'use client' + +// React Imports +import { useRef } from 'react' + +// Next Imports +import Link from 'next/link' + +// MUI Imports +import { styled, useTheme } from '@mui/material/styles' + +// Component Imports +import VerticalNav, { NavHeader } from '@menu/vertical-menu' +import VerticalMenu from './VerticalMenu' +import Logo from '@components/layout/shared/Logo' + +// Hook Imports +import useVerticalNav from '@menu/hooks/useVerticalNav' + +// Style Imports +import navigationCustomStyles from '@core/styles/vertical/navigationCustomStyles' + +const StyledBoxForShadow = styled('div')(({ theme }) => ({ + top: 60, + left: -8, + zIndex: 2, + opacity: 0, + position: 'absolute', + pointerEvents: 'none', + width: 'calc(100% + 15px)', + height: theme.mixins.toolbar.minHeight, + transition: 'opacity .15s ease-in-out', + background: `linear-gradient(var(--mui-palette-background-default) 5%, rgb(var(--mui-palette-background-defaultChannel) / 0.85) 30%, rgb(var(--mui-palette-background-defaultChannel) / 0.5) 65%, rgb(var(--mui-palette-background-defaultChannel) / 0.3) 75%, transparent)`, + '&.scrolled': { + opacity: 1 + } +})) + +const Navigation = () => { + // Hooks + const theme = useTheme() + const { isBreakpointReached, toggleVerticalNav } = useVerticalNav() + + // Refs + const shadowRef = useRef(null) + + const scrollMenu = (container: any, isPerfectScrollbar: boolean) => { + container = isBreakpointReached || !isPerfectScrollbar ? container.target : container + + if (shadowRef && container.scrollTop > 0) { + // @ts-ignore + if (!shadowRef.current.classList.contains('scrolled')) { + // @ts-ignore + shadowRef.current.classList.add('scrolled') + } + } else { + // @ts-ignore + shadowRef.current.classList.remove('scrolled') + } + } + + return ( + // eslint-disable-next-line lines-around-comment + // Sidebar Vertical Menu + + {/* Nav Header including Logo & nav toggle icons */} + + + + + {isBreakpointReached && toggleVerticalNav(false)} />} + + + + + ) +} + +export default Navigation diff --git a/front-urban/src/components/layout/vertical/VerticalMenu.tsx b/front-urban/src/components/layout/vertical/VerticalMenu.tsx new file mode 100644 index 0000000..bf92e9e --- /dev/null +++ b/front-urban/src/components/layout/vertical/VerticalMenu.tsx @@ -0,0 +1,149 @@ +// MUI Imports +import Chip from '@mui/material/Chip' +import { useTheme } from '@mui/material/styles' + +// Third-party Imports +import PerfectScrollbar from 'react-perfect-scrollbar' + +// Type Imports +import type { VerticalMenuContextProps } from '@menu/components/vertical-menu/Menu' + +// Component Imports +import { Menu, SubMenu, MenuItem, MenuSection } from '@menu/vertical-menu' + +// Hook Imports +import useVerticalNav from '@menu/hooks/useVerticalNav' + +// Styled Component Imports +import StyledVerticalNavExpandIcon from '@menu/styles/vertical/StyledVerticalNavExpandIcon' + +// Style Imports +import menuItemStyles from '@core/styles/vertical/menuItemStyles' +import menuSectionStyles from '@core/styles/vertical/menuSectionStyles' +import { useUserAuth } from '@/app/context/UserAuth' + +type RenderExpandIconProps = { + open?: boolean + transitionDuration?: VerticalMenuContextProps['transitionDuration'] +} + +const RenderExpandIcon = ({ open, transitionDuration }: RenderExpandIconProps) => ( + + + +) + +const VerticalMenu = ({ scrollMenu }: { scrollMenu: (container: any, isPerfectScrollbar: boolean) => void }) => { + + // Hooks + const { user } = useUserAuth() + const { role } = user || {} + const theme = useTheme() + const { isBreakpointReached, transitionDuration } = useVerticalNav() + + + const userMenu = { + 'INSTRUCTOR': VerticalMenuProfesor(transitionDuration), + 'ADMIN': VerticalMenuAdmin(transitionDuration) + } + + const ScrollWrapper = isBreakpointReached ? 'div' : PerfectScrollbar + + return ( + // eslint-disable-next-line lines-around-comment + /* Custom scrollbar instead of browser scroll, remove if you want browser scroll only */ + scrollMenu(container, false) + } + : { + options: { wheelPropagation: false, suppressScrollX: true }, + onScrollY: container => scrollMenu(container, true) + })} + > + {/* Incase you also want to scroll NavHeader to scroll with Vertical Menu, remove NavHeader from above and paste it below this comment */} + <> + {userMenu[role as keyof typeof userMenu] ?? null} + + + ) +} + +const VerticalMenuProfesor = (transitionDuration: any) => { + const theme = useTheme() + return ( + } + renderExpandedMenuItemIcon={{ icon: }} + menuSectionStyles={menuSectionStyles(theme)} + > + } + // suffix={} + > + }> + Inicio + + }> + Clases + + + + ) +} + +const VerticalMenuAdmin = (transitionDuration: any) => { + const theme = useTheme() + return ( + } + renderExpandedMenuItemIcon={{ icon: }} + menuSectionStyles={menuSectionStyles(theme)} + > + } + // suffix={} + defaultOpen + > + }> + Inicio + + }> + Clases + + }> + Usuarios + + + + } + > + + Estado + + + } + > + + Backup + + + Sistema + + + + + ) +} + +export default VerticalMenu diff --git a/front-urban/src/components/stepper-dot/index.tsx b/front-urban/src/components/stepper-dot/index.tsx new file mode 100644 index 0000000..96c4173 --- /dev/null +++ b/front-urban/src/components/stepper-dot/index.tsx @@ -0,0 +1,31 @@ +// MUI Imports +import type { StepIconProps } from '@mui/material/StepIcon' + +// Third-party Imports +import classnames from 'classnames' + +// Style Imports +import styles from './styles.module.css' + +const StepperCustomDot = (props: StepIconProps) => { + // Props + const { active, completed, error } = props + + if (error) { + return + } else if (completed) { + return ( +
+ +
+ ) + } else { + return
+ } +} + +export default StepperCustomDot diff --git a/front-urban/src/components/stepper-dot/styles.module.css b/front-urban/src/components/stepper-dot/styles.module.css new file mode 100644 index 0000000..7b10116 --- /dev/null +++ b/front-urban/src/components/stepper-dot/styles.module.css @@ -0,0 +1,23 @@ +.stepperCustomDot { + inline-size: 20px; + block-size: 20px; + border-width: 3px; + border-radius: 50%; + border-style: solid; + border-color: var(--mui-palette-primary-main); + + &.activeStepperCustomDot { + border-width: 5px; + border-color: var(--mui-palette-primary-main); + background-color: var(--mui-palette-common-white); + } + + &.completedStepperCustomDot { + background-color: var(--mui-palette-primary-main); + border-color: var(--mui-palette-primary-main); + } +} + +[data-mui-color-scheme='dark'] .activeStepperCustomDot { + background-color: var(--mui-palette-background-default); +} diff --git a/front-urban/src/components/theme/ModeChanger.tsx b/front-urban/src/components/theme/ModeChanger.tsx new file mode 100644 index 0000000..c32b40f --- /dev/null +++ b/front-urban/src/components/theme/ModeChanger.tsx @@ -0,0 +1,25 @@ +// React Imports +import { useEffect } from 'react' + +// MUI Imports +import { useColorScheme } from '@mui/material/styles' + +// Hook Imports +import { useSettings } from '@core/hooks/useSettings' + +const ModeChanger = () => { + // Hooks + const { setMode } = useColorScheme() + const { settings } = useSettings() + + useEffect(() => { + if (settings.mode) { + setMode(settings.mode) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [settings.mode]) + + return null +} + +export default ModeChanger diff --git a/front-urban/src/components/theme/index.tsx b/front-urban/src/components/theme/index.tsx new file mode 100644 index 0000000..0ce6d60 --- /dev/null +++ b/front-urban/src/components/theme/index.tsx @@ -0,0 +1,95 @@ +'use client' + +// React Imports +import { useMemo } from 'react' + +// MUI Imports +import { deepmerge } from '@mui/utils' +import { + Experimental_CssVarsProvider as CssVarsProvider, + experimental_extendTheme as extendTheme, + lighten, + darken +} from '@mui/material/styles' +import { AppRouterCacheProvider } from '@mui/material-nextjs/v14-appRouter' +import CssBaseline from '@mui/material/CssBaseline' +import type {} from '@mui/material/themeCssVarsAugmentation' //! Do not remove this import otherwise you will get type errors while making a production build +import type {} from '@mui/lab/themeAugmentation' //! Do not remove this import otherwise you will get type errors while making a production build + +// Type Imports +import type { ChildrenType, Direction } from '@core/types' + +// Component Imports +import ModeChanger from './ModeChanger' + +// Config Imports +import themeConfig from '@configs/themeConfig' +import primaryColorConfig from '@configs/primaryColorConfig' + +// Hook Imports +import { useSettings } from '@core/hooks/useSettings' + +// Core Theme Imports +import defaultCoreTheme from '@core/theme' + +type Props = ChildrenType & { + direction: Direction +} + +const ThemeProvider = (props: Props) => { + // Props + const { children, direction } = props + + // Hooks + const { settings } = useSettings() + + // Merge the primary color scheme override with the core theme + const theme = useMemo(() => { + const newColorScheme = { + colorSchemes: { + light: { + palette: { + primary: { + main: primaryColorConfig[0].main, + light: lighten(primaryColorConfig[0].main as string, 0.2), + dark: darken(primaryColorConfig[0].main as string, 0.1) + } + } + }, + dark: { + palette: { + primary: { + main: primaryColorConfig[0].main, + light: lighten(primaryColorConfig[0].main as string, 0.2), + dark: darken(primaryColorConfig[0].main as string, 0.1) + } + } + } + } + } + + const coreTheme = deepmerge(defaultCoreTheme(settings.mode || 'light', direction), newColorScheme) + + return extendTheme(coreTheme) + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [settings.mode]) + + return ( + + + <> + + + {children} + + + + ) +} + +export default ThemeProvider diff --git a/front-urban/src/components/theme/mergedTheme.ts b/front-urban/src/components/theme/mergedTheme.ts new file mode 100644 index 0000000..6f57c23 --- /dev/null +++ b/front-urban/src/components/theme/mergedTheme.ts @@ -0,0 +1,29 @@ +/* + * We recommend using the merged theme if you want to override our core theme. + * This means you can use our core theme and override it with your own customizations. + * Write your overrides in the userTheme object in this file. + * The userTheme object is merged with the coreTheme object within this file. + * Export this file and import it in the `@components/theme/index.tsx` file to use the merged theme. + */ + +// MUI Imports +import { deepmerge } from '@mui/utils' +import type { Theme } from '@mui/material/styles' + +// Type Imports +import type { Settings } from '@core/contexts/settingsContext' +import type { SystemMode } from '@core/types' + +// Core Theme Imports +import coreTheme from '@core/theme' + +const mergedTheme = (settings: Settings, mode: SystemMode, direction: Theme['direction']) => { + // Vars + const userTheme = { + // Write your overrides here. + } as Theme + + return deepmerge(coreTheme(mode, direction), userTheme) +} + +export default mergedTheme diff --git a/front-urban/src/components/theme/types.ts b/front-urban/src/components/theme/types.ts new file mode 100644 index 0000000..3c2dda2 --- /dev/null +++ b/front-urban/src/components/theme/types.ts @@ -0,0 +1,124 @@ +/* + ! This file is for adding custom types to the MUI theme, components and props. + ! Please do not remove anything from this file as it may break the application. + ! You can add your own custom types to the MUI theme, components and props in this file + ! but you must be aware about the MUI theme structure along with MUI CSS Variables. + ! MUI Theme: https://mui.com/material-ui/customization/default-theme/ + ! MUI CSS Variables: https://mui.com/material-ui/experimental-api/css-theme-variables/overview/ + */ + +// MUI Imports +import {} from '@mui/material/styles' + +declare module '@mui/material/styles' { + // eslint-disable-next-line lines-around-comment + // Theme + interface Theme { + shape: { + borderRadius: number + customBorderRadius: { + xs: number + sm: number + md: number + lg: number + xl: number + } + } + customShadows: { + xs: string + sm: string + md: string + lg: string + xl: string + } + mainColorChannels: { + light: string + dark: string + lightShadow: string + darkShadow: string + } + } + interface ThemeOptions { + shape?: { + borderRadius?: number + customBorderRadius?: { + xs?: number + sm?: number + md?: number + lg?: number + xl?: number + } + } + customShadows?: { + xs?: string + sm?: string + md?: string + lg?: string + xl?: string + } + mainColorChannels?: { + light?: string + dark?: string + lightShadow?: string + darkShadow?: string + } + } + + // Palette Color + interface PaletteColor { + lighterOpacity?: string + lightOpacity?: string + mainOpacity?: string + darkOpacity?: string + darkerOpacity?: string + } + interface SimplePaletteColorOptions { + lighterOpacity?: string + lightOpacity?: string + mainOpacity?: string + darkOpacity?: string + darkerOpacity?: string + } + + // Palette + interface Palette { + customColors: { + bodyBg: string + chatBg: string + greyLightBg: string + inputBorder: string + tableHeaderBg: string + tooltipText: string + trackBg: string + } + } + interface PaletteOptions { + customColors?: { + bodyBg?: string + chatBg?: string + greyLightBg?: string + inputBorder?: string + tableHeaderBg?: string + tooltipText?: string + trackBg?: string + } + } +} + +declare module '@mui/material/Chip' { + interface ChipPropsVariantOverrides { + tonal: true + } +} + +declare module '@mui/material/Pagination' { + interface PaginationPropsVariantOverrides { + tonal: true + } +} + +declare module '@mui/lab/TimelineDot' { + interface TimelineDotPropsVariantOverrides { + tonal: true + } +} diff --git a/front-urban/src/components/theme/userTheme.ts b/front-urban/src/components/theme/userTheme.ts new file mode 100644 index 0000000..f8a677c --- /dev/null +++ b/front-urban/src/components/theme/userTheme.ts @@ -0,0 +1,25 @@ +/* + ! We do not recommend using your own custom theme built from scratch. + ! Instead, we recommend using the merged theme (src/components/theme/mergedTheme.ts) and customizing it as per your needs. + ! If you still want to use your own custom theme, you must be aware about the MUI theme structure along with MUI CSS Variables. + ! MUI Theme: https://mui.com/material-ui/customization/default-theme/ + ! MUI CSS Variables: https://mui.com/material-ui/experimental-api/css-theme-variables/overview/ + ! Export this file and import it in the `@components/theme/index.tsx` file to use only this theme. + */ + +// MUI Imports +import type { Theme } from '@mui/material/styles' + +// Type Imports +/* Enable following line and the `settings` parameter in the below `userTheme` + function in order to access `settings` context value in your custom theme object + */ +// import type { Settings } from '@core/contexts/settingsContext' + +const userTheme = (/* settings: Settings */): Theme => { + return { + // Write your custom theme object here. + } as Theme +} + +export default userTheme diff --git a/front-urban/src/configs/dialogInfoContent.tsx b/front-urban/src/configs/dialogInfoContent.tsx new file mode 100644 index 0000000..af95e47 --- /dev/null +++ b/front-urban/src/configs/dialogInfoContent.tsx @@ -0,0 +1,316 @@ +import React from 'react' +import { Typography, Stack, Box, List, ListItem, ListItemText } from '@mui/material' + +/** + * Configuración centralizada de contenidos informativos para los CustomDialog + * Usar como: infoContent={DIALOG_INFO.claseUpsert} + */ +export const DIALOG_INFO = { + claseUpsert: ( + + + Crear o editar clases + + + + Acá podés crear o editar clases. Tenés dos tipos: + + + + + + Se repite semanalmente. Primero elegís un rango de fechas + (por ejemplo, del 1 al 30 del mes) y luego seleccionás + qué días querés dar clase (domingo, lunes, martes, etc.) + y en qué horario. +
+ Ejemplo: “Reggaetón todo el mes, lunes y miércoles de 19:00 a 20:00”. + + } + primaryTypographyProps={{ variant: 'body2', fontWeight: 500 }} + secondaryTypographyProps={{ variant: 'caption' }} + /> +
+ + + + +
+ + + Edición y baja de clases + + + Solo se pueden editar clases que aún no hayan pasado (no se pueden modificar clases en fechas anteriores al día de hoy). + También podés dar de baja una clase para que deje de mostrarse en el sistema. + +
+ ), + + usuarioForm: ( + + + Alta y edición de usuarios + + + + En este formulario podés dar de alta nuevos usuarios o editar los existentes. + + + + + + + + + + + + + + + + + + + + + + En el modo edición también vas a poder dar de baja al usuario para que ya no aparezca como activo en el sistema. + + + ), + + configuracion: ( + + + Configuración del sistema + + + Ajusta los parámetros generales de la aplicación. + + + ), + + // Agregar más contenidos según necesites... + // Ejemplo con componente más complejo: + invoiceDetail: ( + + + Detalles de factura + + + Aquí puedes ver y gestionar la información de la factura. + + + Nota: Las facturas pagadas no pueden ser editadas. + + + ), + + claseDetail: ( + + + Detalle de la clase + + + En esta vista podés ver toda la información de la clase: + + + + + + + + + + + ), + + dashboard: ( + + + Dashboard - Panel de control + + + Vista general con estadísticas y métricas del sistema: + + + + + + + + + + + + + + + + + + + + Gráficos de distribución + + + Los gráficos de torta muestran la proporción entre clases/usuarios activos e inactivos, + y el estado de las facturas (pagadas vs pendientes). Se adaptan automáticamente al tamaño + de pantalla mostrando hasta 3 gráficos en desktop y 2 en mobile. + + + ), + attendanceDialog: ( + + + Control de asistencias + + + + En esta ventana vas a poder ver la lista de asistentes de la clase y marcar quiénes + están presentes. + + + + + + + + + + + + + + Podés cambiar el estado de cada asistente haciendo clic sobre su fila o usando el + control que aparezca a la derecha. + + + ), + + accessLogsDialog: ( + + + Registro de Accesos + + + + Acá podés ver todos los ingresos y egresos de un usuario en una fecha específica. + + + + + + + + + + + + + + + + + ) +} as const + +/** + * Type helper para autocompletado + */ +export type DialogInfoKey = keyof typeof DIALOG_INFO + +/** + * Helper function para obtener contenido con validación + */ +export const getDialogInfo = (key: DialogInfoKey) => DIALOG_INFO[key] diff --git a/front-urban/src/configs/primaryColorConfig.ts b/front-urban/src/configs/primaryColorConfig.ts new file mode 100644 index 0000000..c50833c --- /dev/null +++ b/front-urban/src/configs/primaryColorConfig.ts @@ -0,0 +1,18 @@ +export type PrimaryColorConfig = { + name?: string + light?: string + main: string + dark?: string +} + +// Primary color config object +const primaryColorConfig: PrimaryColorConfig[] = [ + { + name: 'primary-1', + light: '#A379FF', + main: '#8C57FF', + dark: '#7E4EE6' + } +] + +export default primaryColorConfig diff --git a/front-urban/src/configs/themeConfig.ts b/front-urban/src/configs/themeConfig.ts new file mode 100644 index 0000000..d89d4c9 --- /dev/null +++ b/front-urban/src/configs/themeConfig.ts @@ -0,0 +1,34 @@ +/* + * If you change the following items in the config object, you will not see any effect in the local development server + * as these are stored in the cookie (cookie has the highest priority over the themeConfig): + * 1. mode + * + * To see the effect of the above items, you can click on the reset button from the Customizer + * which is on the top-right corner of the customizer besides the close button. + * This will reset the cookie to the values provided in the config object below. + * + * Another way is to clear the cookie from the browser's Application/Storage tab and then reload the page. + */ + +// Type Imports +import type { Mode } from '@core/types' + +export type Config = { + templateName: string + settingsCookieName: string + mode: Mode + layoutPadding: number + compactContentWidth: number + disableRipple: boolean +} + +const themeConfig: Config = { + templateName: 'Urban dance', + settingsCookieName: 'urban-dance', + mode: 'light', // 'light', 'dark' + layoutPadding: 24, // Common padding for header, content, footer layout components (in px) + compactContentWidth: 1440, // in px + disableRipple: false // true, false +} + +export default themeConfig diff --git a/front-urban/src/lib/AxiosInterceptorProvider.tsx b/front-urban/src/lib/AxiosInterceptorProvider.tsx new file mode 100644 index 0000000..0eb687b --- /dev/null +++ b/front-urban/src/lib/AxiosInterceptorProvider.tsx @@ -0,0 +1,53 @@ +'use client'; + +import { useLayoutEffect, useRef } from 'react'; +import { useRouter } from 'next/navigation'; +import { useUserAuth } from '@/app/context/UserAuth'; +import apiClient from './apiClient'; + +/** + * Debe montarse dentro de . + * + * - Request interceptor: añade Authorization: Bearer en cada llamada de apiClient. + * - Response interceptor: si el backend responde 401, redirige a /unauthorized. + * + * Usa useLayoutEffect para que los interceptores queden registrados ANTES + * de que cualquier useEffect en componentes hijos dispare requests. + */ +export function AxiosInterceptorProvider({ children }: { children: React.ReactNode }) { + const router = useRouter(); + const { token } = useUserAuth(); + + // El ref se inicializa con el token actual en el montaje. + // useLayoutEffect lo mantiene sincronizado antes de que corran los useEffect de hijos. + const tokenRef = useRef(token); + useLayoutEffect(() => { + tokenRef.current = token; + }, [token]); + + useLayoutEffect(() => { + const requestId = apiClient.interceptors.request.use(config => { + if (tokenRef.current) { + config.headers.Authorization = `Bearer ${tokenRef.current}`; + } + return config; + }); + + const responseId = apiClient.interceptors.response.use( + response => response, + error => { + if (error?.response?.status === 401) { + router.push('/unauthorized'); + } + return Promise.reject(error); + } + ); + + return () => { + apiClient.interceptors.request.eject(requestId); + apiClient.interceptors.response.eject(responseId); + }; + }, [router]); + + return <>{children}; +} diff --git a/front-urban/src/lib/apiClient.ts b/front-urban/src/lib/apiClient.ts new file mode 100644 index 0000000..07e04f1 --- /dev/null +++ b/front-urban/src/lib/apiClient.ts @@ -0,0 +1,13 @@ +import axios from 'axios'; + +/** + * Instancia axios compartida para todas las llamadas al backend. + * - baseURL apunta a NEXT_PUBLIC_BACKEND_URL + * - El header Authorization se inyecta automáticamente por AxiosInterceptorProvider + * cuando el usuario está autenticado. + */ +const apiClient = axios.create({ + baseURL: process.env.NEXT_PUBLIC_BACKEND_URL ?? '', +}); + +export default apiClient; diff --git a/front-urban/src/libs/ApexCharts.tsx b/front-urban/src/libs/ApexCharts.tsx new file mode 100644 index 0000000..8510130 --- /dev/null +++ b/front-urban/src/libs/ApexCharts.tsx @@ -0,0 +1,5 @@ +import dynamic from 'next/dynamic' + +const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }) + +export default Chart diff --git a/front-urban/src/libs/styles/AppReactApexCharts.tsx b/front-urban/src/libs/styles/AppReactApexCharts.tsx new file mode 100644 index 0000000..554a6ef --- /dev/null +++ b/front-urban/src/libs/styles/AppReactApexCharts.tsx @@ -0,0 +1,108 @@ +'use client' + +// MUI Imports +import Box from '@mui/material/Box' +import { styled } from '@mui/material/styles' +import type { BoxProps } from '@mui/material/Box' + +// Third-party Imports +import type { Props } from 'react-apexcharts' + +// Component Imports +import ReactApexcharts from '@/libs/ApexCharts' + +type ApexChartWrapperProps = Props & { + boxProps?: BoxProps +} + +// Styled Components +const ApexChartWrapper = styled(Box)(({ theme }) => ({ + '& .apexcharts-canvas': { + "& line[stroke='transparent']": { + display: 'none' + }, + '& .apexcharts-tooltip': { + boxShadow: 'var(--mui-shadows-3)', + borderColor: 'var(--mui-palette-divider)', + background: 'var(--mui-palette-background-paper)', + ...(theme.direction === 'rtl' && { + '.apexcharts-tooltip-marker': { + marginInlineEnd: 10, + marginInlineStart: 0 + }, + '.apexcharts-tooltip-text-y-value': { + marginInlineStart: 5, + marginInlineEnd: 0 + } + }), + '& .apexcharts-tooltip-title': { + fontWeight: 600, + borderColor: 'var(--mui-palette-divider)', + background: 'var(--mui-palette-background-paper)' + }, + '&.apexcharts-theme-light': { + color: 'var(--mui-palette-text-primary)' + }, + '&.apexcharts-theme-dark': { + color: 'var(--mui-palette-common-white)' + }, + '& .apexcharts-tooltip-series-group:first-of-type': { + paddingBottom: 0 + }, + '& .bar-chart': { + padding: theme.spacing(2, 2.5) + } + }, + '& .apexcharts-xaxistooltip': { + borderColor: 'var(--mui-palette-divider)', + + // background: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.customColors.bodyBg, + '&:after': { + // borderBottomColor: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.customColors.bodyBg + }, + '&:before': { + borderBottomColor: 'var(--mui-palette-divider)' + } + }, + '& .apexcharts-yaxistooltip': { + borderColor: 'var(--mui-palette-divider)', + + // background: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.customColors.bodyBg, + '&:after': { + // borderLeftColor: theme.palette.mode === 'light' ? theme.palette.grey[50] : theme.palette.customColors.bodyBg + }, + '&:before': { + borderLeftColor: 'var(--mui-palette-divider)' + } + }, + '& .apexcharts-xaxistooltip-text, & .apexcharts-yaxistooltip-text': { + color: 'var(--mui-palette-text-primary)' + }, + '& .apexcharts-yaxis .apexcharts-yaxis-texts-g .apexcharts-yaxis-label': { + textAnchor: theme.direction === 'rtl' ? 'start' : undefined + }, + '& .apexcharts-text, & .apexcharts-tooltip-text, & .apexcharts-datalabel-label, & .apexcharts-datalabel, & .apexcharts-xaxistooltip-text, & .apexcharts-yaxistooltip-text, & .apexcharts-legend-text': + { + fontFamily: `${theme.typography.fontFamily} !important` + }, + '& .apexcharts-pie-label': { + filter: 'none' + }, + '& .apexcharts-marker': { + boxShadow: 'none' + } + } +})) + +const AppReactApexCharts = (props: ApexChartWrapperProps) => { + // Props + const { boxProps, ...rest } = props + + return ( + + + + ) +} + +export default AppReactApexCharts diff --git a/front-urban/src/middleware.txt b/front-urban/src/middleware.txt new file mode 100644 index 0000000..a7ff9ac --- /dev/null +++ b/front-urban/src/middleware.txt @@ -0,0 +1,85 @@ +import { NextRequest, NextResponse } from 'next/server' + +export async function middleware(request: NextRequest) { + const url = request.nextUrl + const tokenFromUrl = url.searchParams.get('t') + const cookieValue = request.cookies.get('authToken')?.value + + let token: string | undefined = undefined + let shouldRevalidate = false + + // 1. Si viene en la URL, usalo y forzá revalidación + if (tokenFromUrl) { + token = tokenFromUrl + shouldRevalidate = true + } else if (cookieValue) { + try { + const parsed = JSON.parse(cookieValue) + token = parsed.token + + const ageInMs = Date.now() - parsed.validatedAt + const fiveMinutes = 5 * 60 * 1000 + shouldRevalidate = ageInMs > fiveMinutes + } catch { + console.warn('⚠️ Cookie malformada') + token = undefined + } + } + + if (!token) { + console.warn('⛔ No token found') + return NextResponse.redirect(new URL('/unauthorized', request.url)) + } + + try { + let autorizado = true + + if (shouldRevalidate) { + const verifyResponse = await fetch(`http://localhost:3001/auth/verify?t=${token}`) + const data = await verifyResponse.json() + autorizado = data.autorizado + } + + if (!autorizado) { + console.warn('⛔ Token inválido') + return NextResponse.redirect(new URL('/unauthorized', request.url)) + } + + const payload = JSON.stringify({ token, validatedAt: Date.now() }) + + if (tokenFromUrl) { + const cleanUrl = new URL(request.url) + cleanUrl.searchParams.delete('t') + + const redirectResponse = NextResponse.redirect(cleanUrl, 307) + redirectResponse.cookies.set('authToken', payload, { + path: '/', + maxAge: 60 * 60, // 1 hora total + sameSite: 'lax', + secure: false, // true en producción con HTTPS + }) + + return redirectResponse + } + + if (shouldRevalidate) { + const response = NextResponse.next() + response.cookies.set('authToken', payload, { + path: '/', + maxAge: 60 * 60, + sameSite: 'lax', + secure: false, + }) + return response + } + + return NextResponse.next() + } catch (error) { + console.error('💥 Error al verificar token:', error) + return NextResponse.redirect(new URL('/unauthorized', request.url)) + } +} + +export const config = { + matcher: ['/((?!_next|favicon.ico|unauthorized|api).*)'], +} diff --git a/front-urban/src/types/pages/widgetTypes.ts b/front-urban/src/types/pages/widgetTypes.ts new file mode 100644 index 0000000..666b7c1 --- /dev/null +++ b/front-urban/src/types/pages/widgetTypes.ts @@ -0,0 +1,18 @@ +// Type Imports +import type { ThemeColor } from '@core/types' +import type { OptionsMenuType } from '@core/components/option-menu/types' +import type { CustomAvatarProps } from '@core/components/mui/Avatar' + +// FIXME - Remove +export type CardStatsVerticalProps = { + title: string + stats: string + avatarIcon: string + subtitle: string + avatarColor?: ThemeColor + trendNumber: string + trend?: 'positive' | 'negative' + avatarSkin?: CustomAvatarProps['skin'] + avatarSize?: number + moreOptions?: OptionsMenuType +} diff --git a/front-urban/src/utils/CustomDialog.tsx b/front-urban/src/utils/CustomDialog.tsx new file mode 100644 index 0000000..a95ec15 --- /dev/null +++ b/front-urban/src/utils/CustomDialog.tsx @@ -0,0 +1,225 @@ +'use client' +import * as React from 'react' +import CloseIcon from '@mui/icons-material/Close' +import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined' +import { + Dialog, + DialogTitle, + DialogContent, + DialogActions, + IconButton, + SxProps, + Theme, + DialogProps, + Popover, +} from '@mui/material' + + +/** Scroll moderno que respeta tu paleta/estética */ +export const modernScrollbarSX: SxProps = { + maxHeight: '70vh', + overflowY: 'auto', + scrollbarGutter: 'stable', + scrollbarWidth: 'thin', // Firefox + scrollbarColor: 'rgba(197,171,255,0.65) rgba(255,255,255,0.06)', + '&::-webkit-scrollbar': { width: 10 }, + '&::-webkit-scrollbar-track': { + background: 'rgba(255,255,255,0.03)', + borderRadius: 999, + border: '1px solid rgba(255,255,255,0.06)', + }, + '&::-webkit-scrollbar-thumb': { + borderRadius: 999, + background: + 'linear-gradient(180deg, var(--mui-palette-primary-main), rgba(197,171,255,0.9))', + boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.15)', + }, + '&::-webkit-scrollbar-thumb:hover': { + background: + 'linear-gradient(180deg, var(--mui-palette-primary-light), rgba(197,171,255,1))', + }, +} + +export type CustomDialogProps = Omit & { + open: boolean + onClose: () => void + /** Título del dialog (texto o nodo) */ + title?: React.ReactNode + /** Zona de acciones al pie (botones) */ + actions?: React.ReactNode + /** Contenido del popover de información (opcional) */ + infoContent?: React.ReactNode + /** Estilos extra */ + paperSx?: SxProps + titleSx?: SxProps + contentSx?: SxProps + /** Props extra para secciones */ + titleProps?: React.ComponentProps + contentProps?: React.ComponentProps + /** Mostrar botón X de cierre en el título */ + showCloseButton?: boolean + maxWidth?: DialogProps['maxWidth'] +} + +const CustomDialog: React.FC = ({ + open, + onClose, + title, + actions, + children, + maxWidth = 'xs', + fullWidth = true, + showCloseButton = true, + infoContent, + paperSx, + titleSx, + contentSx, + titleProps, + contentProps, + ...dialogProps +}) => { + const [anchorEl, setAnchorEl] = React.useState(null) + + const handleInfoClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget) + } + + const handleInfoClose = () => { + setAnchorEl(null) + } + + const openPopover = Boolean(anchorEl) + const popoverId = openPopover ? 'info-popover' : undefined + + return ( + + {title !== undefined && ( + + {title} + {infoContent && ( + + + + )} + {showCloseButton && ( + + + + )} + + )} + + + {children} + + + {actions ? {actions} : null} + + {infoContent && ( + + {infoContent} + + )} + + ) +} + +export default CustomDialog diff --git a/front-urban/src/utils/diasSemana.ts b/front-urban/src/utils/diasSemana.ts new file mode 100644 index 0000000..7d09c1d --- /dev/null +++ b/front-urban/src/utils/diasSemana.ts @@ -0,0 +1 @@ +export const diasSemana = ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo']; diff --git a/front-urban/src/utils/diasToIndex.ts b/front-urban/src/utils/diasToIndex.ts new file mode 100644 index 0000000..e2855df --- /dev/null +++ b/front-urban/src/utils/diasToIndex.ts @@ -0,0 +1,10 @@ +// Map nombre → índice dayjs().day() (0=Dom..6=Sáb) +export const diasToIndex: Record = { + Lunes: 1, + Martes: 2, + Miércoles: 3, + Jueves: 4, + Viernes: 5, + Sábado: 6, + Domingo: 0, +}; diff --git a/front-urban/src/utils/downloadBackup.ts b/front-urban/src/utils/downloadBackup.ts new file mode 100644 index 0000000..27b8a7e --- /dev/null +++ b/front-urban/src/utils/downloadBackup.ts @@ -0,0 +1,91 @@ +import apiClient from '@/lib/apiClient'; + +// Función para descargar backup +export const downloadDatabaseBackup = async (token: string) => { + try { + const response = await apiClient.get('/backup/download', { responseType: 'blob' }); + + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const fileName = `database-backup-${timestamp}.sql`; + + const blob = new Blob([response.data], { type: 'application/sql' }); + const url = window.URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.href = url; + link.download = fileName; + document.body.appendChild(link); + link.click(); + + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + + return { success: true, fileName }; + } catch (error: any) { + console.error('Error descargando backup:', error); + + if (error.response?.status === 401) { + throw new Error('Sin autorización'); + } else { + throw new Error('Error al generar el backup'); + } + } +}; + +// Nueva función para validar archivo antes de subir +export const validateBackupFile = async (file: File) => { + try { + const formData = new FormData(); + formData.append('backup', file); + + const response = await apiClient.post('/backup/validate', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + return { success: true, data: response.data }; + } catch (error: any) { + console.error('Error validando backup:', error); + + if (error.response?.status === 401) { + throw new Error('Sin autorización'); + } else if (error.response?.status === 400) { + throw new Error('Archivo inválido. Solo se permiten archivos .sql válidos'); + } else { + throw new Error('Error al validar el archivo de backup'); + } + } +}; + +// Función para subir y restaurar backup +export const uploadBackup = async (file: File) => { + try { + const formData = new FormData(); + formData.append('backup', file); + + const response = await apiClient.post('/backup/upload', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + return { success: true, data: response.data }; + } catch (error: any) { + console.error('Error subiendo backup:', error); + + if (error.response?.status === 401) { + throw new Error('Sin autorización'); + } else if (error.response?.status === 400) { + throw new Error('Archivo inválido. Solo se permiten archivos .sql'); + } else { + throw new Error('Error al procesar el archivo de backup'); + } + } +}; + +// Función para verificar el estado del servicio de backup +export const checkBackupStatus = async () => { + try { + const response = await apiClient.get('/backup/status'); + return response.data; + } catch (error: any) { + throw new Error('Error al verificar el estado del backup'); + } +}; diff --git a/front-urban/src/utils/modernScrollBarSX.ts b/front-urban/src/utils/modernScrollBarSX.ts new file mode 100644 index 0000000..39f7c34 --- /dev/null +++ b/front-urban/src/utils/modernScrollBarSX.ts @@ -0,0 +1,27 @@ +export const modernScrollbarSX = { + maxHeight: '70vh', + overflowY: 'auto', + scrollbarGutter: 'stable', // evita saltos de layout + scrollbarWidth: 'thin', // Firefox + scrollbarColor: 'rgba(197,171,255,0.65) rgba(255,255,255,0.06)', + + /* Chrome/Edge/Safari */ + '&::-webkit-scrollbar': { + width: 10, + }, + '&::-webkit-scrollbar-track': { + background: 'rgba(255,255,255,0.03)', + borderRadius: 999, + border: '1px solid rgba(255,255,255,0.06)', + }, + '&::-webkit-scrollbar-thumb': { + borderRadius: 999, + background: + 'linear-gradient(180deg, var(--mui-palette-primary-main), rgba(197,171,255,0.9))', + boxShadow: 'inset 0 0 0 1px rgba(255,255,255,0.15)', + }, + '&::-webkit-scrollbar-thumb:hover': { + background: + 'linear-gradient(180deg, var(--mui-palette-primary-light), rgba(197,171,255,1))', + }, +}; diff --git a/front-urban/src/utils/parseLocalDate.ts b/front-urban/src/utils/parseLocalDate.ts new file mode 100644 index 0000000..3efad95 --- /dev/null +++ b/front-urban/src/utils/parseLocalDate.ts @@ -0,0 +1,4 @@ +export function parseLocalDate(yyyyMmDd: string) { + const [y, m, d] = yyyyMmDd.split('-').map(Number); + return new Date(y, m - 1, d); // medianoche local +} diff --git a/front-urban/src/utils/rgbaToHex.ts b/front-urban/src/utils/rgbaToHex.ts new file mode 100644 index 0000000..24cb988 --- /dev/null +++ b/front-urban/src/utils/rgbaToHex.ts @@ -0,0 +1,46 @@ +export const rgbaToHex = (colorStr: string, forceRemoveAlpha: boolean = false) => { + // Check if the input string contains '/' + const hasSlash = colorStr.includes('/') + + if (hasSlash) { + // Extract the RGBA values from the input string + const rgbaValues = colorStr.match(/(\d+)\s+(\d+)\s+(\d+)\s+\/\s+([\d.]+)/) + + if (!rgbaValues) { + return colorStr // Return the original string if it doesn't match the expected format + } + + const [red, green, blue, alpha] = rgbaValues.slice(1, 5).map(parseFloat) + + // Convert the RGB values to hexadecimal format + const redHex = red.toString(16).padStart(2, '0') + const greenHex = green.toString(16).padStart(2, '0') + const blueHex = blue.toString(16).padStart(2, '0') + + // Convert alpha to a hexadecimal format (assuming it's already a decimal value in the range [0, 1]) + const alphaHex = forceRemoveAlpha + ? '' + : Math.round(alpha * 255) + .toString(16) + .padStart(2, '0') + + // Combine the hexadecimal values to form the final hex color string + const hexColor = `#${redHex}${greenHex}${blueHex}${alphaHex}` + + return hexColor + } else { + // Use the second code block for the case when '/' is not present + return ( + '#' + + colorStr + .replace(/^rgba?\(|\s+|\)$/g, '') // Get's rgba / rgb string values + .split(',') // splits them at "," + .filter((string, index) => !forceRemoveAlpha || index !== 3) + .map(string => parseFloat(string)) // Converts them to numbers + .map((number, index) => (index === 3 ? Math.round(number * 255) : number)) // Converts alpha to 255 number + .map(number => number.toString(16)) // Converts numbers to hex + .map(string => (string.length === 1 ? '0' + string : string)) // Adds 0 when length of one number is 1 + .join('') + ) + } +} diff --git a/front-urban/src/views/NotFound.tsx b/front-urban/src/views/NotFound.tsx new file mode 100644 index 0000000..efb6b08 --- /dev/null +++ b/front-urban/src/views/NotFound.tsx @@ -0,0 +1,51 @@ +'use client' + +// Next Imports +import Link from 'next/link' + +// MUI Imports +import Button from '@mui/material/Button' +import Typography from '@mui/material/Typography' + +// Type Imports +import type { Mode } from '@core/types' + +// Component Imports +import Illustrations from '@components/Illustrations' + +// Hook Imports +import { useImageVariant } from '@core/hooks/useImageVariant' + +const NotFound = ({ mode }: { mode: Mode }) => { + // Vars + const darkImg = '/images/pages/misc-mask-dark.png' + const lightImg = '/images/pages/misc-mask-light.png' + + // Hooks + const miscBackground = useImageVariant(mode, lightImg, darkImg) + + return ( +
+
+
+ + 404 + + Page Not Found ⚠️ + We couldn't find the page you are looking for. +
+ error-illustration + +
+ +
+ ) +} + +export default NotFound diff --git a/front-urban/src/views/account-settings/account/AccountDelete.tsx b/front-urban/src/views/account-settings/account/AccountDelete.tsx new file mode 100644 index 0000000..e1f5005 --- /dev/null +++ b/front-urban/src/views/account-settings/account/AccountDelete.tsx @@ -0,0 +1,23 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import FormControlLabel from '@mui/material/FormControlLabel' +import Checkbox from '@mui/material/Checkbox' +import Button from '@mui/material/Button' + +const AccountDelete = () => { + return ( + + + + } label='I confirm my account deactivation' /> + + + + ) +} + +export default AccountDelete diff --git a/front-urban/src/views/account-settings/account/AccountDetails.tsx b/front-urban/src/views/account-settings/account/AccountDetails.tsx new file mode 100644 index 0000000..bf5be8b --- /dev/null +++ b/front-urban/src/views/account-settings/account/AccountDetails.tsx @@ -0,0 +1,301 @@ +'use client' + +// React Imports +import { useState } from 'react' +import type { ChangeEvent } from 'react' + +// MUI Imports +import Grid from '@mui/material/Grid' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Button from '@mui/material/Button' +import Typography from '@mui/material/Typography' +import TextField from '@mui/material/TextField' +import FormControl from '@mui/material/FormControl' +import InputLabel from '@mui/material/InputLabel' +import Select from '@mui/material/Select' +import MenuItem from '@mui/material/MenuItem' +import Chip from '@mui/material/Chip' +import type { SelectChangeEvent } from '@mui/material/Select' + +type Data = { + firstName: string + lastName: string + email: string + organization: string + phoneNumber: number | string + address: string + state: string + zipCode: string + country: string + language: string + timezone: string + currency: string +} + +// Vars +const initialData: Data = { + firstName: 'John', + lastName: 'Doe', + email: 'john.doe@example.com', + organization: 'ThemeSelection', + phoneNumber: '+1 (917) 543-9876', + address: '123 Main St, New York, NY 10001', + state: 'New York', + zipCode: '634880', + country: 'usa', + language: 'arabic', + timezone: 'gmt-12', + currency: 'usd' +} + +const languageData = ['English', 'Arabic', 'French', 'German', 'Portuguese'] + +const AccountDetails = () => { + // States + const [formData, setFormData] = useState(initialData) + const [fileInput, setFileInput] = useState('') + const [imgSrc, setImgSrc] = useState('/images/avatars/1.png') + const [language, setLanguage] = useState(['English']) + + const handleDelete = (value: string) => { + setLanguage(current => current.filter(item => item !== value)) + } + + const handleChange = (event: SelectChangeEvent) => { + setLanguage(event.target.value as string[]) + } + + const handleFormChange = (field: keyof Data, value: Data[keyof Data]) => { + setFormData({ ...formData, [field]: value }) + } + + const handleFileInputChange = (file: ChangeEvent) => { + const reader = new FileReader() + const { files } = file.target as HTMLInputElement + + if (files && files.length !== 0) { + reader.onload = () => setImgSrc(reader.result as string) + reader.readAsDataURL(files[0]) + + if (reader.result !== null) { + setFileInput(reader.result as string) + } + } + } + + const handleFileInputReset = () => { + setFileInput('') + setImgSrc('/images/avatars/1.png') + } + + return ( + + +
+ Profile +
+
+ + +
+ Allowed JPG, GIF or PNG. Max size of 800K +
+
+
+ + e.preventDefault()}> + + + handleFormChange('firstName', e.target.value)} + /> + + + handleFormChange('lastName', e.target.value)} + /> + + + handleFormChange('email', e.target.value)} + /> + + + handleFormChange('organization', e.target.value)} + /> + + + handleFormChange('phoneNumber', e.target.value)} + /> + + + handleFormChange('address', e.target.value)} + /> + + + handleFormChange('state', e.target.value)} + /> + + + handleFormChange('zipCode', e.target.value)} + /> + + + + Country + + + + + + Language + + + + + + TimeZone + + + + + + Currency + + + + + + + + + + +
+ ) +} + +export default AccountDetails diff --git a/front-urban/src/views/account-settings/account/index.tsx b/front-urban/src/views/account-settings/account/index.tsx new file mode 100644 index 0000000..6590f24 --- /dev/null +++ b/front-urban/src/views/account-settings/account/index.tsx @@ -0,0 +1,21 @@ +// MUI Imports +import Grid from '@mui/material/Grid' + +// Component Imports +import AccountDetails from './AccountDetails' +import AccountDelete from './AccountDelete' + +const Account = () => { + return ( + + + + + + + + + ) +} + +export default Account diff --git a/front-urban/src/views/account-settings/connections/index.tsx b/front-urban/src/views/account-settings/connections/index.tsx new file mode 100644 index 0000000..a5d459b --- /dev/null +++ b/front-urban/src/views/account-settings/connections/index.tsx @@ -0,0 +1,154 @@ +// Next Imports +import Link from 'next/link' + +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Grid from '@mui/material/Grid' +import Typography from '@mui/material/Typography' +import Switch from '@mui/material/Switch' + +// Component Imports +import CustomIconButton from '@core/components/mui/IconButton' + +type ConnectedAccountsType = { + title: string + logo: string + checked: boolean + subtitle: string +} + +type SocialAccountsType = { + title: string + logo: string + username?: string + isConnected: boolean + href?: string +} + +// Vars +const connectedAccountsArr: ConnectedAccountsType[] = [ + { + checked: true, + title: 'Google', + logo: '/images/logos/google.png', + subtitle: 'Calendar and Contacts' + }, + { + checked: false, + title: 'Slack', + logo: '/images/logos/slack.png', + subtitle: 'Communications' + }, + { + checked: true, + title: 'Github', + logo: '/images/logos/github.png', + subtitle: 'Manage your Git repositories' + }, + { + checked: true, + title: 'Mailchimp', + subtitle: 'Email marketing service', + logo: '/images/logos/mailchimp.png' + }, + { + title: 'Asana', + checked: false, + subtitle: 'Task Communication', + logo: '/images/logos/asana.png' + } +] + +const socialAccountsArr: SocialAccountsType[] = [ + { + title: 'Facebook', + isConnected: false, + logo: '/images/logos/facebook.png' + }, + { + title: 'Twitter', + isConnected: true, + username: '@Theme_Selection', + logo: '/images/logos/twitter.png', + href: 'https://twitter.com/Theme_Selection' + }, + { + title: 'Linkedin', + isConnected: true, + username: '@ThemeSelection', + logo: '/images/logos/linkedin.png', + href: 'https://in.linkedin.com/company/themeselection' + }, + { + title: 'Dribbble', + isConnected: false, + logo: '/images/logos/dribbble.png' + }, + { + title: 'Behance', + isConnected: false, + logo: '/images/logos/behance.png' + } +] + +const Connections = () => { + return ( + + + + + + {connectedAccountsArr.map((item, index) => ( +
+
+ {item.title} +
+ + {item.title} + + {item.subtitle} +
+
+ +
+ ))} +
+
+ + + + {socialAccountsArr.map((item, index) => ( +
+
+ {item.title} +
+ + {item.title} + + {item.isConnected ? ( + + {item.username} + + ) : ( + Not Connected + )} +
+
+ + + +
+ ))} +
+
+
+
+ ) +} + +export default Connections diff --git a/front-urban/src/views/account-settings/index.tsx b/front-urban/src/views/account-settings/index.tsx new file mode 100644 index 0000000..4181f9f --- /dev/null +++ b/front-urban/src/views/account-settings/index.tsx @@ -0,0 +1,47 @@ +'use client' + +// React Imports +import { useState } from 'react' +import type { SyntheticEvent, ReactElement } from 'react' + +// MUI Imports +import Grid from '@mui/material/Grid' +import Tab from '@mui/material/Tab' +import TabContext from '@mui/lab/TabContext' +import TabList from '@mui/lab/TabList' +import TabPanel from '@mui/lab/TabPanel' + +const AccountSettings = ({ tabContentList }: { tabContentList: { [key: string]: ReactElement } }) => { + // States + const [activeTab, setActiveTab] = useState('account') + + const handleChange = (event: SyntheticEvent, value: string) => { + setActiveTab(value) + } + + return ( + + + + + } iconPosition='start' value='account' /> + } + iconPosition='start' + value='notifications' + /> + } iconPosition='start' value='connections' /> + + + + + {tabContentList[activeTab]} + + + + + ) +} + +export default AccountSettings diff --git a/front-urban/src/views/account-settings/notifications/index.tsx b/front-urban/src/views/account-settings/notifications/index.tsx new file mode 100644 index 0000000..fab1fa0 --- /dev/null +++ b/front-urban/src/views/account-settings/notifications/index.tsx @@ -0,0 +1,121 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Checkbox from '@mui/material/Checkbox' +import Select from '@mui/material/Select' +import MenuItem from '@mui/material/MenuItem' +import Grid from '@mui/material/Grid' +import Button from '@mui/material/Button' + +// Component Imports +import Link from '@components/Link' +import Form from '@components/Form' + +// Style Imports +import tableStyles from '@core/styles/table.module.css' + +type TableDataType = { + type: string + app: boolean + email: boolean + browser: boolean +} + +// Vars +const tableData: TableDataType[] = [ + { + app: true, + email: true, + browser: true, + type: 'New for you' + }, + { + app: true, + email: true, + browser: true, + type: 'Account activity' + }, + { + app: false, + email: true, + browser: true, + type: 'A new browser used to sign in' + }, + { + app: false, + email: true, + browser: false, + type: 'A new device is linked' + } +] + +const Notifications = () => { + return ( + + + We need permission from your browser to show notifications. + Request Permission + + } + /> +
+
+ + + + + + + + + + + {tableData.map((data, index) => ( + + + + + + + ))} + +
TypeEmailBrowserApp
+ {data.type} + + + + + + +
+
+ + When should we send you notifications? + + + + + + + + + + +
+
+ ) +} + +export default Notifications diff --git a/front-urban/src/views/card-basic/CardFacebook.tsx b/front-urban/src/views/card-basic/CardFacebook.tsx new file mode 100644 index 0000000..8108170 --- /dev/null +++ b/front-urban/src/views/card-basic/CardFacebook.tsx @@ -0,0 +1,42 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Avatar from '@mui/material/Avatar' + +const CardFacebook = () => { + return ( + + +
+ + + Facebook Card + +
+ + You've read about the importance of being courageous, rebellious and imaginative. These are all vital + ingredients in an effective. + +
+
+ + Eugene Clarke +
+
+ + + 2.5k + + + + 124 + +
+
+
+
+ ) +} + +export default CardFacebook diff --git a/front-urban/src/views/card-basic/CardHorizontalRatings.tsx b/front-urban/src/views/card-basic/CardHorizontalRatings.tsx new file mode 100644 index 0000000..dec4165 --- /dev/null +++ b/front-urban/src/views/card-basic/CardHorizontalRatings.tsx @@ -0,0 +1,45 @@ +'use client' + +// MUI Imports +import Card from '@mui/material/Card' +import Grid from '@mui/material/Grid' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Rating from '@mui/material/Rating' +import CardActions from '@mui/material/CardActions' +import Button from '@mui/material/Button' + +const CardHorizontalRatings = () => { + return ( + + + + + + Stumptown Roasters + +
+ + 4 Star | 98 reviews +
+ + Before there was a United States of America, there were coffee houses, because how are you supposed to + build. + +
+ + + + +
+ + + + + +
+
+ ) +} + +export default CardHorizontalRatings diff --git a/front-urban/src/views/card-basic/CardInfluencingInfluencer.tsx b/front-urban/src/views/card-basic/CardInfluencingInfluencer.tsx new file mode 100644 index 0000000..9981bab --- /dev/null +++ b/front-urban/src/views/card-basic/CardInfluencingInfluencer.tsx @@ -0,0 +1,32 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import CardActions from '@mui/material/CardActions' +import Button from '@mui/material/Button' + +const CardInfluencingInfluencer = () => { + return ( + + + + Influencing Influencer + + + Computers have become ubiquitous in almost every facet of our lives. At work, desk jockeys spend hours in + front of their desktops, while delivery people scan bar codes with handhelds and workers in the field stay in + touch. + + + If you're in the market for new desktops, notebooks, or PDAs, there are a myriad of choices. Here's a + rundown of some of the best systems available. + + + + + + + ) +} + +export default CardInfluencingInfluencer diff --git a/front-urban/src/views/card-basic/CardInfluencingInfluencerWithImg.tsx b/front-urban/src/views/card-basic/CardInfluencingInfluencerWithImg.tsx new file mode 100644 index 0000000..e6f84ff --- /dev/null +++ b/front-urban/src/views/card-basic/CardInfluencingInfluencerWithImg.tsx @@ -0,0 +1,24 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardMedia from '@mui/material/CardMedia' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' + +const CardInfluencingInfluencerWithImg = () => { + return ( + + + + + Influencing The Influencer + + + Cancun is back, better than ever! Over a hundred Mexico resorts have reopened and the state tourism minister + predicts Cancun will draw as many visitors in 2006 as it did two years ago. + + + + ) +} + +export default CardInfluencingInfluencerWithImg diff --git a/front-urban/src/views/card-basic/CardLifetimeMembership.tsx b/front-urban/src/views/card-basic/CardLifetimeMembership.tsx new file mode 100644 index 0000000..312d607 --- /dev/null +++ b/front-urban/src/views/card-basic/CardLifetimeMembership.tsx @@ -0,0 +1,80 @@ +// MUI Imports +import Card from '@mui/material/Card' +import Grid from '@mui/material/Grid' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Divider from '@mui/material/Divider' +import Button from '@mui/material/Button' + +const CardLifetimeMembership = () => { + return ( + + + + + + Lifetime Membership + + + Here, I focus on a range of items and features that we use in life without giving them a second thought + such as Coca Cola, body muscles and holding ones own breath. Though, most of these notes are not + fundamentally necessary, they are such that you can use them for a good laugh, at a drinks party or for + picking up women or men. + + + + +
+
+ +
+ Full Access +
+
+
+ +
+ 15 Members +
+
+ +
+
+ +
+ Access all Features +
+
+
+ +
+ Lifetime Free Update +
+
+
+
+
+ + +
+
+ $ + 899 + USD +
+ + 5 Tips For Offshore + Software Development + + +
+
+
+
+
+ ) +} + +export default CardLifetimeMembership diff --git a/front-urban/src/views/card-basic/CardLinkedIn.tsx b/front-urban/src/views/card-basic/CardLinkedIn.tsx new file mode 100644 index 0000000..45fe70b --- /dev/null +++ b/front-urban/src/views/card-basic/CardLinkedIn.tsx @@ -0,0 +1,42 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Avatar from '@mui/material/Avatar' + +const CardLinkedIn = () => { + return ( + + +
+ + + LinkedIn Card + +
+ + With the Internet spreading like wildfire and reaching every part of our daily life, more and more traffic is + directed. + +
+
+ + Anne Burke +
+
+ + + 1.2k + + + + 56 + +
+
+
+
+ ) +} + +export default CardLinkedIn diff --git a/front-urban/src/views/card-basic/CardMobile.tsx b/front-urban/src/views/card-basic/CardMobile.tsx new file mode 100644 index 0000000..b8ea5d0 --- /dev/null +++ b/front-urban/src/views/card-basic/CardMobile.tsx @@ -0,0 +1,91 @@ +'use client' + +// React Imports +import { useState } from 'react' +import type { MouseEvent } from 'react' + +// MUI Imports +import Card from '@mui/material/Card' +import Grid from '@mui/material/Grid' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import CardActions from '@mui/material/CardActions' +import Button from '@mui/material/Button' +import IconButton from '@mui/material/IconButton' +import Menu from '@mui/material/Menu' +import MenuItem from '@mui/material/MenuItem' + +const CardMobile = () => { + // States + const [anchorEl, setAnchorEl] = useState(null) + + const open = Boolean(anchorEl) + + const handleClick = (event: MouseEvent) => { + setAnchorEl(event.currentTarget) + } + + const handleClose = () => { + setAnchorEl(null) + } + + return ( + + + + + iPhone 11 Pro + + + + + + Apple iPhone 11 Pro + + + Apple iPhone 11 Pro smartphone. Announced Sep 2019. Features 5.8″ display Apple A13 Bionic + +
+ Price: + + $899 + +
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+ ) +} + +export default CardMobile diff --git a/front-urban/src/views/card-basic/CardSupport.tsx b/front-urban/src/views/card-basic/CardSupport.tsx new file mode 100644 index 0000000..72196e7 --- /dev/null +++ b/front-urban/src/views/card-basic/CardSupport.tsx @@ -0,0 +1,28 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Avatar from '@mui/material/Avatar' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' + +const CardSupport = () => { + return ( + + + + + + + Support + + + According to us blisters are a very common thing and we come across them very often in our daily lives. It is + a very common occurrence like cold or fever depending upon your lifestyle. + + + + + ) +} + +export default CardSupport diff --git a/front-urban/src/views/card-basic/CardTwitter.tsx b/front-urban/src/views/card-basic/CardTwitter.tsx new file mode 100644 index 0000000..7643843 --- /dev/null +++ b/front-urban/src/views/card-basic/CardTwitter.tsx @@ -0,0 +1,42 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Avatar from '@mui/material/Avatar' + +const CardTwitter = () => { + return ( + + +
+ + + Twitter Card + +
+ + Turns out semicolon-less style is easier and safer in TS because most gotcha edge cases are type invalid as + well. + +
+
+ + Mary Vaughn +
+
+ + + 1.6k + + + + 98 + +
+
+
+
+ ) +} + +export default CardTwitter diff --git a/front-urban/src/views/card-basic/CardUser.tsx b/front-urban/src/views/card-basic/CardUser.tsx new file mode 100644 index 0000000..e402f6a --- /dev/null +++ b/front-urban/src/views/card-basic/CardUser.tsx @@ -0,0 +1,45 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardMedia from '@mui/material/CardMedia' +import CardContent from '@mui/material/CardContent' +import Avatar from '@mui/material/Avatar' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' +import AvatarGroup from '@mui/material/AvatarGroup' + +const CardUser = () => { + return ( + + + + +
+
+ Robert Meyer + London, UK +
+ +
+
+ + 18 mutual friends + + + + + + + + + +
+
+
+ ) +} + +export default CardUser diff --git a/front-urban/src/views/card-basic/CardVerticalRatings.tsx b/front-urban/src/views/card-basic/CardVerticalRatings.tsx new file mode 100644 index 0000000..a80478a --- /dev/null +++ b/front-urban/src/views/card-basic/CardVerticalRatings.tsx @@ -0,0 +1,37 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Rating from '@mui/material/Rating' +import CardActions from '@mui/material/CardActions' +import Button from '@mui/material/Button' + +const CardVerticalRatings = () => { + return ( + + + + The Best Answers + +
+ + 4 Star | 98 reviews +
+ + If you are looking for a new way to promote your business that won't cost you more money, maybe printing + is one of the options you won't resist. + + + Printing is a widely use process in making printed materials that are used for advertising. It become fast, + easy and simple. + +
+ + + + +
+ ) +} + +export default CardVerticalRatings diff --git a/front-urban/src/views/card-basic/CardWatch.tsx b/front-urban/src/views/card-basic/CardWatch.tsx new file mode 100644 index 0000000..2d2c24d --- /dev/null +++ b/front-urban/src/views/card-basic/CardWatch.tsx @@ -0,0 +1,26 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardMedia from '@mui/material/CardMedia' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' + +const CardWatch = () => { + return ( + + + + + Apple Watch + + $249.40 + 3.1GHz 6-core 10th-generation Intel Core i5 processor, Turbo Boost up to 4.5GHz + + + + ) +} + +export default CardWatch diff --git a/front-urban/src/views/card-basic/CardWithCollapse.tsx b/front-urban/src/views/card-basic/CardWithCollapse.tsx new file mode 100644 index 0000000..2ef6ba5 --- /dev/null +++ b/front-urban/src/views/card-basic/CardWithCollapse.tsx @@ -0,0 +1,50 @@ +'use client' + +// React Imports +import { useState } from 'react' + +// MUI Imports +import Card from '@mui/material/Card' +import CardMedia from '@mui/material/CardMedia' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import CardActions from '@mui/material/CardActions' +import Button from '@mui/material/Button' +import IconButton from '@mui/material/IconButton' +import Collapse from '@mui/material/Collapse' +import Divider from '@mui/material/Divider' + +const CardWithCollapse = () => { + const [expanded, setExpanded] = useState(false) + + return ( + + + + + Popular Uses Of The Internet + + Although cards can support multiple actions, UI controls, and an overflow menu. + + + + setExpanded(!expanded)}> + + + + + + + + I'm a thing. But, like most politicians, he promised more than he could deliver. You won't have time + for sleeping, soldier, not with all the bed making you'll be doing. Then we'll go with that data + file! Hey, you add a one and two zeros to that or we walk! You're going to do his laundry? I've got + to find a way to escape. + + + + + ) +} + +export default CardWithCollapse diff --git a/front-urban/src/views/card-basic/CardWithTabs.tsx b/front-urban/src/views/card-basic/CardWithTabs.tsx new file mode 100644 index 0000000..0c74e9f --- /dev/null +++ b/front-urban/src/views/card-basic/CardWithTabs.tsx @@ -0,0 +1,70 @@ +'use client' + +// React Imports +import { useState } from 'react' +import type { SyntheticEvent } from 'react' + +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import TabContext from '@mui/lab/TabContext' +import TabList from '@mui/lab/TabList' +import Tab from '@mui/material/Tab' +import TabPanel from '@mui/lab/TabPanel' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' + +const CardWithTabs = () => { + // ** State + const [value, setValue] = useState('1') + + const handleChange = (event: SyntheticEvent, newValue: string) => { + setValue(newValue) + } + + return ( + + + + + + + + + + + Header One + + + Pudding tiramisu caramels. Gingerbread gummies danish chocolate bar toffee marzipan. Wafer wafer cake + powder danish oat cake. + + + + + + Header Two + + + Dragée chupa chups soufflé cheesecake jelly tootsie roll cupcake marzipan. Carrot cake sweet roll gummi + bears caramels jelly beans. + + + + + + Header Three + + + Icing cake macaroon macaroon jelly chocolate bar. Chupa chups dessert dessert soufflé chocolate bar + jujubes gummi bears lollipop. + + + + + + + ) +} + +export default CardWithTabs diff --git a/front-urban/src/views/card-basic/CardWithTabsCenter.tsx b/front-urban/src/views/card-basic/CardWithTabsCenter.tsx new file mode 100644 index 0000000..0e1cfc0 --- /dev/null +++ b/front-urban/src/views/card-basic/CardWithTabsCenter.tsx @@ -0,0 +1,70 @@ +'use client' + +// React Imports +import { useState } from 'react' +import type { SyntheticEvent } from 'react' + +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import TabContext from '@mui/lab/TabContext' +import TabList from '@mui/lab/TabList' +import Tab from '@mui/material/Tab' +import TabPanel from '@mui/lab/TabPanel' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' + +const CardWithTabsCenter = () => { + // ** State + const [value, setValue] = useState('1') + + const handleChange = (event: SyntheticEvent, newValue: string) => { + setValue(newValue) + } + + return ( + + + + + + + + + + + Header One + + + Pudding tiramisu caramels. Gingerbread gummies danish chocolate bar toffee marzipan. Wafer wafer cake + powder danish oat cake. + + + + + + Header Two + + + Dragée chupa chups soufflé cheesecake jelly tootsie roll cupcake marzipan. Carrot cake sweet roll gummi + bears caramels jelly beans. + + + + + + Header Three + + + Icing cake macaroon macaroon jelly chocolate bar. Chupa chups dessert dessert soufflé chocolate bar + jujubes gummi bears lollipop. + + + + + + + ) +} + +export default CardWithTabsCenter diff --git a/front-urban/src/views/clases/AlertNoEditClase.tsx b/front-urban/src/views/clases/AlertNoEditClase.tsx new file mode 100644 index 0000000..2bad065 --- /dev/null +++ b/front-urban/src/views/clases/AlertNoEditClase.tsx @@ -0,0 +1,213 @@ +'use client'; + +import React, { useMemo, useState } from 'react'; +import { + Alert, + AlertTitle, + Button, + Stack, + Typography, + Dialog, + DialogTitle, + DialogContent, + DialogActions, +} from '@mui/material'; +import dayjs from 'dayjs'; +import 'dayjs/locale/es'; +import axios from 'axios'; +import CustomDialog from '@/utils/CustomDialog'; +import { DeactivateDialog } from './DesactivateDialog'; +dayjs.locale('es'); + +/** ===== Tipos ===== */ +export type Clase = { + id: string; + type: 'ONE_TIME' | 'RECURRING'; + description?: string; + startDate?: string; + endDate?: string; + instructors?: Array<{ id: string; name: string }>; + SessionDateSnapshot?: Array<{ + dateRange?: { start?: string; end?: string }; + }>; +}; + +/** ===== Utils de formato ===== */ +const fmtD = (iso?: string | null) => + iso && dayjs(iso).isValid() ? dayjs(iso).format('DD/MM/YYYY') : '—'; + +const fmtT = (iso?: string | null) => + iso && dayjs(iso).isValid() ? dayjs(iso).format('HH:mm') : '—'; + +/** ===== Reglas de bloqueo ===== + * ONE_TIME: bloquear SOLO si TODAS las ocurrencias ya comenzaron (start < now) + * RECURRING: bloquear si TODAS las ocurrencias conocidas ya comenzaron (o el inicio global ya pasó sin snaps) + */ +function computeEditLockReason(clase?: Clase): string | null { + if (!clase) return null; + const now = dayjs(); + const snaps = clase.SessionDateSnapshot ?? []; + + const getStart = (s?: { dateRange?: { start?: string } }) => + dayjs(s?.dateRange?.start ?? null); + + if (clase.type === 'ONE_TIME') { + if (snaps.length > 0) { + const allStarted = snaps.every((s) => { + const st = getStart(s); + return st.isValid() && st.isBefore(now); + }); + if (allStarted) { + return 'Esta clase puntual ya comenzó (todas sus ocurrencias) y no se puede editar. Solo puedes darla de baja.'; + } + return null; + } else { + if (clase.startDate && dayjs(clase.startDate).isBefore(now)) { + return 'Esta clase puntual ya comenzó y no se puede editar. Solo puedes darla de baja.'; + } + return null; + } + } + + // RECURRING + if (snaps.length > 0) { + const allStarted = snaps.every((s) => { + const st = getStart(s); + return st.isValid() && st.isBefore(now); + }); + if (allStarted) { + return 'Todas las ocurrencias de esta clase recurrente ya comenzaron. Solo puedes darla de baja.'; + } + } else { + if (clase.startDate && dayjs(clase.startDate).isBefore(now)) { + return 'El rango de esta clase ya comenzó. Solo puedes darla de baja.'; + } + } + + return null; +} + +/** 🔹 Export util: saber si está bloqueada */ +export function isClaseEditLocked(clase?: Clase) { + return !!computeEditLockReason(clase); +} + +/** ===== Rango de fechas (snapshots) con fallback ===== */ +function computeDateRange(clase?: Clase) { + if (!clase) return { from: '—', to: '—' }; + const snaps = clase.SessionDateSnapshot ?? []; + if (snaps.length > 0) { + const starts = snaps.map((s) => s.dateRange?.start).filter(Boolean) as string[]; + const ends = snaps.map((s) => s.dateRange?.end).filter(Boolean) as string[]; + if (starts.length && ends.length) { + const minStart = starts.reduce((a, b) => (dayjs(a).isBefore(b) ? a : b)); + const maxEnd = ends.reduce((a, b) => (dayjs(a).isAfter(b) ? a : b)); + return { from: fmtD(minStart), to: fmtD(maxEnd) }; + } + } + return { from: fmtD(clase.startDate), to: fmtD(clase.endDate) }; +} + +/** ===== Rango de horarios (snapshots) con fallback ===== */ +function computeTimeRange(clase?: Clase) { + if (!clase) return { from: '—', to: '—' }; + const snaps = clase.SessionDateSnapshot ?? []; + if (snaps.length > 0) { + const startTimes = snaps.map((s) => s.dateRange?.start).filter(Boolean) as string[]; + const endTimes = snaps.map((s) => s.dateRange?.end).filter(Boolean) as string[]; + + if (startTimes.length && endTimes.length) { + const minStart = startTimes + .map((x) => dayjs(x)) + .filter((d) => d.isValid()) + .sort((a, b) => a.valueOf() - b.valueOf())[0]; + const maxEnd = endTimes + .map((x) => dayjs(x)) + .filter((d) => d.isValid()) + .sort((a, b) => b.valueOf() - a.valueOf())[0]; + return { from: fmtT(minStart?.toISOString()), to: fmtT(maxEnd?.toISOString()) }; + } + } + return { from: fmtT(clase.startDate), to: fmtT(clase.endDate) }; +} + + + + +/** ===== Alert principal (default) ===== */ +type AlertNoEditProps = { + clase?: Clase; + hideDeactivateButton?: boolean; + token?: string; + onDeactivated?: () => void; +}; + +const AlertNoEditClase: React.FC = ({ + clase, + hideDeactivateButton, + token, + onDeactivated, +}) => { + const reason = useMemo(() => computeEditLockReason(clase), [clase]); + const dateRange = useMemo(() => computeDateRange(clase), [clase]); + const timeRange = useMemo(() => computeTimeRange(clase), [clase]); + const profesores = + (clase?.instructors ?? []).map((i) => i.name).join(', ') || '—'; + + const [openConfirm, setOpenConfirm] = useState(false); + + if (!reason) return null; + + const canOpenDialog = !!(clase?.id); + + return ( + <> + + No se puede editar + {reason} + + {/* Mini ficha descriptiva */} + + + Descripción: {clase?.description || '—'} + + + Profesor: {profesores} + + + Rango de fechas: {dateRange.from} — {dateRange.to} + + + Rango de horarios: {timeRange.from} — {timeRange.to} + + + + {!hideDeactivateButton && ( + + + + )} + + + {/* Diálogo reutilizable con lógica interna */} + {clase?.id && ( + setOpenConfirm(false)} + modelId={clase.id} + model='session' + claseDescription={clase.description} + onSuccess={onDeactivated} + /> + )} + + ); +}; + +export default AlertNoEditClase; diff --git a/front-urban/src/views/clases/AsignarParticiapntesAccordion.tsx b/front-urban/src/views/clases/AsignarParticiapntesAccordion.tsx new file mode 100644 index 0000000..cbcc0c4 --- /dev/null +++ b/front-urban/src/views/clases/AsignarParticiapntesAccordion.tsx @@ -0,0 +1,272 @@ +'use client' + +import ExpandMoreIcon from '@mui/icons-material/ExpandMore' +import { + Accordion, + AccordionDetails, + AccordionSummary, + Button, + IconButton, + List, + ListItem, + ListItemText, + Typography, +} from '@mui/material' +import ArrowBackIcon from '@mui/icons-material/ArrowBack' +import ArrowForwardIcon from '@mui/icons-material/ArrowForward' +import ClearIcon from '@mui/icons-material/Clear' +import { + Grid, + InputAdornment, + Paper, + TextField, + Tooltip +} from '@mui/material' +import { useEffect, useMemo, useState } from 'react' +import { useUserAuth } from '@/app/context/UserAuth' +import apiClient from '@/lib/apiClient' + +type UserSession = { id: string; customId: string; name: string; role: string } + +type ResponseGetParticipants = { selected: UserSession[]; available: UserSession[] } + +type Props = { + clase: any +} + +const AsignarParticiapntesAccordion = ({ clase }: Props) => { + const { token } = useUserAuth() + + const [selectedParticipants, setSelectedParticipants] = useState([]) + const [availableParticipants, setAvailableParticipants] = useState([]) + const [qSelected, setQSelected] = useState('') + const [qAvailable, setQAvailable] = useState('') + const [saving, setSaving] = useState(false) + + + const filteredSelected = useMemo( + () => selectedParticipants.filter(u => u.name.toLowerCase().includes(qSelected.toLowerCase())), + [selectedParticipants, qSelected] + ) + const filteredAvailable = useMemo( + () => availableParticipants.filter(u => u.name.toLowerCase().includes(qAvailable.toLowerCase())), + [availableParticipants, qAvailable] + ) + + const handleAddParticipant = (user: UserSession) => { + setAvailableParticipants(prev => prev.filter(p => (p.customId || p.id) !== (user.customId || user.id))) + setSelectedParticipants(prev => + prev.some(p => (p.customId || p.id) === (user.customId || user.id)) ? prev : [...prev, user] + ) + } + + const handleRemoveParticipant = (user: UserSession) => { + setSelectedParticipants(prev => prev.filter(p => (p.customId || p.id) !== (user.customId || user.id))) + setAvailableParticipants(prev => + prev.some(p => (p.customId || p.id) === (user.customId || user.id)) ? prev : [...prev, user] + ) + } + + const handleUpdateParticipants = async () => { + if (!clase?.id || !token) return + setSaving(true) + try { + await apiClient.put( + `/sessions/${clase.id}/participants`, + { userIds: selectedParticipants.map(u => u.id) } + ) + } catch { + } finally { + setSaving(false) + } + } + + + useEffect(() => { + if (!open || !clase?.id || !token) return + const controller = new AbortController() + ; (async () => { + const response = await apiClient.get( + `/sessions/${clase.id}/participants`, + { signal: controller.signal } + ) + setSelectedParticipants(response.data.selected || []) + setAvailableParticipants(response.data.available || []) + })().catch(() => { }) + return () => controller.abort() + }, [open, clase?.id, token]) + + return ( + + }> + Asignar participantes + + + + {/* SELECCIONADOS */} + + Seleccionados + + setQSelected(e.target.value)} + fullWidth + variant="filled" + InputLabelProps={{ shrink: true }} + InputProps={{ + endAdornment: qSelected ? ( + + setQSelected('')} aria-label="Limpiar búsqueda"> + + + + ) : undefined, + }} + sx={{ + mb: 1.5, + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + {filteredSelected.map((user, idx) => ( + + handleRemoveParticipant(user)}> + + + + } + > + + + ))} + + + + + {/* FLECHA CENTRAL */} + + + + + {/* DISPONIBLES */} + + Disponibles + + setQAvailable(e.target.value)} + fullWidth + variant="filled" + InputLabelProps={{ shrink: true }} + InputProps={{ + endAdornment: qAvailable ? ( + + setQAvailable('')} aria-label="Limpiar búsqueda"> + + + + ) : undefined, + }} + sx={{ + mb: 1.5, + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + {filteredAvailable.map((user, idx) => ( + + handleAddParticipant(user)}> + + + + } + > + + + ))} + + + + + + + + ) +} + +export default AsignarParticiapntesAccordion diff --git a/front-urban/src/views/clases/DesactivateDialog.tsx b/front-urban/src/views/clases/DesactivateDialog.tsx new file mode 100644 index 0000000..91d6725 --- /dev/null +++ b/front-urban/src/views/clases/DesactivateDialog.tsx @@ -0,0 +1,88 @@ +import CustomDialog from "@/utils/CustomDialog"; +import { Button, Typography } from "@mui/material"; +import apiClient from "@/lib/apiClient"; +import React from "react"; + +export type DeactivateDialogProps = { + open: boolean; + onClose: () => void; + modelId: string; + model: 'session' | 'snapshot'; + claseDescription?: React.ReactNode; + onSuccess?: () => void; +}; + +export const DeactivateDialog: React.FC = ({ + open, + modelId, + model, + claseDescription, + onClose, + onSuccess, +}) => { + + const [loading, setLoading] = React.useState(false); + const [err, setErr] = React.useState(null); + + const handleConfirm = async () => { + setErr(null); + try { + setLoading(true); + await apiClient.post( + '/sessions/deactivate', + { modelId, model } + ); + onSuccess?.(); + onClose(); + } catch (e: any) { + console.error(e); + setErr(e?.response?.data?.message || 'No se pudo dar de baja.'); + } finally { + setLoading(false); + } + }; + + const handleClose = () => { + if (loading) return; + onClose(); + }; + + return ( + + + + + } + > + + ¿Confirmás que querés dar de baja?{' '} + {claseDescription || 'esta clase'} + + + Esta acción la marcará como no disponible. + + + {err && ( + + {err} + + )} + + ); +}; diff --git a/front-urban/src/views/clases/DetailClaseDialog.tsx b/front-urban/src/views/clases/DetailClaseDialog.tsx new file mode 100644 index 0000000..ee2aa2b --- /dev/null +++ b/front-urban/src/views/clases/DetailClaseDialog.tsx @@ -0,0 +1,240 @@ +'use client' + +import dayjs from 'dayjs' +import { + alpha, + Box, + Button, + Chip, + Divider, + Stack, + Typography +} from '@mui/material' +import CustomDialog from '@/utils/CustomDialog' +import { DIALOG_INFO } from '@/configs/dialogInfoContent' +import AsignarParticiapntesAccordion from './AsignarParticiapntesAccordion' +import FechasProgramadasAccordion from './FechasProgramadasAccordion' +import FacturasAsistentesAccordion from './FacturasAsistentesAccordion' + +type SessionType = 'RECURRING' | 'ONE_TIME' + +export type Clase = { + id: string + customId: string + description: string + type: SessionType + startDate: string + endDate: string + isActive: boolean + instructorId: string | null + amount: number | null + createdAt: string + updatedAt: string + instructors: { + id: string + customId: string + createdAt: string + name: string + dni: string | null + phone: string | null + birth: string | null + rfid: string | null + deleted: string | null + role: 'ADMIN' | 'INSTRUCTOR' | 'STUDENT' + }[] + SessionDateSnapshot: { + id: string + createdAt: string + notes: string | null + sessionId: string + dateRangeId: string + isActive: boolean + dateRange: { + id: string + start: string + end: string + sessionId: string + } + substituteInstructors: { + id: string + name: string + dni: string + }[] + }[] +} + +type Props = { open: boolean; onClose: () => void; clase: Clase | null; onDeactivateSuccess?: () => void } + +const DetailClaseDialog = ({ open, onClose, clase, onDeactivateSuccess }: Props) => { + if (!clase) return null + + const isRecurrente = clase.type === 'RECURRING' + const fmt = (iso?: string) => (iso ? dayjs(iso).format('DD/MM/YYYY') : '—') + const currency = + typeof clase.amount === 'number' + ? new Intl.NumberFormat('es-AR', { style: 'currency', currency: 'ARS', maximumFractionDigits: 0 }).format(clase.amount) + : '—' + + return ( + + Cerrar + + } + > + {/* Encabezado con chips */} + + ({ + p: 2.5, + borderRadius: 3, + background: 'rgba(255,255,255,0.03)', + border: `1px solid ${alpha('#fff', 0.08)}` + })} + > + + + {clase.description || '—'} + + + + + + + ({ + borderColor: alpha(theme.palette.text.primary, 0.24), + color: theme.palette.text.secondary, + fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace' + })} + /> + + + + + {/* Grid de detalles rápidos */} + + + + + + {clase.instructors.map(i => ( + ({ + height: 24, + borderRadius: 2, + border: `1px solid ${alpha(theme.palette.primary.main, 0.3)}` + })} + /> + ))} + + ) + : '—' + } + /> + + + + {/* Secciones funcionales */} + ({ + p: 2.5, + borderRadius: 3, + background: 'rgba(255,255,255,0.03)', + border: `1px solid ${alpha('#fff', 0.06)}` + })} + > + + Fechas programadas + + + + + ({ + p: 2.5, + borderRadius: 3, + background: 'rgba(255,255,255,0.03)', + border: `1px solid ${alpha('#fff', 0.06)}` + })} + > + + Participantes + + + + + ({ + p: 2.5, + borderRadius: 3, + background: 'rgba(255,255,255,0.03)', + border: `1px solid ${alpha('#fff', 0.06)}` + })} + > + + Facturas + + + + + + ) +} + +export default DetailClaseDialog + +// --- Pequeño subcomponente para filas de detalle +function DetailRow({ + label, + value +}: { + label: string + value: React.ReactNode +}) { + return ( + + + {label}: + + {value} + + ) +} diff --git a/front-urban/src/views/clases/DialogUpserSubstituteInstructors.tsx b/front-urban/src/views/clases/DialogUpserSubstituteInstructors.tsx new file mode 100644 index 0000000..ad78d00 --- /dev/null +++ b/front-urban/src/views/clases/DialogUpserSubstituteInstructors.tsx @@ -0,0 +1,189 @@ +'use client' + +import { Autocomplete, Box, Button, Chip, Checkbox, Stack, TextField, Typography } from '@mui/material' +import dayjs from 'dayjs' +import { useEffect, useMemo, useState } from 'react' +import { useUserAuth } from '@/app/context/UserAuth' +import { useClases } from '@/@core/hooks/useClases' +import CustomDialog from '@/utils/CustomDialog' +import { Instructor } from '@/app/modules/users/dto/instructor.dto' +import useInstructors from '@/@core/hooks/useInstructors' +import apiClient from '@/lib/apiClient' +import { Snapshot } from './FechasProgramadasAccordion' + +type DialogUpserSubstituteInstructorsProps = { + selected: Snapshot | null + openEditProf: boolean + closeDialogs: () => void +} + +const getInstructorLabel = (i: Instructor) => + i?.name ?? i?.customId ?? (i as any)?.id ?? 'Instructor' + +const isSameInstructor = (a: Instructor, b: Instructor) => a.id === b.id + +const DialogUpserSubstituteInstructors = ({ + closeDialogs, + openEditProf, + selected +}: DialogUpserSubstituteInstructorsProps) => { + const { token } = useUserAuth() + const { refresh: refreshClases } = useClases() + + // Hook de instructores + const { + data: fetchedInstructors = [], + loading, + error: fetchError, + refresh: refreshInstructors + } = useInstructors() + + const [value, setValue] = useState([]) + const [saveError, setSaveError] = useState(null) + + // Fecha para el encabezado + const fechaTexto = useMemo( + () => + selected?.dateRange?.start + ? dayjs(selected.dateRange.start).format('DD-MM HH-mm') + : '—', + [selected] + ) + + // Opciones = fetched + cualquier preseleccionado que no viniera en fetched + const options: Instructor[] = useMemo(() => { + const preSelected = (selected?.substituteInstructors ?? []) as Instructor[] + const byId = new Map() + for (const i of fetchedInstructors) byId.set(i.id, i) + for (const p of preSelected) if (!byId.has(p.id)) byId.set(p.id, p) + return Array.from(byId.values()) + }, [fetchedInstructors, selected?.substituteInstructors]) + + // Rehidratar selección cuando se abre o cambian datos/selección + useEffect(() => { + if (!openEditProf) return + setSaveError(null) + + const preSelected = (selected?.substituteInstructors ?? []) as Instructor[] + const mapped = preSelected.map(p => fetchedInstructors.find(f => f.id === p.id) ?? p) + setValue(mapped) + }, [openEditProf, selected?.id, fetchedInstructors]) + + const handleGuardar = async () => { + if (!selected?.id) return + setSaveError(null) + + try { + const substituteIds = value.map(i => i.id) + + await apiClient.put( + `/sessions/${selected.id}/snapshot`, + { substituteInstructorId: substituteIds } + ) + + await refreshClases() + closeDialogs() + } catch (err: any) { + console.error('❌ Error al actualizar suplentes', err) + setSaveError('Error al guardar los profesores suplentes.') + } + } + + return ( + + + + } + > + + + Fecha: {fechaTexto} + + + + + multiple + options={options} + value={value} + onChange={(_, newValue) => setValue(newValue)} + getOptionLabel={getInstructorLabel} + isOptionEqualToValue={(opt, val) => isSameInstructor(opt, val)} + disableCloseOnSelect + filterSelectedOptions + loading={loading} + loadingText="Cargando…" + noOptionsText={loading ? 'Cargando…' : 'Sin resultados'} + renderTags={(tagValue, getTagProps) => + tagValue.map((option, index) => ( + + )) + } + renderOption={(props, option, { selected }) => ( +
  • + + + + {getInstructorLabel(option)} + + {(option as any).dni && ( + + DNI {(option as any).dni} + + )} + +
  • + )} + renderInput={(params) => ( + + )} + /> +
    +
    +
    + ) +} + +export default DialogUpserSubstituteInstructors diff --git a/front-urban/src/views/clases/DialogUpsertClase copy.txt b/front-urban/src/views/clases/DialogUpsertClase copy.txt new file mode 100644 index 0000000..8444a36 --- /dev/null +++ b/front-urban/src/views/clases/DialogUpsertClase copy.txt @@ -0,0 +1,633 @@ +'use client'; + +import { useUserAuth } from '@/app/context/UserAuth'; +import { Instructor } from '@/app/modules/users/dto/instructor.dto'; +import CustomDialog from '@/utils/CustomDialog'; +import { diasSemana } from '@/utils/diasSemana'; +import { parseLocalDate } from '@/utils/parseLocalDate'; + +import { Delete } from '@mui/icons-material'; +import { + Box, + Button, + Checkbox, + Divider, + FormControl, + FormControlLabel, + FormGroup, + Grid, + IconButton, + Radio, + RadioGroup, + Snackbar, + TextField, + Typography, +} from '@mui/material'; +import type { AlertProps } from '@mui/material/Alert'; +import MuiAlert from '@mui/material/Alert'; +import Autocomplete from '@mui/material/Autocomplete'; +import axios from 'axios'; +import React, { useEffect, useState } from 'react'; + + +const Alert = React.forwardRef(function Alert(props, ref) { + return ; +}); + +/** Helpers de fecha/hora (local → ISO y viceversa) */ +function ymdFromLocalDate(d: Date) { + const y = d.getFullYear(); + const m = String(d.getMonth() + 1).padStart(2, '0'); + const day = String(d.getDate()).padStart(2, '0'); + return `${y}-${m}-${day}`; // YYYY-MM-DD en local +} +function buildLocalISO(yyyyMmDd: string, hhmm: string) { + const [y, m, d] = yyyyMmDd.split('-').map(Number); + const [hh, mm] = (hhmm || '00:00').split(':').map(Number); + const local = new Date(y, m - 1, d, hh, mm, 0, 0); // construye en hora local + return local.toISOString(); // ISO (UTC) para backend +} +function hhmmFromISOToLocal(iso: string) { + const dt = new Date(iso); + return dt.toTimeString().slice(0, 5); // HH:mm +} +function ymdFromISOToLocal(iso: string) { + const dt = new Date(iso); + return ymdFromLocalDate(dt); // YYYY-MM-DD según TZ local +} + +export const DialogUpsertClase = ({ + open, + clase, + onClose, + onRefresh, +}: { + open: boolean; + clase?: any; + onClose: () => void; + onRefresh: () => Promise; +}) => { + const { token } = useUserAuth(); + const [instructores, setInstructores] = useState([]); + const [openSnackbar, setOpenSnackbar] = useState(false); + const [tipo, setTipo] = useState<'recurrente' | 'puntual'>('recurrente'); + const [nombre, setNombre] = useState(''); + const [profesor, setProfesor] = useState(''); + const [dias, setDias] = useState([]); + const [rangoFechas, setRangoFechas] = useState({ desde: '', hasta: '' }); // YYYY-MM-DD local + const [horarios, setHorarios] = useState>({}); + const [fechasPuntuales, setFechasPuntuales] = useState<{ fecha: string; inicio: string; fin: string }[]>([]); + const [errorNombre, setErrorNombre] = useState(false); + const [errorFechas, setErrorFechas] = useState(false); + + const [snackbarText, setSnackbarText] = useState(''); + const [mode, setMode] = useState<'create' | 'edit'>('create'); + + useEffect(() => { + if (open) setMode(clase?.id ? 'edit' : 'create'); + }, [open, clase?.id]); + + const diasEnIngles: Record = { + Lunes: 1, + Martes: 2, + Miércoles: 3, + Jueves: 4, + Viernes: 5, + Sábado: 6, + Domingo: 0, + }; + + const handleDiaChange = (dia: string) => { + setDias((prev) => (prev.includes(dia) ? prev.filter((d) => d !== dia) : [...prev, dia])); + }; + + const addFechaPuntual = () => { + setFechasPuntuales([...fechasPuntuales, { fecha: '', inicio: '', fin: '' }]); + }; + + const updateFechaPuntual = (index: number, key: keyof (typeof fechasPuntuales)[0], value: string) => { + const nuevas = [...fechasPuntuales]; + nuevas[index][key] = value; + setFechasPuntuales(nuevas); + }; + + const removeFechaPuntual = (index: number) => { + setFechasPuntuales((prev) => prev.filter((_, i) => i !== index)); + }; + + const handleCrearClase = async () => { + setErrorNombre(false); + setErrorFechas(false); + + if (!nombre.trim()) { + setErrorNombre(true); + return; + } + + // Calculamos fechas en LOCAL y convertimos a ISO (strings) para enviar + let fechasISO: { start: string; end: string }[] = []; + let startDateISO: string | null = null; + let endDateISO: string | null = null; + + if (tipo === 'recurrente') { + if (!rangoFechas.desde || !rangoFechas.hasta) { + setErrorFechas(true); + return; + } + + const start = parseLocalDate(rangoFechas.desde); + const end = parseLocalDate(rangoFechas.hasta); + const diasSeleccionados = dias.map((d) => diasEnIngles[d]); // 0..6 + + for (let d = new Date(start); d <= end; d.setDate(d.getDate() + 1)) { + const current = new Date(d); + const weekday = current.getDay(); // 0=Dom..6=Sáb (local) + if (diasSeleccionados.includes(weekday)) { + const nombreDia = diasSemana[(weekday + 6) % 7]; // Lunes..Domingo + const cfg = horarios[nombreDia]; + if (cfg?.inicio && cfg?.fin) { + const ymd = ymdFromLocalDate(current); // YYYY-MM-DD en local + fechasISO.push({ + start: buildLocalISO(ymd, cfg.inicio), + end: buildLocalISO(ymd, cfg.fin), + }); + } + } + } + + if (fechasISO.length === 0) { + setErrorFechas(true); + return; + } + + startDateISO = fechasISO[0].start; + endDateISO = fechasISO[fechasISO.length - 1].end; + } else { + // puntual + const validas = fechasPuntuales + .filter((f) => f.fecha) + .map((f) => ({ + start: buildLocalISO(f.fecha, f.inicio || '00:00'), + end: buildLocalISO(f.fecha, f.fin || '00:00'), + })); + + if (validas.length === 0) { + setErrorFechas(true); + return; + } + + fechasISO = validas; + startDateISO = validas.map((v) => v.start).sort()[0]; + endDateISO = validas.map((v) => v.end).sort().slice(-1)[0]; + } + + const payload = { + id: clase?.id, // UPSERT + title: nombre, + profesor: { customId: profesor }, + type: tipo === 'recurrente' ? 'RECURRING' : 'ONE_TIME', + days: tipo === 'recurrente' ? dias.map((d) => d.toLowerCase()) : null, + dates: fechasISO, // ISO strings + startDate: startDateISO, // ISO string + endDate: endDateISO, // ISO string + }; + + try { + const res = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_URL}/sessions/upsert`, payload, { + headers: { Authorization: `Bearer ${token}` }, + }); + + console.log('✅ Clase creada/actualizada:', res.data); + onClose(); + // Reset + setNombre(''); + setProfesor(''); + setTipo('recurrente'); + setDias([]); + setRangoFechas({ desde: '', hasta: '' }); + setHorarios({}); + setFechasPuntuales([]); + setErrorFechas(false); + + const wasEdit = Boolean(clase?.id); + setSnackbarText(wasEdit ? 'La clase fue actualizada exitosamente.' : 'La clase fue creada exitosamente.'); + setOpenSnackbar(true); + await onRefresh(); + } catch (err) { + console.error('❌ Error al guardar clase:', err); + } + }; + + /** Precarga de datos para EDITAR: ISO (UTC) → local para inputs */ + useEffect(() => { + if (!clase) return; + + setNombre(clase.description || ''); + setTipo(clase.type === 'RECURRING' ? 'recurrente' : 'puntual'); + setProfesor(clase.instructors?.[0]?.customId || ''); + + if (clase.startDate && clase.endDate) { + setRangoFechas({ + desde: ymdFromISOToLocal(clase.startDate), + hasta: ymdFromISOToLocal(clase.endDate), + }); + } + + const dayIndexToNombre = (d: number) => diasSemana[(d + 6) % 7]; + const dates = extractDatesFromClase(clase); + + if (dates.length > 0) { + if (clase.type === 'RECURRING') { + const setDiasSel = new Set(); + const h: Record = {}; + + for (const d of dates) { + const localStart = new Date(d.start); // UTC → local + const nombreDia = dayIndexToNombre(localStart.getDay()); // Lunes..Domingo + setDiasSel.add(nombreDia); + + if (!h[nombreDia]) { + h[nombreDia] = { + inicio: hhmmFromISOToLocal(d.start), + fin: hhmmFromISOToLocal(d.end), + }; + } + } + + setDias(Array.from(setDiasSel)); + setHorarios(h); + setFechasPuntuales([]); + } else { + const fechasFormateadas = dates.map((d) => ({ + fecha: ymdFromISOToLocal(d.start), + inicio: hhmmFromISOToLocal(d.start), + fin: hhmmFromISOToLocal(d.end), + })); + setFechasPuntuales(fechasFormateadas); + setDias([]); + setHorarios({}); + } + } else { + setDias([]); + setHorarios({}); + setFechasPuntuales([]); + } + }, [clase]); + + useEffect(() => { + axios + .get('http://localhost:3001/users/instructor', { + headers: { + Authorization: `Bearer ${token}`, + }, + }) + .then((res) => setInstructores(res.data)) + .catch((err) => console.error('❌ Error al obtener instructores:', err)); + }, []); + + const isFormReady = + !!nombre && + (tipo === 'puntual' + ? fechasPuntuales.length > 0 && fechasPuntuales.every((f) => f.fecha && f.inicio && f.fin) + : dias.length > 0 && Object.keys(horarios).length > 0 && !!rangoFechas.desde && !!rangoFechas.hasta); + + return ( + <> + + {clase?.id ? 'Guardar cambios' : 'Crear clase'} + + } + > + + setNombre(e.target.value)} + fullWidth + error={errorNombre} + helperText={errorNombre ? 'El nombre es obligatorio' : ''} + variant="filled" + InputLabelProps={{ shrink: true }} + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + option.name} + renderInput={(params) => ( + + )} + value={instructores.find((i) => i.customId === profesor) || null} + onChange={(_, newValue) => { + setProfesor(newValue?.customId || ''); + }} + isOptionEqualToValue={(option, value) => option.customId === value.customId} + /> + + + + + + + + ¿La clase es recurrente o puntual? + setTipo(e.target.value as any)}> + } label="Recurrente" sx={{ mr: 2 }} /> + } label="Puntual" /> + + + + {tipo === 'recurrente' && ( + + + {diasSemana.map((dia) => ( + handleDiaChange(dia)} color="primary" />} + label={dia} + sx={{ minWidth: 120, mr: 1 }} + /> + ))} + + + + + setRangoFechas((r) => ({ ...r, desde: e.target.value }))} + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + setRangoFechas((r) => ({ ...r, hasta: e.target.value }))} + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + + {dias.map((dia) => ( + + + + setHorarios((h) => ({ + ...h, + [dia]: { ...h[dia], inicio: e.target.value }, + })) + } + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + + setHorarios((h) => ({ + ...h, + [dia]: { ...h[dia], fin: e.target.value }, + })) + } + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + ))} + + )} + + {tipo === 'puntual' && ( + + {fechasPuntuales.map((item, index) => ( + + + updateFechaPuntual(index, 'fecha', e.target.value)} + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + updateFechaPuntual(index, 'inicio', e.target.value)} + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + updateFechaPuntual(index, 'fin', e.target.value)} + sx={{ + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }} + /> + + + removeFechaPuntual(index)} + aria-label="Eliminar" + color="error" + sx={{ + bgcolor: 'rgba(244,67,54,0.08)', + '&:hover': { bgcolor: 'rgba(244,67,54,0.18)' }, + }} + > + + + + + ))} + + + )} + + {errorFechas && ( + + Debe ingresar al menos una fecha válida. + + )} + + + + {openSnackbar && ( + setOpenSnackbar(false)} + anchorOrigin={{ vertical: 'top', horizontal: 'center' }} + > + setOpenSnackbar(false)} severity="success"> + {snackbarText} + + + )} + + ); +}; + +export default DialogUpsertClase; + +/** Extrae [{start,end}] indistintamente si viene como `dates` o `SessionDateSnapshot` */ +function extractDatesFromClase(clase: any): Array<{ start: string; end: string }> { + if (Array.isArray(clase?.dates) && clase.dates.length > 0) { + return clase.dates; + } + if (Array.isArray(clase?.SessionDateSnapshot) && clase.SessionDateSnapshot.length > 0) { + return clase.SessionDateSnapshot + .filter((s: any) => s?.dateRange?.start && s?.dateRange?.end) + .map((s: any) => ({ start: s.dateRange.start, end: s.dateRange.end })); + } + return []; +} diff --git a/front-urban/src/views/clases/DialogUpsertClase.tsx b/front-urban/src/views/clases/DialogUpsertClase.tsx new file mode 100644 index 0000000..d67fd78 --- /dev/null +++ b/front-urban/src/views/clases/DialogUpsertClase.tsx @@ -0,0 +1,638 @@ +'use client'; + +import React, { useEffect, useMemo, useState } from 'react'; +import { + Box, + Button, + Chip, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Divider, + FormControl, + InputLabel, + MenuItem, + Select, + Stack, + TextField, + Typography, + IconButton, + Tooltip, + Paper, + Grid, +} from '@mui/material'; +import { DatePicker, TimePicker, LocalizationProvider } from '@mui/x-date-pickers'; +import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; +import dayjs, { Dayjs } from 'dayjs'; +import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline'; +import ContentCopyIcon from '@mui/icons-material/ContentCopy'; +import AddIcon from '@mui/icons-material/Add'; +import apiClient from '@/lib/apiClient'; +import { useUserAuth } from '@/app/context/UserAuth'; +import 'dayjs/locale/es'; +import AlertNoEditClase, { isClaseEditLocked } from './AlertNoEditClase'; +import CustomDialog from '@/utils/CustomDialog'; +import { DeactivateDialog } from './DesactivateDialog'; +import { DIALOG_INFO } from '@/configs/dialogInfoContent'; +dayjs.locale('es'); + + +type Instructor = { id: string; name: string; customId?: string }; +type SessionType = 'RECURRING' | 'ONE_TIME'; + +type OneTimeRow = { + date: Dayjs | null; + startTime: Dayjs | null; + endTime: Dayjs | null; +}; + +type Props = { + open: boolean; + onClose: () => void; + onRefresh: () => Promise | void; + clase?: any; + instructores: Instructor[]; +}; + + +const DIAS_LABELS = ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'] as const; // 0..6 + +const toDayIdx = (iso: string) => dayjs(iso).day(); // 0..6 +const toHM = (iso: string) => ({ + h: dayjs(iso).hour(), + m: dayjs(iso).minute(), +}); + +export default function DialogUpsertClase({ + open, + onClose, + onRefresh, + clase, + instructores, +}: Props) { + const { token } = useUserAuth(); + const today = dayjs().startOf('day'); + const editLocked = isClaseEditLocked(clase); + + // --------- Estados base --------- + const [loading, setLoading] = useState(false); + const [title, setTitle] = useState(''); + const [type, setType] = useState('RECURRING'); + const [instructorId, setInstructorId] = useState(''); + const [amount, setAmount] = useState('0'); + + // --------- Estado para DeactivateDialog --------- + const [openDeactivate, setOpenDeactivate] = useState(false); + + // --------- Recurrente (rango + días + horas por día) --------- + const [recStartDate, setRecStartDate] = useState(dayjs().startOf('day')); + const [recEndDate, setRecEndDate] = useState(null); + const [recDays, setRecDays] = useState([]); + const [dayTimes, setDayTimes] = useState>({ + 0: { start: null, end: null }, + 1: { start: null, end: null }, + 2: { start: null, end: null }, + 3: { start: null, end: null }, + 4: { start: null, end: null }, + 5: { start: null, end: null }, + 6: { start: null, end: null }, + }); + + // --------- Puntual --------- + const [rows, setRows] = useState([ + { date: dayjs(), startTime: dayjs().hour(18).minute(0), endTime: dayjs().hour(19).minute(0) }, + ]); + + // Precarga si viene clase (editar) + useEffect(() => { + if (!clase) return; + + // base + setTitle(clase.description ?? ''); + setType((clase.type as SessionType) ?? 'RECURRING'); + setAmount(clase.amount != null ? String(clase.amount) : '0'); + if (clase.instructors?.[0]?.id) setInstructorId(clase.instructors[0].id); + + // snapshots -> dateRanges + const snaps = clase?.SessionDateSnapshot as Array<{ + dateRange: { start: string; end: string }; + }> | undefined; + + const dateRanges = + snaps?.map((s) => ({ start: s.dateRange.start, end: s.dateRange.end })) ?? []; + + if ((clase.type as SessionType) === 'ONE_TIME') { + if (dateRanges.length > 0) { + setRows( + dateRanges.map((dr) => { + const d = dayjs(dr.start); + const { h: sh, m: sm } = toHM(dr.start); + const { h: eh, m: em } = toHM(dr.end); + return { + date: d.startOf('day'), + startTime: dayjs().hour(sh).minute(sm).second(0).millisecond(0), + endTime: dayjs().hour(eh).minute(em).second(0).millisecond(0), + }; + }), + ); + const minStart = dayjs(Math.min(...dateRanges.map((r) => dayjs(r.start).valueOf()))); + const maxEnd = dayjs(Math.max(...dateRanges.map((r) => dayjs(r.end).valueOf()))); + setRecStartDate(minStart.startOf('day')); + setRecEndDate(maxEnd.startOf('day')); + } else { + if (clase.startDate && clase.endDate) { + const d = dayjs(clase.startDate); + setRows([ + { + date: d.startOf('day'), + startTime: dayjs(clase.startDate), + endTime: dayjs(clase.endDate), + }, + ]); + } + } + return; // no setear recDays en ONE_TIME + } + + // RECURRING + if (dateRanges.length > 0) { + const daysSet = new Set(); + const timesByDay: Record = { + 0: { start: null, end: null }, + 1: { start: null, end: null }, + 2: { start: null, end: null }, + 3: { start: null, end: null }, + 4: { start: null, end: null }, + 5: { start: null, end: null }, + 6: { start: null, end: null }, + }; + + for (const r of dateRanges) { + const dIdx = toDayIdx(r.start); + daysSet.add(dIdx); + const { h: sh, m: sm } = toHM(r.start); + const { h: eh, m: em } = toHM(r.end); + if (!timesByDay[dIdx].start || !timesByDay[dIdx].end) { + timesByDay[dIdx] = { + start: dayjs().hour(sh).minute(sm).second(0).millisecond(0), + end: dayjs().hour(eh).minute(em).second(0).millisecond(0), + }; + } + } + + const sortedDays = Array.from(daysSet).sort((a, b) => a - b); + setRecDays(sortedDays); + setDayTimes(timesByDay); + + const minStart = dayjs(Math.min(...dateRanges.map((r) => dayjs(r.start).valueOf()))); + const maxEnd = dayjs(Math.max(...dateRanges.map((r) => dayjs(r.end).valueOf()))); + setRecStartDate(minStart.startOf('day')); + setRecEndDate(maxEnd.startOf('day')); + } else { + if (clase.startDate) setRecStartDate(dayjs(clase.startDate).startOf('day')); + if (clase.endDate) setRecEndDate(dayjs(clase.endDate).startOf('day')); + setRecDays([]); + } + }, [clase, open]); + + const canSave = useMemo(() => { + if (!title.trim() || !instructorId) return false; + const money = Number(amount); + if (Number.isNaN(money) || money < 0) return false; + + if (type === 'RECURRING') { + if (!recStartDate || !recEndDate || !recDays.length) return false; + // Fechas: no pasado y fin >= inicio + if (recStartDate.isBefore(today, 'day')) return false; + if (recEndDate.isBefore(recStartDate, 'day')) return false; + + // Horas por día: fin > inicio + for (const d of recDays) { + const t = dayTimes[d]; + if (!t?.start || !t?.end || !t.end.isAfter(t.start)) return false; + } + return true; + } else { + if (!rows.length) return false; + return rows.every((r) => { + if (!r.date || !r.startTime || !r.endTime) return false; + // fecha no en pasado + if (r.date.startOf('day').isBefore(today)) return false; + // horas fin > inicio + if (!r.endTime.isAfter(r.startTime)) return false; + return true; + }); + } + }, [title, instructorId, amount, type, recStartDate, recEndDate, recDays, dayTimes, rows, today]); + + + const getFirstSelectedTime = ( + _recDays: number[], + _dayTimes: Record, + ) => { + if (!_recDays.length) return null; + const t = _dayTimes[_recDays[0]]; + return t?.start && t?.end ? t : null; + }; + + const handleToggleDay = (idx: number) => { + setRecDays((prev) => { + const adding = !prev.includes(idx); + const next = adding ? [...prev, idx].sort((a, b) => a - b) : prev.filter((d) => d !== idx); + + if (adding) { + const base = + getFirstSelectedTime(prev, dayTimes) || { + start: dayjs().hour(18).minute(0).second(0).millisecond(0), + end: dayjs().hour(19).minute(0).second(0).millisecond(0), + }; + setDayTimes((prevTimes) => ({ + ...prevTimes, + [idx]: { + start: prevTimes[idx]?.start || base.start, + end: prevTimes[idx]?.end || base.end, + }, + })); + } + return next; + }); + }; + + const copyTimeToAllSelected = (fromDayIdx: number) => { + const base = dayTimes[fromDayIdx]; + if (!base?.start || !base?.end) return; + setDayTimes((prev) => { + const next = { ...prev }; + for (const d of recDays) { + next[d] = { start: base.start, end: base.end }; + } + return next; + }); + }; + + const handleAddRow = () => { + setRows((prev) => [ + ...prev, + { date: dayjs(), startTime: dayjs().hour(18).minute(0), endTime: dayjs().hour(19).minute(0) }, + ]); + }; + + const handleRemoveRow = (i: number) => { + setRows((prev) => prev.filter((_, idx) => idx !== i)); + }; + + const buildDatesFromRows = () => + rows.map((r) => { + const dateStr = r.date!.format('YYYY-MM-DD'); + const start = dayjs(`${dateStr}T${r.startTime!.format('HH:mm')}`).toISOString(); + const end = dayjs(`${dateStr}T${r.endTime!.format('HH:mm')}`).toISOString(); + return { start, end }; + }); + + const handleSave = async () => { + if (!canSave) return; + setLoading(true); + try { + const payload: any = { + id: clase?.id, + title: title.trim(), + type, + instructorId, + amount: Number(amount) || 0, + }; + + if (type === 'RECURRING') { + // Normalizar horas faltantes con la del primer día + const firstSel = recDays[0]; + const base = + firstSel != null && dayTimes[firstSel]?.start && dayTimes[firstSel]?.end + ? { start: dayTimes[firstSel].start!, end: dayTimes[firstSel].end! } + : { + start: dayjs().hour(18).minute(0).second(0).millisecond(0), + end: dayjs().hour(19).minute(0).second(0).millisecond(0), + }; + + const dayTimesFilled: Record = {} as any; + for (const d of recDays) { + const t = dayTimes[d]; + dayTimesFilled[d] = { + start: (t?.start ?? base.start), + end: (t?.end ?? base.end), + }; + } + + // Normalización del rango: si hay 2+ días y start==end => extender a 7 días + let recStart = recStartDate!; + let recEnd = recEndDate!; + if (recDays.length > 1 && recEnd.isSame(recStart, 'day')) { + recEnd = recStart.add(6, 'day'); + } + + payload.recurrence = { + startDate: recStart.format('YYYY-MM-DD'), + endDate: recEnd.format('YYYY-MM-DD'), + days: recDays, + dayTimes: Object.fromEntries( + recDays.map((d) => [ + String(d), + { + startTime: dayTimesFilled[d].start.format('HH:mm'), + endTime: dayTimesFilled[d].end.format('HH:mm'), + }, + ]), + ), + }; + } else { + payload.dates = buildDatesFromRows(); + } + + await apiClient.post('/sessions/upsert', payload); + + await onRefresh(); + onClose(); + } catch (e: any) { + console.error(e); + alert(e?.response?.data?.message || 'Error al guardar la clase'); + } finally { + setLoading(false); + } + }; + + return ( + + + + + + } + > + <> + { + editLocked ? ( + { + await onRefresh?.(); + onClose(); + }} + /> + ) : ( + + setTitle(e.target.value)} + fullWidth + /> + + { + clase ? + ( + + ) + : ( + + Tipo + + + ) + } + + + Instructor + + + + setAmount(e.target.value)} + inputProps={{ min: 0, step: 50 }} + fullWidth + /> + + + {type === 'RECURRING' ? ( + + Rango habilitado + + setRecStartDate(v ? v.startOf('day') : v)} + slotProps={{ textField: { fullWidth: true } as any }} + format="DD/MM/YYYY" + disablePast + minDate={today} + /> + setRecEndDate(v ? v.startOf('day') : v)} + slotProps={{ textField: { fullWidth: true } as any }} + format="DD/MM/YYYY" + disablePast + minDate={recStartDate ?? today} + + /> + + + Días y horarios + + {DIAS_LABELS.map((label, idx) => { + const selected = recDays.includes(idx); + return ( + handleToggleDay(idx)} + sx={{ mb: 1 }} + /> + ); + })} + + + + {recDays.map((d) => { + const t = dayTimes[d] || { start: null, end: null }; + return ( + + + {DIAS_LABELS[d]} + + + setDayTimes((prev) => ({ ...prev, [d]: { ...prev[d], start: v } })) + } + sx={{ width: '40%' }} + /> + + setDayTimes((prev) => ({ ...prev, [d]: { ...prev[d], end: v } })) + } minTime={t.start ? dayjs().hour(t.start.hour()).minute(t.start.minute()) : undefined} + sx={{ width: '40%' }} + /> + + copyTimeToAllSelected(d)}> + + + + + + + ); + })} + + + ) : ( + + Fechas puntuales + + {rows.map((row, i) => ( + + + + setRows((prev) => + prev.map((r, idx) => (idx === i ? { ...r, date: v ? v.startOf('day') : v } : r)), + ) + } + format="DD/MM/YYYY" + disablePast + minDate={today} + + slotProps={{ textField: { fullWidth: true } as any }} + /> + + setRows((prev) => + prev.map((r, idx) => (idx === i ? { ...r, startTime: v } : r)), + ) + } + slotProps={{ textField: { fullWidth: true } as any }} + /> + + setRows((prev) => + prev.map((r, idx) => (idx === i ? { ...r, endTime: v } : r)), + ) + } + minTime={ + row.startTime + ? dayjs().hour(row.startTime.hour()).minute(row.startTime.minute()) + : undefined + } + slotProps={{ textField: { fullWidth: true } as any }} + /> + + + + handleRemoveRow(i)} + disabled={rows.length === 1} + size="small" + > + + + + + + + ))} + + + + + + + )} + + ) + } + + + + {/* Diálogo de desactivación */} + {clase && ( + setOpenDeactivate(false)} + modelId={clase.id} + model="session" + claseDescription={title || clase.description || 'esta clase'} + onSuccess={async () => { + await onRefresh(); + onClose(); + }} + /> + )} + + ); +} diff --git a/front-urban/src/views/clases/FacturasAsistentesAccordion.tsx b/front-urban/src/views/clases/FacturasAsistentesAccordion.tsx new file mode 100644 index 0000000..a1db820 --- /dev/null +++ b/front-urban/src/views/clases/FacturasAsistentesAccordion.tsx @@ -0,0 +1,282 @@ +'use client'; + +import { useMemo, useState } from 'react'; +import dayjs from 'dayjs'; +import { + Accordion, + AccordionSummary, + AccordionDetails, + Box, + Chip, + CircularProgress, + Stack, + Typography, + Alert, + MenuItem, + Select, + FormControl, + InputLabel, + ToggleButtonGroup, + ToggleButton, + alpha, + Tooltip +} from '@mui/material'; +import { MaterialReactTable, MRT_ColumnDef } from 'material-react-table'; +import { MRT_Localization_ES } from 'material-react-table/locales/es'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import WarningAmberIcon from '@mui/icons-material/WarningAmber'; +import { useSessionInvoicesByMonth, type InvoiceStatus, type AssistantInvoice } from '@/@core/hooks/useSessionInvoicesByMonth'; +import { useUserAuth } from '@/app/context/UserAuth'; + +type Props = { + sessionId: string; +}; + +const FacturasAsistentesAccordion = ({ sessionId }: Props) => { + const { token } = useUserAuth(); + + // Estado para mes y año + const [selectedMonth, setSelectedMonth] = useState(dayjs().format('MM')); + const [selectedYear, setSelectedYear] = useState(dayjs().format('YYYY')); + + // Estado para filtro de status (en memoria) + const [statusFilter, setStatusFilter] = useState<'all' | InvoiceStatus | 'no-invoice'>('all'); + + const { data, loading, error } = useSessionInvoicesByMonth({ + sessionId, + month: selectedMonth, + year: selectedYear, + }); + + // Filtrado en memoria por status + const filteredAssistants = useMemo(() => { + if (!data?.assistants) return []; + + if (statusFilter === 'all') return data.assistants; + + if (statusFilter === 'no-invoice') { + return data.assistants.filter((a: AssistantInvoice) => !a.hasInvoice); + } + + return data.assistants.filter((a: AssistantInvoice) => a.invoiceStatus === statusFilter); + }, [data?.assistants, statusFilter]); + + // Verificar si estamos en un mes futuro + const isCurrentOrPastMonth = useMemo(() => { + const selectedDate = dayjs(`${selectedYear}-${selectedMonth}-01`); + const now = dayjs(); + return selectedDate.isBefore(now, 'month') || selectedDate.isSame(now, 'month'); + }, [selectedMonth, selectedYear]); + + // Generar años (últimos 3 años + próximos 2) + const years = useMemo(() => { + const currentYear = dayjs().year(); + const yearsList = []; + for (let i = currentYear - 3; i <= currentYear + 2; i++) { + yearsList.push(i.toString()); + } + return yearsList; + }, []); + + // Meses + const months = [ + { value: '01', label: 'Enero' }, + { value: '02', label: 'Febrero' }, + { value: '03', label: 'Marzo' }, + { value: '04', label: 'Abril' }, + { value: '05', label: 'Mayo' }, + { value: '06', label: 'Junio' }, + { value: '07', label: 'Julio' }, + { value: '08', label: 'Agosto' }, + { value: '09', label: 'Septiembre' }, + { value: '10', label: 'Octubre' }, + { value: '11', label: 'Noviembre' }, + { value: '12', label: 'Diciembre' }, + ]; + + // Columnas para la tabla + const columns = useMemo(() => [ + { + header: 'Asistente', + accessorKey: 'name', + size: 180, + Cell: ({ row }) => ( + + + {row.original.name || '—'} + + {!row.original.hasInvoice && isCurrentOrPastMonth && ( + + + + )} + + ) + }, + { + header: 'Estado', + accessorKey: 'invoiceStatus', + size: 90, + Cell: ({ row }) => { + const status = row.original.invoiceStatus; + const colorMap: Record = { + PAID: 'success', + PENDING: 'warning', + CANCELED: 'error' + }; + return ( + + ); + } + }, + { + header: 'Monto', + accessorKey: 'amount', + size: 80, + Cell: ({ row }) => ( + + {row.original.amount === null ? '—' : new Intl.NumberFormat('es-AR', { style: 'currency', currency: 'ARS', maximumFractionDigits: 0 }).format(row.original.amount)} + + ) + }, + { + header: 'Factura ID', + accessorKey: 'invoiceId', + size: 160, + Cell: ({ row }) => ( + + {row.original.invoiceId || '—'} + + ) + } + ], [isCurrentOrPastMonth]) as MRT_ColumnDef[]; + + // UI fragments para evitar problemas de inferencia + const loadingUI: React.ReactNode = loading ? ( + + + + ) : null; + + const errorUI: React.ReactNode = !loading && error ? ( + Error al cargar las facturas. Por favor, intenta nuevamente. + ) : null; + + const warningUI: React.ReactNode = !loading && !error && !isCurrentOrPastMonth ? ( + }>Las facturas para este mes todavía pueden no estar generadas. + ) : null; + + const tableUI: React.ReactNode = !loading && !error ? ( + + ) : null; + + return ( + + }> + + Facturas por Asistente + + + + +
    + {/* Filtros de Mes y Año */} + + + Mes + + + + + Año + + + + + + {loadingUI} + {errorUI} + {warningUI} + {tableUI} +
    +
    +
    + ); +}; + +export default FacturasAsistentesAccordion; + +// --- Filtro de estado extraído para evitar problemas de sobrecarga de tipos +type StatusFilterProps = { + value: 'all' | InvoiceStatus | 'no-invoice'; + onChange: (v: 'all' | InvoiceStatus | 'no-invoice') => void; +}; + +function StatusFilter({ value, onChange }: StatusFilterProps) { + const handleChange = (_: React.MouseEvent, newValue: string | null) => { + if (newValue !== null) onChange(newValue as 'all' | InvoiceStatus | 'no-invoice'); + }; + return ( + // @ts-ignore: MUI type inference edge case for ToggleButtonGroup inside Box + + + Filtrar por estado: + + + Todos + Pendientes + Pagadas + Canceladas + Sin Factura + + + ); +} + +// (Listado original reemplazado por MaterialReactTable) diff --git a/front-urban/src/views/clases/FechasProgramadasAccordion.tsx b/front-urban/src/views/clases/FechasProgramadasAccordion.tsx new file mode 100644 index 0000000..6fd5bcc --- /dev/null +++ b/front-urban/src/views/clases/FechasProgramadasAccordion.tsx @@ -0,0 +1,194 @@ +'use client' +import DeleteIcon from '@mui/icons-material/Delete'; +import EditIcon from '@mui/icons-material/Edit'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import HowToRegIcon from '@mui/icons-material/HowToReg'; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Box, + Chip, + IconButton, + List, + ListItem, + ListItemText, + Stack, + Tooltip, + Typography +} from '@mui/material'; +import dayjs from 'dayjs'; +import 'dayjs/locale/es'; // 👈 español +import { useMemo, useState } from 'react'; +import DialogAttendanceSnapshot from '../dashboard/DialogAttendanceSnapshot'; +import { DeactivateDialog } from './DesactivateDialog'; +import { Clase } from './DetailClaseDialog'; +import DialogUpserSubstituteInstructors from './DialogUpserSubstituteInstructors'; + +type Props = { clase: Clase; onDeactivateSuccess?: () => void } +export type Snapshot = Clase['SessionDateSnapshot'][number] + +const FechasProgramadasAccordion = ({ clase, onDeactivateSuccess }: Props) => { + const snapshots = useMemo(() => clase.SessionDateSnapshot ?? [], [clase]) + + const [selected, setSelected] = useState(null) + const [openAsist, setOpenAsist] = useState(false) + const [openEditProf, setOpenEditProf] = useState(false) + const [openDeactivate, setOpenDeactivate] = useState(false) + + const openAsistDialog = (snap: Snapshot) => { + setSelected(snap) + setOpenAsist(true) + } + + const openEditProfDialog = (snap: Snapshot) => { + setSelected(snap) + setOpenEditProf(true) + } + + const openDeactivateDialog = (snap: Snapshot) => { + setSelected(snap) + setOpenDeactivate(true) + } + + const closeDialogs = () => { + setOpenAsist(false) + setOpenEditProf(false) + setSelected(null) + } + + const horasEntre = (startISO: string, endISO: string) => { + const minutes = dayjs(endISO).diff(dayjs(startISO), 'minute') + const h = minutes / 60 + return Number.isInteger(h) ? `${h} h` : `${h.toFixed(1)} h` + } + + const diaDeSemana = (iso: string) => { + const str = dayjs(iso).locale('es').format('dddd') // lunes, martes... + return str.charAt(0).toUpperCase() + str.slice(1) // Lunes, Martes... + } + + return ( + <> + + }> + Fechas Programadas + + + {snapshots.length === 0 ? ( + Sin fechas programadas. + ) : ( + + {snapshots.map((s) => { + const start = s.dateRange.start + const end = s.dateRange.end + return ( + + + openAsistDialog(s)} disabled={!s.isActive}> + + + + + openEditProfDialog(s)} disabled={!s.isActive}> + + + + + openDeactivateDialog(s)} disabled={!s.isActive}> + + + + + } + > + + + {dayjs(start).format('DD-MM HH-mm')} + + + + + } + secondary={ + + 0 + ? `Suplente: ${s.substituteInstructors.map(i => i.name).join(', ')}` + : 'Sin suplente' + } + color={s.substituteInstructors.length > 0 ? "info" : "primary"} + sx={{ + mt: 0.5, + height: 22 + }} + /> + {!s.isActive && ( + + )} + + } + /> + + ) + })} + + )} + + + + + + + + setOpenDeactivate(false)} + modelId={selected?.id || ''} + model='snapshot' + claseDescription={ + + + {dayjs(selected?.dateRange.start).format('DD-MM HH-mm')} + + + + + } + onSuccess={() => { + setOpenDeactivate(false) + onDeactivateSuccess?.() + // Aquí podrías agregar lógica para refrescar la lista si es necesario + }} + /> + + + + ) +} + +export default FechasProgramadasAccordion diff --git a/front-urban/src/views/clases/ListClases.tsx b/front-urban/src/views/clases/ListClases.tsx new file mode 100644 index 0000000..e32143c --- /dev/null +++ b/front-urban/src/views/clases/ListClases.tsx @@ -0,0 +1,212 @@ +'use client'; + +import EditIcon from '@mui/icons-material/Edit'; +import VisibilityIcon from '@mui/icons-material/Visibility'; +import { Chip, Grid, IconButton, Tooltip, Typography, Box, ToggleButtonGroup, ToggleButton } from '@mui/material'; +import CheckCircleIcon from '@mui/icons-material/CheckCircle'; +import CancelIcon from '@mui/icons-material/Cancel'; +import ViewListIcon from '@mui/icons-material/ViewList'; +import { MaterialReactTable } from 'material-react-table'; +import { useMemo, useState } from 'react'; +import DetailClaseDialog, { Clase } from './DetailClaseDialog'; +import useInstructors from '@/@core/hooks/useInstructors'; +import DialogUpsertClase from './DialogUpsertClase'; +import { useUserAuth } from '@/app/context/UserAuth'; + +type Props = { + data: Clase[]; + loading: boolean; + error: unknown; + refresh: () => Promise; + statusFilter: 'all' | 'active' | 'inactive'; + onStatusFilterChange: (filter: 'all' | 'active' | 'inactive') => void; +}; + +const ListClases = ({ data, loading, error, refresh, statusFilter, onStatusFilterChange }: Props) => { + const { user } = useUserAuth(); + + const [claseSeleccionada, setClaseSeleccionada] = useState(null); + const [openDialog, setOpenDialog] = useState(false); + const [openDetalle, setOpenDetalle] = useState(false); + + // Hook de instructores + const { + data: instructores = [], + loading: loadingInstructores, + error: errorInstructores, + } = useInstructors(user?.role === 'ADMIN'); + + // Ya no necesitamos filtrar aquí porque viene filtrado del backend + // const filteredData = useMemo(() => { ... }, [data, statusFilter]); + + const handleFilterChange = ( + event: React.MouseEvent, + newFilter: 'all' | 'active' | 'inactive' | null, + ) => { + if (newFilter !== null) { + onStatusFilterChange(newFilter); + } + }; + + const columns = useMemo( + () => [ + { + header: 'Descripción', + accessorKey: 'description', + Cell: ({ row }: any) => { + const desc = row.original.description || '—'; + return ( + + {desc} + + ); + }, + }, + { + header: 'Estado', + accessorKey: 'estado', + size: 10, + Cell: ({ row }: any) => { + const desc = row.original.isActive ? 'Activo' : 'Inactivo'; + return ( + + ); + }, + }, + { + header: 'Acciones', + id: 'acciones', + enableSorting: false, + enableColumnFilter: false, + size: 140, + Cell: ({ row }: any) => ( + <> + {user && user.role === 'ADMIN' && ( + + + { + setClaseSeleccionada(row.original); + setOpenDialog(true); + }} + aria-label="Editar clase" + > + + + + + )} + + { + setClaseSeleccionada(row.original); + setOpenDetalle(true); + }} + aria-label="Ver detalle de clase" + > + + + + + ), + }, + ], + [] + ); + + return ( + <> + + {/* Botones de filtro */} + + + + + + Todas + + + + Activas + + + + Inactivas + + + + {data.length} {data.length === 1 ? 'clase' : 'clases'} + + + + + {/* Tabla */} + + + + + + { setOpenDialog(false) }} + clase={claseSeleccionada} + onRefresh={refresh} + instructores={instructores} + /> + { setOpenDetalle(false) }} + clase={claseSeleccionada} + /> + + ); +}; + +export default ListClases; diff --git a/front-urban/src/views/clases/ParticipantsAccordion.tsx b/front-urban/src/views/clases/ParticipantsAccordion.tsx new file mode 100644 index 0000000..575b442 --- /dev/null +++ b/front-urban/src/views/clases/ParticipantsAccordion.tsx @@ -0,0 +1,260 @@ +'use client'; + +import React, { + forwardRef, + useEffect, + useImperativeHandle, + useMemo, + useState, +} from 'react'; +import { + Accordion, + AccordionSummary, + AccordionDetails, + Grid, + Typography, + Button, + Paper, + List, + ListItem, + ListItemText, + IconButton, + CircularProgress, + TextField, + InputAdornment, +} from '@mui/material'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import SearchIcon from '@mui/icons-material/Search'; +import ClearIcon from '@mui/icons-material/Clear'; +import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; +import ArrowBackIcon from '@mui/icons-material/ArrowBack'; +import { useSessionParticipants } from '@/@core/hooks/useSessionParticipants'; +import { useUserAuth } from '@/app/context/UserAuth'; + +export type ParticipantsAccordionHandle = { + /** Guarda cambios en el backend (PUT /participants) */ + save: () => Promise; + /** Refresca listas desde el backend */ + refresh: () => Promise; + /** Indica si ya se cargaron los datos al menos una vez */ + isLoaded: boolean; +}; + +type Props = { + sessionId: string; + title?: string; + defaultExpanded?: boolean; +}; + +const normalize = (s: string) => + (s || '').toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, ''); + +const ParticipantsAccordion = forwardRef( + ({ sessionId, title = 'Agregar Participantes', defaultExpanded = false }, ref) => { + const { token } = useUserAuth() + // Lazy: no auto-fetch + const { selected, available, add, remove, save, loading, refresh } = + useSessionParticipants(token ?? '', sessionId, false); + + const [expanded, setExpanded] = useState(defaultExpanded); + const [loaded, setLoaded] = useState(false); + + const [qSel, setQSel] = useState(''); + const [qAvail, setQAvail] = useState(''); + + // Cargar solo al expandir por primera vez + useEffect(() => { + if (expanded && !loaded) { + (async () => { + try { + await refresh(); + } finally { + setLoaded(true); + } + })(); + } + }, [expanded, loaded, refresh]); + + useImperativeHandle(ref, () => ({ + save: async () => { + if (!loaded) { + await refresh(); + setLoaded(true); + } + await save(); + }, + refresh: async () => { + await refresh(); + setLoaded(true); + }, + isLoaded: loaded, + })); + + const selFiltered = useMemo(() => { + const q = normalize(qSel); + if (!q) return selected; + return selected.filter((p) => + normalize(`${p.customId ?? ''} ${p.name}`).includes(q), + ); + }, [selected, qSel]); + + const availFiltered = useMemo(() => { + const q = normalize(qAvail); + if (!q) return available; + return available.filter((p) => + normalize(`${p.customId ?? ''} ${p.name}`).includes(q), + ); + }, [available, qAvail]); + + const clearSearches = () => { + setQSel(''); + setQAvail(''); + }; + + return ( + setExpanded(exp)} sx={{ mt: 2 }}> + }> + {title} + + + + + + + + + + + + {/* Seleccionados */} + + Seleccionados ({selected.length}) + + setQSel(e.target.value)} + disabled={loading && !loaded} + sx={{ my: 1 }} + InputProps={{ + startAdornment: ( + + + + ), + }} + /> + + + {!loaded || loading ? ( + + + + ) : ( + + {selFiltered.map((p) => ( + remove(p)} + disabled={loading} + aria-label="Quitar" + > + + + } + > + + + ))} + {!selFiltered.length && ( + + + + )} + + )} + + + + {/* Flecha central */} + + + + + {/* Disponibles */} + + Disponibles ({available.length}) + + setQAvail(e.target.value)} + disabled={loading && !loaded} + sx={{ my: 1 }} + InputProps={{ + startAdornment: ( + + + + ), + }} + /> + + + {!loaded || loading ? ( + + + + ) : ( + + {availFiltered.map((p) => ( + add(p)} + disabled={loading} + aria-label="Agregar" + > + + + } + > + + + ))} + {!availFiltered.length && ( + + + + )} + + )} + + + + + + ); + }, +); + +ParticipantsAccordion.displayName = 'ParticipantsAccordion'; +export default ParticipantsAccordion; diff --git a/front-urban/src/views/clases/index.tsx b/front-urban/src/views/clases/index.tsx new file mode 100644 index 0000000..34dd33d --- /dev/null +++ b/front-urban/src/views/clases/index.tsx @@ -0,0 +1,121 @@ +'use client'; + +import { Add } from '@mui/icons-material'; +import { + alpha, + Box, + Card, + CardActionArea, + CardContent, + Grid, + Typography, +} from '@mui/material'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import DialogUpsertClase from './DialogUpsertClase'; +import ListClases from './ListClases'; +import { useClases } from '@/@core/hooks/useClases'; +import useInstructors from '@/@core/hooks/useInstructors'; +import { useUserAuth } from '@/app/context/UserAuth'; + +const ClasesComponent = () => { + const [openUpsert, setOpenUpsert] = useState(false); + const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive'>('all'); + const { user } = useUserAuth(); + const { data, loading, error, refresh } = useClases({ status: statusFilter }); + + // Hook de instructores + const { + data: instructores = [], + loading: loadingInstructores, + error: errorInstructores, + } = useInstructors(); + return ( + + + + { + user && user.role === 'ADMIN' && ( + setOpenUpsert(true)} + elevation={0} + sx={theme => ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + border: `1px solid ${alpha(theme.palette.primary.main, 0.25)}`, + boxShadow: `0 10px 30px ${alpha('#000', 0.18)}`, + transition: 'transform .15s ease, box-shadow .2s ease, border-color .2s ease', + '&:hover': { + transform: 'translateY(-2px) scale(1.02)', + boxShadow: `0 14px 40px ${alpha(theme.palette.primary.main, 0.35)}`, + borderColor: alpha(theme.palette.primary.main, 0.5) + }, + '&:active': { + transform: 'translateY(0) scale(0.998)' + } + })} + > + + + ({ + width: 56, + height: 56, + borderRadius: '14px', + display: 'grid', + placeItems: 'center', + background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.18)} 0%, ${alpha( + theme.palette.primary.light, + 0.12 + )} 100%)`, + border: `1px solid ${alpha(theme.palette.primary.main, 0.35)}` + })} + > + + + + + Crear nueva clase + + + Programá una clase o workshop + + + + + ) + } + + + + + + setOpenUpsert(false)} + onRefresh={refresh} + instructores={instructores} + /> + + ); +}; + +export default ClasesComponent; diff --git a/front-urban/src/views/configuracion/index.tsx b/front-urban/src/views/configuracion/index.tsx new file mode 100644 index 0000000..9f5ca72 --- /dev/null +++ b/front-urban/src/views/configuracion/index.tsx @@ -0,0 +1,168 @@ +'use client'; + +import { + Box, Grid, Card, CardContent, Typography, Chip, Button, CircularProgress, +} from '@mui/material'; +import { useEffect, useRef, useState } from 'react'; +import { useUserAuth } from '@/app/context/UserAuth'; +import apiClient from '@/lib/apiClient'; + +const WHATSAPP_STATUS_URL = '/whatsapp/status'; + +type WhatsappStatusResp = { + status: 'Correcto' | 'Sin session' | string; + phone: string | null; + qr: string | null; +}; + +const ensureDataUrl = (qr: string | null) => (qr ? (qr.startsWith('data:') ? qr : `data:image/png;base64,${qr}`) : null); + +const WhatsAppComponent = () => { + const { token } = useUserAuth(); + + const [qrSrc, setQrSrc] = useState(null); + const [waStatus, setWaStatus] = useState('Sin session'); + const [phone, setPhone] = useState('No disponible'); + const [loading, setLoading] = useState(false); + const [err, setErr] = useState(null); + + const inFlight = useRef(false); // evita solapar requests del polling + + const applyStatus = (json: WhatsappStatusResp) => { + setWaStatus(json.status ?? 'Sin session'); + setPhone(json.phone ?? 'No disponible'); + setQrSrc(ensureDataUrl(json.qr ?? null)); + setErr(null); + }; + + const fetchStatus = async (opts?: { silent?: boolean }) => { + if (!token) return; + + const silent = opts?.silent === true; + if (!silent) { + setLoading(true); + setErr(null); + } + + try { + const res = await apiClient.get(WHATSAPP_STATUS_URL); + applyStatus(res.data); + } catch (e: any) { + if (!silent) { + setErr(e?.response?.data?.message || e?.message || 'Error obteniendo estado de WhatsApp'); + setWaStatus('Sin session'); + setPhone('No disponible'); + setQrSrc(null); + } + } finally { + if (!silent) setLoading(false); + } + }; + + // Primer fetch + useEffect(() => { + fetchStatus(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [token]); + + // Polling cada 5s (silencioso) + useEffect(() => { + if (!token) return; + + const tick = async () => { + if (document.hidden) return; // opcional: no refrescar si la pestaña está oculta + if (inFlight.current) return; // evita superposición + inFlight.current = true; + try { + await fetchStatus({ silent: true }); + } finally { + inFlight.current = false; + } + }; + + const id = setInterval(tick, 5000); + // correr una vez al montar para no esperar 5s + tick(); + + return () => clearInterval(id); + }, [token]); + + const chipColor = err ? 'error' : waStatus === 'Correcto' ? 'success' : 'warning'; + + return ( + + + + + + {loading ? ( + + + + ) : qrSrc ? ( + + ) : ( + + {err || 'No hay QR disponible'} + + )} + + + + + + Bot de WhatsApp + + + + + + + + + + Teléfono:{' '} + + {phone} + + + + + + + + ); +}; + +export default WhatsAppComponent; diff --git a/front-urban/src/views/dashboard/Award.tsx b/front-urban/src/views/dashboard/Award.tsx new file mode 100644 index 0000000..137356f --- /dev/null +++ b/front-urban/src/views/dashboard/Award.tsx @@ -0,0 +1,35 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Button from '@mui/material/Button' + +const Award = () => { + return ( + + +
    + Congratulations John! 🎉 + Best seller of the month +
    +
    + + $42.8k + + 78% of target 🚀 +
    + + trophy image +
    +
    + ) +} + +export default Award diff --git a/front-urban/src/views/dashboard/CardDashboardDetailProfesor.tsx b/front-urban/src/views/dashboard/CardDashboardDetailProfesor.tsx new file mode 100644 index 0000000..15b0ce0 --- /dev/null +++ b/front-urban/src/views/dashboard/CardDashboardDetailProfesor.tsx @@ -0,0 +1,191 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Grid from '@mui/material/Grid' +import { alpha, Badge } from '@mui/material' + +// Type Imports +import type { ThemeColor } from '@core/types' + +// Components Imports +import OptionMenu from '@core/components/option-menu' +import CustomAvatar from '@core/components/mui/Avatar' +import { useUserAuth } from '@/app/context/UserAuth' + +export type CardDetailsData = { + sessions: { + total: number + active: number + inactive: number + } + users: { + total: number + active: number + inactive: number + } + assistants: number + invoices: { + total: number + paid: number + pending: number + } + revenue: number +} + +type Props = { + cardDetails: CardDetailsData | undefined +} + +// helpers +const fmtInt = (n?: number) => + typeof n === 'number' ? n.toLocaleString('es-AR') : '—' + +const fmtCurrency = (n?: number) => + typeof n === 'number' + ? new Intl.NumberFormat('es-AR', { style: 'currency', currency: 'ARS', maximumFractionDigits: 0 }).format(n) + : '—' + +const CardDashboardDetail = ({ cardDetails }: Props) => { + const { user } = useUserAuth() + + const items: Array<{ + title: string + stats: string + subtitle?: string + color: ThemeColor + icon: string + showBadge?: boolean + badgeContent?: number + }> = [ + { + title: 'Clases', + stats: fmtInt(cardDetails?.sessions.total), + subtitle: `${fmtInt(cardDetails?.sessions.active)} activas`, + color: 'primary', + icon: 'ri-pie-chart-2-line' + }, + { + title: 'Asistentes', + stats: fmtInt(cardDetails?.assistants), + color: 'warning', + icon: 'ri-user-add-line' + }, + ...(user && user?.role === 'ADMIN' ? [ + { + title: 'Usuarios', + stats: fmtInt(cardDetails?.users.total), + subtitle: `${fmtInt(cardDetails?.users.active)} activos`, + color: 'success' as ThemeColor, + icon: 'ri-group-line' + }, + { + title: 'Facturas', + stats: fmtInt(cardDetails?.invoices?.total), + subtitle: `${fmtInt(cardDetails?.invoices?.pending)} pendientes`, + color: 'warning' as ThemeColor, + icon: 'ri-file-list-3-line', + showBadge: (cardDetails?.invoices?.pending ?? 0) > 0, + badgeContent: cardDetails?.invoices?.pending + }, + { + title: 'Ingresos', + stats: fmtCurrency(cardDetails?.revenue), + color: 'info' as ThemeColor, + icon: 'ri-money-dollar-circle-line' + } + ] : []) + ] + + return ( + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}` + })} + > + + ({ + fontWeight: 800, + letterSpacing: 0.2, + background: `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.55 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text', + // color: 'transparent' + })} + > + Detalles + + } + // action={} + subheader={ +

    + Resumen general • datos en tiempo real +

    + } + /> + + + + {items.map((item, idx) => ( + +
    + + + + + + +
    + {item.title} + + {item.stats} + + {item.subtitle && ( + + {item.subtitle} + + )} +
    +
    +
    + ))} +
    +
    +
    + ) +} + +export default CardDashboardDetail diff --git a/front-urban/src/views/dashboard/DashboardCharts.tsx b/front-urban/src/views/dashboard/DashboardCharts.tsx new file mode 100644 index 0000000..4f55032 --- /dev/null +++ b/front-urban/src/views/dashboard/DashboardCharts.tsx @@ -0,0 +1,355 @@ +'use client' + +import { memo } from 'react' +import { Card, CardContent, CardHeader, Typography, Grid, alpha, useTheme, Box } from '@mui/material' +import { PieChart, Pie, Cell, Legend, Tooltip, ResponsiveContainer } from 'recharts' +import type { CardDetailsData } from './CardDashboardDetailProfesor' + +type Props = { + cardDetails: CardDetailsData | undefined + userRole: 'ADMIN' | 'INSTRUCTOR' +} + +const DashboardCharts = memo(({ cardDetails, userRole }: Props) => { + const theme = useTheme() + + // Validación temprana para evitar errores + if (!cardDetails || !cardDetails.sessions || !cardDetails.users) { + return null + } + + // Asegurar que los valores sean números válidos + const sessionsActive = Math.max(0, Number(cardDetails.sessions?.active) || 0) + const sessionsInactive = Math.max(0, Number(cardDetails.sessions?.inactive) || 0) + const sessionsTotal = sessionsActive + sessionsInactive + + const usersActive = Math.max(0, Number(cardDetails.users?.active) || 0) + const usersInactive = Math.max(0, Number(cardDetails.users?.inactive) || 0) + const usersTotal = usersActive + usersInactive + + const invoicesPaid = Math.max(0, Number(cardDetails.invoices?.paid) || 0) + const invoicesPending = Math.max(0, Number(cardDetails.invoices?.pending) || 0) + const invoicesTotal = invoicesPaid + invoicesPending + + // Color adaptativo según el tema + const textColor = theme.palette.mode === 'dark' ? '#ffffff' : theme.palette.text.primary + + // Preparar datos para Recharts (formato array de objetos) + const sessionsData = [ + { name: 'Activas', value: sessionsActive }, + { name: 'Inactivas', value: sessionsInactive } + ].filter(d => d.value > 0) + + const usersData = [ + { name: 'Activos', value: usersActive }, + { name: 'Inactivos', value: usersInactive } + ].filter(d => d.value > 0) + + const invoicesData = [ + { name: 'Pagadas', value: invoicesPaid }, + { name: 'Pendientes', value: invoicesPending } + ].filter(d => d.value > 0) + + // Colores para gráficos + const sessionsColors = ['#10b981', '#ef4444'] + const usersColors = ['#3b82f6', '#94a3b8'] + const invoicesColors = ['#10b981', '#f59e0b'] + + // Si el usuario es instructor y no hay datos de usuarios, no mostramos ese gráfico + const showUsersChart = userRole === 'ADMIN' && usersTotal > 0 + const showInvoicesChart = userRole === 'ADMIN' + + // Determinar el tamaño de los gráficos según cuántos se mostrarán + const chartsToShow = [true, showUsersChart, showInvoicesChart].filter(Boolean).length + const chartSize = chartsToShow === 3 ? 4 : chartsToShow === 2 ? 6 : 12 + + // No renderizar si no hay datos válidos en sesiones + if (sessionsTotal === 0) { + return ( + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}`, + p: 4, + textAlign: 'center' + })} + > + + No hay datos suficientes para mostrar gráficos + + + ) + } + + // Componente reutilizable para gráficos Recharts + const DonutChart = ({ + data, + colors, + tooltipLabel + }: { + data: Array<{ name: string; value: number }> + colors: string[] + tooltipLabel: string + }) => { + const total = data.reduce((sum, d) => sum + d.value, 0) + const percentOf = (val: number) => (total > 0 ? Math.round((val / total) * 100) : 0) + + // Etiqueta personalizada colocada dentro del sector para evitar overflow + const RADIAN = Math.PI / 180 + const renderLabel = (props: any) => { + const { cx, cy, midAngle, innerRadius, outerRadius, value, name } = props + const percent = percentOf(Number(value)) + // Punto a medio camino entre inner y outer radius + const radius = innerRadius + (outerRadius - innerRadius) * 0.6 + const x = cx + radius * Math.cos(-midAngle * RADIAN) + const y = cy + radius * Math.sin(-midAngle * RADIAN) + // No mostrar etiquetas en sectores muy pequeños + if (percent < 5) return null + return ( + + {`${percent}%`} + + ) + } + return ( + + + + {data.map((entry, index) => ( + + ))} + + [ + `${value} ${tooltipLabel} (${percentOf(Number(value))}%)`, + name + ]} + /> + + + + ) + } + + return ( + + {/* Gráfico de Sesiones */} + + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}` + })} + > + ({ + fontWeight: 800, + letterSpacing: 0.2, + background: `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.55 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text' + })} + > + Distribución de Clases + + } + subheader={ + + {sessionsTotal} clases • {sessionsActive} activas + + } + /> + + {sessionsData.length > 0 ? ( + + ) : ( + + Sin datos para sesiones + + )} + + + + + {/* Gráfico de Usuarios (solo para ADMIN) */} + {showUsersChart && ( + + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}` + })} + > + ({ + fontWeight: 800, + letterSpacing: 0.2, + background: `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.55 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text' + })} + > + Distribución de Usuarios + + } + subheader={ + + {usersTotal} usuarios • {usersActive} activos + + } + /> + + {usersData.length > 0 ? ( + + ) : ( + + Sin datos para usuarios + + )} + + + + )} + + {/* Gráfico de Facturas (solo para ADMIN) */} + {showInvoicesChart && ( + + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + boxShadow: `0 10px 30px ${alpha('#000', 0.2)}` + })} + > + ({ + fontWeight: 800, + letterSpacing: 0.2, + background: `linear-gradient(90deg, ${theme.palette.text.primary} 0%, ${alpha( + theme.palette.text.primary, + 0.55 + )} 100%)`, + WebkitBackgroundClip: 'text', + backgroundClip: 'text' + })} + > + Estado de Facturas + + } + subheader={ + + {invoicesTotal} facturas • {invoicesPending} pendientes + + } + /> + + {invoicesData.length > 0 ? ( + + ) : ( + + + 📋 + + + No hay facturas este mes + + + )} + + + + )} + + ) +}) + +DashboardCharts.displayName = 'DashboardCharts' + +export default DashboardCharts diff --git a/front-urban/src/views/dashboard/DepositWithdraw.tsx b/front-urban/src/views/dashboard/DepositWithdraw.tsx new file mode 100644 index 0000000..be92f7c --- /dev/null +++ b/front-urban/src/views/dashboard/DepositWithdraw.tsx @@ -0,0 +1,150 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Grid from '@mui/material/Grid' + +// Component Imports +import Link from '@components/Link' + +type DataType = { + logo: string + title: string + amount: string + subtitle: string +} + +// Vars +export const depositData: DataType[] = [ + { + amount: '+$4,650', + subtitle: 'Sell UI Kit', + title: 'Gumroad Account', + logo: '/images/cards/gumroad.png' + }, + { + amount: '+$92,705', + title: 'Mastercard', + subtitle: 'Wallet deposit', + logo: '/images/logos/mastercard.png' + }, + { + amount: '+$957', + title: 'Stripe Account', + subtitle: 'iOS Application', + logo: '/images/logos/stripe.png' + }, + { + amount: '+$6,837', + title: 'American Bank', + subtitle: 'Bank Transfer', + logo: '/images/logos/american-bank.png' + }, + { + amount: '+$446', + title: 'Bank Account', + subtitle: 'Wallet deposit', + logo: '/images/logos/citi-bank.png' + } +] + +const withdrawData = [ + { + amount: '-$145', + title: 'Google Adsense', + subtitle: 'Paypal deposit', + logo: '/images/logos/google.png' + }, + { + amount: '-$1870', + title: 'Github Enterprise', + logo: '/images/logos/github.png', + subtitle: 'Security & compliance' + }, + { + amount: '-$450', + title: 'Upgrade Slack Plan', + subtitle: 'Debit card deposit', + logo: '/images/logos/slack.png' + }, + { + amount: '-$540', + title: 'Digital Ocean', + subtitle: 'Cloud Hosting', + logo: '/images/logos/digital-ocean.png' + }, + { + amount: '-$21', + title: 'AWS Account', + logo: '/images/logos/aws.png', + subtitle: 'Choosing a Cloud Platform' + } +] + +const DepositWithdraw = () => { + return ( + + + + + Ver todas + + } + /> + + {depositData.map((item, index) => ( +
    + {item.title} +
    +
    + + {item.title} + + {item.subtitle} +
    + + {item.amount} + +
    +
    + ))} +
    +
    + + + View All + + } + /> + + {withdrawData.map((item, index) => ( +
    + {item.title} +
    +
    + + {item.title} + + {item.subtitle} +
    + + {item.amount} + +
    +
    + ))} +
    +
    +
    +
    + ) +} + +export default DepositWithdraw diff --git a/front-urban/src/views/dashboard/DialogAccessLogs.tsx b/front-urban/src/views/dashboard/DialogAccessLogs.tsx new file mode 100644 index 0000000..12816e5 --- /dev/null +++ b/front-urban/src/views/dashboard/DialogAccessLogs.tsx @@ -0,0 +1,138 @@ +'use client' + +import { useEffect, useMemo, useState } from 'react' +import dayjs from 'dayjs' +import CustomDialog from '@/utils/CustomDialog' +import { MaterialReactTable, type MRT_ColumnDef } from 'material-react-table' +import { MRT_Localization_ES } from 'material-react-table/locales/es' +import { + Box, + Chip, + Stack, + Typography, + TextField +} from '@mui/material' +import { useAccessLogs, type AccessLog } from '@/@core/hooks/useAccessLogs' +import { DIALOG_INFO } from '@/configs/dialogInfoContent' + +type Props = { + userId: string | null + userName: string + open: boolean + onClose: () => void +} + +const DialogAccessLogs = ({ userId, userName, open, onClose }: Props) => { + const [selectedDate, setSelectedDate] = useState(() => dayjs().format('YYYY-MM-DD')) + + const { data, loading, error } = useAccessLogs(userId || undefined, selectedDate, open && !!userId) + + // Reset fecha al cerrar + useEffect(() => { + if (!open) { + setSelectedDate(dayjs().format('YYYY-MM-DD')) + } + }, [open]) + + const columns = useMemo[]>(() => [ + { + header: 'Tipo', + accessorKey: 'direction', + size: 15, + Cell: ({ cell }) => { + const direction = cell.getValue<'INGRESS' | 'EGRESS'>() + const label = direction === 'INGRESS' ? 'Ingreso' : 'Egreso' + const color = direction === 'INGRESS' ? 'success' : 'warning' + return ( + + ) + }, + filterVariant: 'select', + filterSelectOptions: [ + { label: 'Ingreso', value: 'INGRESS' }, + { label: 'Egreso', value: 'EGRESS' } + ] + }, + { + header: 'Fecha y Hora', + accessorKey: 'timestamp', + size: 20, + Cell: ({ cell }) => { + const timestamp = cell.getValue() + return dayjs(timestamp).format('DD/MM/YYYY HH:mm') + } + } + ], []) + + return ( + + + + setSelectedDate(e.target.value)} + InputLabelProps={{ shrink: true }} + fullWidth + size="small" + /> + + + + Registros de ingreso y egreso de {data?.name || userName} para el día seleccionado. + + + + + columns={columns} + data={data?.accessLogs || []} + state={{ isLoading: loading, showAlertBanner: !!error }} + enableColumnFilters + enableGlobalFilter={false} + enableDensityToggle + enableHiding={false} + localization={MRT_Localization_ES} + muiToolbarAlertBannerProps={ + error ? { color: 'error', children: error } : undefined + } + muiPaginationProps={{ + rowsPerPageOptions: [10, 25, 50], + showFirstButton: true, + showLastButton: true, + SelectProps: { + native: false, + sx: { + '& .MuiSelect-select': { + paddingRight: '32px !important', + }, + '& .MuiSelect-icon': { + right: '4px', + } + } + }, + }} + initialState={{ + sorting: [{ id: 'timestamp', desc: false }], + pagination: { pageSize: 10, pageIndex: 0 } + }} + /> + + + + ) +} + +export default DialogAccessLogs diff --git a/front-urban/src/views/dashboard/DialogAttendanceSnapshot.tsx b/front-urban/src/views/dashboard/DialogAttendanceSnapshot.tsx new file mode 100644 index 0000000..7a9e78d --- /dev/null +++ b/front-urban/src/views/dashboard/DialogAttendanceSnapshot.tsx @@ -0,0 +1,301 @@ +'use client' + +import { useEffect, useMemo, useState } from 'react' +import apiClient from '@/lib/apiClient' +import dayjs from 'dayjs' +import CustomDialog from '@/utils/CustomDialog' +import { useUserAuth } from '@/app/context/UserAuth' + +import { MaterialReactTable, type MRT_ColumnDef } from 'material-react-table' +import { MRT_Localization_ES } from 'material-react-table/locales/es' +import { + Box, + Chip, + IconButton, + Stack, + Typography, + Tooltip, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + Button +} from '@mui/material' +import HowToRegIcon from '@mui/icons-material/HowToReg' +import HistoryIcon from '@mui/icons-material/History' +import { Snapshot } from '../clases/FechasProgramadasAccordion' +import { useAttendeesSnapshot } from '@/@core/hooks/useAttendeesSnapshot' +import { DIALOG_INFO } from '@/configs/dialogInfoContent' +import DialogAccessLogs from './DialogAccessLogs' + +type Props = { + snapshot: Snapshot | null + open: boolean + onClose: () => void +} + +type RowUser = { + id: string + name: string + role: 'instructor' | 'assistant' +} + +const DialogAttendanceSnapshot = ({ snapshot, open, onClose }: Props) => { + const { token } = useUserAuth() + + // usa el hook + const { data, loading, error, refresh } = useAttendeesSnapshot(snapshot?.id, open) + + const [rows, setRows] = useState([]) + const [attendedSet, setAttendedSet] = useState>(new Set()) + const [savingSet, setSavingSet] = useState>(new Set()) + const [confirmState, setConfirmState] = useState<{ userId: string | null; isAttended: boolean }>(() => ({ userId: null, isAttended: false })) + + // Estado para el diálogo de logs de acceso + const [accessLogsState, setAccessLogsState] = useState<{ open: boolean; userId: string | null; userName: string }>({ + open: false, + userId: null, + userName: '' + }) + + const titleDate = useMemo( + () => + (data?.dateRange?.start + ? dayjs(data.dateRange.start).format('DD-MM HH:mm') + : '—'), + [data] + ) + + // reset locales al cerrar + useEffect(() => { + if (!open) { + setAttendedSet(new Set()) + setSavingSet(new Set()) + setRows([]) + setAccessLogsState({ open: false, userId: null, userName: '' }) + } + }, [open]) + + // hidratar filas y asistencias desde la data del hook + useEffect(() => { + if (!data) return + const merged: RowUser[] = [ + ...data.instructors.map(i => ({ ...i, role: 'instructor' as const })), + ...data.assistants.map(a => ({ ...a, role: 'assistant' as const })) + ].sort((a, b) => a.name.localeCompare(b.name)) + + setRows(merged) + setAttendedSet(new Set((data.attendance ?? []).map(a => a.id))) + }, [data]) + + const markAttendance = (userId: string) => { + if (!snapshot?.id) return + const isAttended = attendedSet.has(userId) + setConfirmState({ userId, isAttended }) + } + + const openAccessLogs = (userId: string, userName: string) => { + setAccessLogsState({ open: true, userId, userName }) + } + + const closeAccessLogs = () => { + setAccessLogsState({ open: false, userId: null, userName: '' }) + } + + const confirmAttendanceChange = async () => { + const userId = confirmState.userId + if (!userId || !snapshot?.id) return + const isAttended = confirmState.isAttended + + setSavingSet(prev => new Set(prev).add(userId)) + + try { + const base = `/attendance/${userId}/${snapshot.id}` + const url = isAttended ? `${base}?unmark=true` : base + await apiClient.put(url, null) + // optimista + sync con backend + setAttendedSet(prev => { + const next = new Set(prev) + if (isAttended) next.delete(userId) + else next.add(userId) + return next + }) + refresh() + } finally { + setSavingSet(prev => { + const next = new Set(prev) + next.delete(userId) + return next + }) + setConfirmState({ userId: null, isAttended: false }) + } + } + + const columns = useMemo[]>(() => [ + { + header: 'Nombre', + accessorKey: 'name', + size: 15 + }, + { + header: 'Presencia', + id: 'presence', + size: 12, + Cell: ({ row }) => { + const present = attendedSet.has(row.original.id) + return ( + + ) + }, + enableSorting: false, + enableColumnFilter: false, + }, + { + header: 'Rol', + accessorKey: 'role', + size: 15, + Cell: ({ cell }) => { + const role = cell.getValue<'instructor' | 'assistant'>() + const label = role === 'instructor' ? 'Instructor' : 'Asistente' + return ( + + ) + }, + filterVariant: 'select', + filterSelectOptions: [ + { label: 'Instructor', value: 'instructor' }, + { label: 'Asistente', value: 'assistant' } + ] + }, + { + header: 'Acciones', + id: 'acciones', + enableSorting: false, + enableColumnFilter: false, + size: 15, + Cell: ({ row }) => { + const userId = row.original.id + const userName = row.original.name + const attended = attendedSet.has(userId) + const saving = savingSet.has(userId) + + return ( + + + + markAttendance(userId)} + size="small" + color={attended ? 'success' : 'default'} + disabled={saving} + > + + + + + + openAccessLogs(userId, userName)} + size="small" + color="primary" + > + + + + + ) + } + } + ], [attendedSet, savingSet]) + + return ( + + + + Listado de instructores y asistentes de la clase. + + + + + columns={columns} + data={rows} + state={{ isLoading: loading, showAlertBanner: !!error }} + enableColumnFilters + enableGlobalFilter + enableDensityToggle + enableHiding={false} + localization={MRT_Localization_ES} + muiToolbarAlertBannerProps={ + error ? { color: 'error', children: error } : undefined + } + muiPaginationProps={{ + rowsPerPageOptions: [10, 50], + showFirstButton: true, + showLastButton: true, + SelectProps: { + native: false, + sx: { + '& .MuiSelect-select': { + paddingRight: '32px !important', + }, + '& .MuiSelect-icon': { + right: '4px', + } + } + }, + }} + /> + + + + {/* Confirmación de asistencia */} + setConfirmState({ userId: null, isAttended: false })}> + {confirmState.isAttended ? 'Desmarcar asistencia' : 'Marcar asistencia'} + + + {confirmState.isAttended + ? '¿Confirma que desea desmarcar la asistencia de este usuario?' + : '¿Confirma que desea marcar la asistencia de este usuario?'} + + + + + + + + + {/* Diálogo de logs de acceso */} + + + ) +} + +export default DialogAttendanceSnapshot diff --git a/front-urban/src/views/dashboard/DistributedColumnChart.tsx b/front-urban/src/views/dashboard/DistributedColumnChart.tsx new file mode 100644 index 0000000..d86fbdb --- /dev/null +++ b/front-urban/src/views/dashboard/DistributedColumnChart.tsx @@ -0,0 +1,114 @@ +'use client' + +// Next Imports +import dynamic from 'next/dynamic' + +//MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import { useTheme } from '@mui/material/styles' + +// Third-party Imports +import type { ApexOptions } from 'apexcharts' + +// Styled Component Imports +const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts')) + +// Vars +const series = [ + { + name: '2022', + data: [45, 85, 65, 50, 70] + } +] + +const DistributedColumnChart = () => { + // Hooks + const theme = useTheme() + + // Vars + const primaryColor = 'var(--mui-palette-primary-main)' + const errorColor = 'var(--mui-palette-error-main)' + const trackBgColor = 'var(--mui-palette-customColors-trackBg)' + + const options: ApexOptions = { + chart: { + type: 'bar', + stacked: false, + parentHeightOffset: 0, + toolbar: { show: false } + }, + tooltip: { + x: { show: false } + }, + grid: { + show: false, + padding: { + top: -10, + left: -3, + right: -2, + bottom: 5 + } + }, + legend: { show: false }, + dataLabels: { enabled: false }, + colors: [errorColor, primaryColor, errorColor, primaryColor, primaryColor], + plotOptions: { + bar: { + horizontal: false, + columnWidth: '24%', + borderRadius: 4, + borderRadiusApplication: 'around', + borderRadiusWhenStacked: 'all', + distributed: true, + colors: { + backgroundBarRadius: 5, + backgroundBarColors: [trackBgColor, trackBgColor, trackBgColor, trackBgColor, trackBgColor] + } + } + }, + xaxis: { + labels: { show: false }, + axisTicks: { show: false }, + axisBorder: { show: false } + }, + yaxis: { show: false }, + responsive: [ + { + breakpoint: 900, + options: { + plotOptions: { + bar: { + columnWidth: '18%' + } + } + } + }, + { + breakpoint: theme.breakpoints.values.sm, + options: { + plotOptions: { + bar: { + columnWidth: '12%' + } + } + } + } + ] + } + + return ( + + + 2,856 + + + Sessions + + + + ) +} + +export default DistributedColumnChart diff --git a/front-urban/src/views/dashboard/LineChart.tsx b/front-urban/src/views/dashboard/LineChart.tsx new file mode 100644 index 0000000..3744648 --- /dev/null +++ b/front-urban/src/views/dashboard/LineChart.tsx @@ -0,0 +1,90 @@ +'use client' + +// Next Imports +import dynamic from 'next/dynamic' + +//MUI Imports +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' + +import type { ApexOptions } from 'apexcharts' + +// Styled Component Imports +const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts')) + +// Vars +const series = [{ data: [0, 20, 5, 30, 15, 45] }] + +const LineChart = () => { + const primaryColor = 'var(--mui-palette-primary-main)' + + const options: ApexOptions = { + chart: { + parentHeightOffset: 0, + toolbar: { show: false } + }, + tooltip: { enabled: false }, + grid: { + strokeDashArray: 6, + borderColor: 'var(--mui-palette-divider)', + xaxis: { + lines: { show: true } + }, + yaxis: { + lines: { show: false } + }, + padding: { + top: -10, + left: -7, + right: 5, + bottom: 5 + } + }, + stroke: { + width: 3, + lineCap: 'butt', + curve: 'straight' + }, + colors: [primaryColor], + markers: { + size: 6, + offsetY: 4, + offsetX: -2, + strokeWidth: 3, + colors: ['transparent'], + strokeColors: 'transparent', + discrete: [ + { + size: 5.5, + seriesIndex: 0, + strokeColor: primaryColor, + fillColor: 'var(--mui-palette-background-paper)', + dataPointIndex: series[0].data.length - 1 + } + ] + }, + xaxis: { + labels: { show: false }, + axisTicks: { show: false }, + axisBorder: { show: false } + }, + yaxis: { + labels: { show: false } + } + } + + return ( + + + $86.4k + + + Total Profit + + + + ) +} + +export default LineChart diff --git a/front-urban/src/views/dashboard/SalesByCountries.tsx b/front-urban/src/views/dashboard/SalesByCountries.tsx new file mode 100644 index 0000000..f91366b --- /dev/null +++ b/front-urban/src/views/dashboard/SalesByCountries.tsx @@ -0,0 +1,125 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' + +// Third-party Imports +import classnames from 'classnames' + +// Type Imports +import type { ThemeColor } from '@core/types' + +// Components Imports +import OptionMenu from '@core/components/option-menu' +import CustomAvatar from '@core/components/mui/Avatar' + +type DataType = { + avatarLabel: string + avatarColor?: ThemeColor + title: string + subtitle: string + sales: string + trend: 'up' | 'down' + trendPercentage: string +} + +// Vars +const data: DataType[] = [ + { + avatarLabel: 'US', + avatarColor: 'success', + title: '$8,656k', + subtitle: 'United states of america', + sales: '894k', + trend: 'up', + trendPercentage: '25.8%' + }, + { + avatarLabel: 'UK', + avatarColor: 'error', + title: '$2,415k', + subtitle: 'United kingdom', + sales: '645k', + trend: 'down', + trendPercentage: '6.2%' + }, + { + avatarLabel: 'IN', + avatarColor: 'warning', + title: '$865k', + subtitle: 'India', + sales: '148k', + trend: 'up', + trendPercentage: '12.4%' + }, + { + avatarLabel: 'JA', + avatarColor: 'secondary', + title: '$745k', + subtitle: 'Japan', + sales: '86k', + trend: 'down', + trendPercentage: '11.9%' + }, + { + avatarLabel: 'KO', + avatarColor: 'error', + title: '$45k', + subtitle: 'Korea', + sales: '42k', + trend: 'up', + trendPercentage: '16.2%' + } +] + +const SalesByCountries = () => { + return ( + + } + /> + + {data.map((item, index) => ( +
    + + {item.avatarLabel} + +
    +
    +
    + + {item.title} + +
    + + + {item.trendPercentage} + +
    +
    + {item.subtitle} +
    +
    + + {item.sales} + + + Sales + +
    +
    +
    + ))} +
    +
    + ) +} + +export default SalesByCountries diff --git a/front-urban/src/views/dashboard/Table.tsx b/front-urban/src/views/dashboard/Table.tsx new file mode 100644 index 0000000..349cfbf --- /dev/null +++ b/front-urban/src/views/dashboard/Table.tsx @@ -0,0 +1,164 @@ +// MUI Imports +import Typography from '@mui/material/Typography' +import Card from '@mui/material/Card' +import Chip from '@mui/material/Chip' + +// Third-party Imports +import classnames from 'classnames' + +// Components Imports +import CustomAvatar from '@core/components/mui/Avatar' + +// Styles Imports +import tableStyles from '@core/styles/table.module.css' + +type TableBodyRowType = { + avatarSrc?: string + name: string + username: string + email: string + iconClass: string + roleIcon?: string + role: string + status: string +} + +// Vars +const rowsData: TableBodyRowType[] = [ + { + avatarSrc: '/images/avatars/1.png', + name: 'Jordan Stevenson', + username: '@amiccoo', + email: 'Jacinthe_Blick@hotmail.com', + iconClass: 'text-primary', + roleIcon: 'ri-vip-crown-line', + role: 'Admin', + status: 'pending' + }, + { + avatarSrc: '/images/avatars/2.png', + name: 'Richard Payne', + username: '@brossiter15', + email: 'Jaylon_Bartell3@gmail.com', + iconClass: 'text-warning', + roleIcon: 'ri-edit-box-line', + role: 'Editor', + status: 'active' + }, + { + avatarSrc: '/images/avatars/3.png', + name: 'Jennifer Summers', + username: '@jsbemblinf', + email: 'Tristin_Johnson@gmail.com', + iconClass: 'text-error', + roleIcon: 'ri-computer-line', + role: 'Author', + status: 'active' + }, + { + avatarSrc: '/images/avatars/4.png', + name: 'Mr. Justin Richardson', + username: '@justin45', + email: 'Toney21@yahoo.com', + iconClass: 'text-warning', + roleIcon: 'ri-edit-box-line', + role: 'Editor', + status: 'pending' + }, + { + avatarSrc: '/images/avatars/5.png', + name: 'Nicholas Tanner', + username: '@tannernic', + email: 'Hunter_Kuhic68@hotmail.com', + iconClass: 'text-info', + roleIcon: 'ri-pie-chart-2-line', + role: 'Maintainer', + status: 'active' + }, + { + avatarSrc: '/images/avatars/6.png', + name: 'Crystal Mays', + username: '@crystal99', + email: 'Norene_Bins@yahoo.com', + iconClass: 'text-warning', + roleIcon: 'ri-edit-box-line', + role: 'Editor', + status: 'pending' + }, + { + avatarSrc: '/images/avatars/7.png', + name: 'Mary Garcia', + username: '@marygarcia4', + email: 'Emmitt.Walker14@hotmail.com', + iconClass: 'text-info', + roleIcon: 'ri-pie-chart-2-line', + role: 'Maintainer', + status: 'inactive' + }, + { + avatarSrc: '/images/avatars/8.png', + name: 'Megan Roberts', + username: '@megan78', + email: 'Patrick.Howe73@gmail.com', + iconClass: 'text-success', + roleIcon: 'ri-user-3-line', + role: 'Subscriber', + status: 'active' + } +] + +const Table = () => { + return ( + +
    + + + + + + + + + + + {rowsData.map((row, index) => ( + + + + + + + ))} + +
    UserEmailRoleStatus
    +
    + +
    + + {row.name} + + {row.username} +
    +
    +
    + {row.email} + +
    + + {row.role} +
    +
    + +
    +
    +
    + ) +} + +export default Table diff --git a/front-urban/src/views/dashboard/TotalEarning.tsx b/front-urban/src/views/dashboard/TotalEarning.tsx new file mode 100644 index 0000000..862a658 --- /dev/null +++ b/front-urban/src/views/dashboard/TotalEarning.tsx @@ -0,0 +1,101 @@ +// MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Avatar from '@mui/material/Avatar' +import LinearProgress from '@mui/material/LinearProgress' + +import Typography from '@mui/material/Typography' + +// Type Imports +import type { ThemeColor } from '@core/types' + +// Components Imports +import OptionMenu from '@core/components/option-menu' + +type DataType = { + title: string + imgSrc: string + amount: string + progress: number + subtitle: string + color?: ThemeColor +} + +// Vars +const data: DataType[] = [ + { + progress: 75, + title: 'Zipcar', + amount: '$24,895.65', + subtitle: 'Vuejs, React & HTML', + imgSrc: '/images/cards/zipcar.png' + }, + { + progress: 50, + color: 'info', + title: 'Bitbank', + amount: '$8,650.20', + subtitle: 'Sketch, Figma & XD', + imgSrc: '/images/cards/bitbank.png' + }, + { + progress: 20, + title: 'Aviato', + color: 'secondary', + amount: '$1,245.80', + subtitle: 'HTML & Angular', + imgSrc: '/images/cards/aviato.png' + } +] + +const TotalEarning = () => { + return ( + + } + > + +
    +
    + $24,895 + + + 10% + +
    + Compared to $84,325 last year +
    +
    + {data.map((item, index) => ( +
    + +
    +
    + + {item.title} + + {item.subtitle} +
    +
    + + {item.amount} + + +
    +
    +
    + ))} +
    +
    +
    + ) +} + +export default TotalEarning diff --git a/front-urban/src/views/dashboard/Transactions.tsx b/front-urban/src/views/dashboard/Transactions.tsx new file mode 100644 index 0000000..76fcd63 --- /dev/null +++ b/front-urban/src/views/dashboard/Transactions.tsx @@ -0,0 +1,84 @@ +//MUI Imports +import Card from '@mui/material/Card' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import Grid from '@mui/material/Grid' + +// Type Imports +import type { ThemeColor } from '@core/types' + +// Components Imports +import OptionMenu from '@core/components/option-menu' +import CustomAvatar from '@core/components/mui/Avatar' + +type DataType = { + icon: string + stats: string + title: string + color: ThemeColor +} + +// Vars +const data: DataType[] = [ + { + stats: '245k', + title: 'Sales', + color: 'primary', + icon: 'ri-pie-chart-2-line' + }, + { + stats: '12.5k', + title: 'Users', + color: 'success', + icon: 'ri-group-line' + }, + { + stats: '1.54k', + color: 'warning', + title: 'Products', + icon: 'ri-macbook-line' + }, + { + stats: '$88k', + color: 'info', + title: 'Revenue', + icon: 'ri-money-dollar-circle-line' + } +] + +const Transactions = () => { + return ( + + } + subheader={ +

    + Total 48.5% Growth 😎 + this month +

    + } + /> + + + {data.map((item, index) => ( + +
    + + + +
    + {item.title} + {item.stats} +
    +
    +
    + ))} +
    +
    +
    + ) +} + +export default Transactions diff --git a/front-urban/src/views/dashboard/WeeklyOverview.tsx b/front-urban/src/views/dashboard/WeeklyOverview.tsx new file mode 100644 index 0000000..4f7f806 --- /dev/null +++ b/front-urban/src/views/dashboard/WeeklyOverview.tsx @@ -0,0 +1,116 @@ +'use client' + +// Next Imports +import dynamic from 'next/dynamic' + +// MUI Imports +import Card from '@mui/material/Card' +import Button from '@mui/material/Button' +import { useTheme } from '@mui/material/styles' +import CardHeader from '@mui/material/CardHeader' +import Typography from '@mui/material/Typography' +import CardContent from '@mui/material/CardContent' + +// Third Party Imports +import type { ApexOptions } from 'apexcharts' + +// Components Imports +import OptionsMenu from '@core/components/option-menu' + +// Styled Component Imports +const AppReactApexCharts = dynamic(() => import('@/libs/styles/AppReactApexCharts')) + +const WeeklyOverview = () => { + // Hooks + const theme = useTheme() + + // Vars + const divider = 'var(--mui-palette-divider)' + const disabled = 'var(--mui-palette-text-disabled)' + + const options: ApexOptions = { + chart: { + parentHeightOffset: 0, + toolbar: { show: false } + }, + plotOptions: { + bar: { + borderRadius: 7, + distributed: true, + columnWidth: '40%' + } + }, + stroke: { + width: 2, + colors: ['var(--mui-palette-background-paper)'] + }, + legend: { show: false }, + grid: { + xaxis: { lines: { show: false } }, + strokeDashArray: 7, + padding: { left: -9, top: -20, bottom: 13 }, + borderColor: divider + }, + dataLabels: { enabled: false }, + colors: [ + 'var(--mui-palette-customColors-trackBg)', + 'var(--mui-palette-customColors-trackBg)', + 'var(--mui-palette-customColors-trackBg)', + 'var(--mui-palette-primary-main)', + 'var(--mui-palette-customColors-trackBg)', + 'var(--mui-palette-customColors-trackBg)' + ], + states: { + hover: { + filter: { type: 'none' } + }, + active: { + filter: { type: 'none' } + } + }, + xaxis: { + categories: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + tickPlacement: 'on', + labels: { show: false }, + axisTicks: { show: false }, + axisBorder: { show: false } + }, + yaxis: { + show: true, + tickAmount: 4, + labels: { + offsetY: 2, + offsetX: -17, + style: { colors: disabled, fontSize: theme.typography.body2.fontSize as string }, + formatter: value => `${value > 999 ? `${(value / 1000).toFixed(0)}` : value}k` + } + } + } + + return ( + + } + /> + + +
    + 45% + Your sales performance is 45% 😎 better compared to last month +
    + +
    +
    + ) +} + +export default WeeklyOverview diff --git a/front-urban/src/views/form-layouts/FormLayoutsAlignment.tsx b/front-urban/src/views/form-layouts/FormLayoutsAlignment.tsx new file mode 100644 index 0000000..6e441c1 --- /dev/null +++ b/front-urban/src/views/form-layouts/FormLayoutsAlignment.tsx @@ -0,0 +1,76 @@ +'use client' + +// React Imports +import { useState } from 'react' + +// MUI Imports +import Card from '@mui/material/Card' +import Grid from '@mui/material/Grid' +import Button from '@mui/material/Button' +import TextField from '@mui/material/TextField' +import Typography from '@mui/material/Typography' +import Checkbox from '@mui/material/Checkbox' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import FormControlLabel from '@mui/material/FormControlLabel' +import InputAdornment from '@mui/material/InputAdornment' +import IconButton from '@mui/material/IconButton' + +const FormLayoutsAlignment = () => { + // States + const [isPasswordShown, setIsPasswordShown] = useState(false) + + const handleClickShowPassword = () => setIsPasswordShown(show => !show) + + return ( + + + +
    e.preventDefault()} className='p-12 max-is-[400px] border rounded'> + + + Sign In + + + + + + + e.preventDefault()} + aria-label='toggle password visibility' + > + + + + ) + }} + /> + + + } label='Remember me' /> + + + + + + +
    +
    + ) +} + +export default FormLayoutsAlignment diff --git a/front-urban/src/views/form-layouts/FormLayoutsBasic.tsx b/front-urban/src/views/form-layouts/FormLayoutsBasic.tsx new file mode 100644 index 0000000..413ce13 --- /dev/null +++ b/front-urban/src/views/form-layouts/FormLayoutsBasic.tsx @@ -0,0 +1,117 @@ +'use client' + +// React Imports +import { useState } from 'react' + +// Next Imports +import Link from 'next/link' + +// MUI Imports +import Card from '@mui/material/Card' +import Grid from '@mui/material/Grid' +import Button from '@mui/material/Button' +import TextField from '@mui/material/TextField' +import Typography from '@mui/material/Typography' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import IconButton from '@mui/material/IconButton' +import InputAdornment from '@mui/material/InputAdornment' + +const FormLayoutsBasic = () => { + // States + const [isPasswordShown, setIsPasswordShown] = useState(false) + const [isConfirmPasswordShown, setIsConfirmPasswordShown] = useState(false) + + const handleClickShowPassword = () => setIsPasswordShown(show => !show) + + const handleClickShowConfirmPassword = () => setIsConfirmPasswordShown(show => !show) + + return ( + + + +
    e.preventDefault()}> + + + + + + + + + + e.preventDefault()} + aria-label='toggle password visibility' + > + + + + ) + }} + /> + + + + e.preventDefault()} + aria-label='toggle confirm password visibility' + > + + + + ) + }} + /> + + +
    + +
    + Already have an account? + e.preventDefault()} className='text-primary'> + Log In + +
    +
    +
    +
    + +
    +
    + ) +} + +export default FormLayoutsBasic diff --git a/front-urban/src/views/form-layouts/FormLayoutsIcons.tsx b/front-urban/src/views/form-layouts/FormLayoutsIcons.tsx new file mode 100644 index 0000000..f523de7 --- /dev/null +++ b/front-urban/src/views/form-layouts/FormLayoutsIcons.tsx @@ -0,0 +1,92 @@ +// MUI Imports +import Card from '@mui/material/Card' +import Grid from '@mui/material/Grid' +import Button from '@mui/material/Button' +import TextField from '@mui/material/TextField' +import CardHeader from '@mui/material/CardHeader' +import CardContent from '@mui/material/CardContent' +import InputAdornment from '@mui/material/InputAdornment' + +// Component Imports +import Form from '@components/Form' + +const FormLayoutsWithIcon = () => { + return ( + + + +
    + + + + + + ) + }} + /> + + + + + + ) + }} + /> + + + + + + ) + }} + /> + + + + + + ) + }} + /> + + + + + + +
    +
    + ) +} + +export default FormLayoutsWithIcon diff --git a/front-urban/src/views/pages/misc/UnderMaintenance.tsx b/front-urban/src/views/pages/misc/UnderMaintenance.tsx new file mode 100644 index 0000000..0a81cc6 --- /dev/null +++ b/front-urban/src/views/pages/misc/UnderMaintenance.tsx @@ -0,0 +1,48 @@ +'use client' + +// Next Imports +import Link from 'next/link' + +// MUI Imports +import Button from '@mui/material/Button' +import Typography from '@mui/material/Typography' + +// Type Imports +import type { Mode } from '@core/types' + +// Component Imports +import Illustrations from '@components/Illustrations' + +// Hook Imports +import { useImageVariant } from '@core/hooks/useImageVariant' + +const UnderMaintenance = ({ mode }: { mode: Mode }) => { + // Vars + const darkImg = '/images/pages/misc-mask-dark.png' + const lightImg = '/images/pages/misc-mask-light.png' + + // Hooks + const miscBackground = useImageVariant(mode, lightImg, darkImg) + + return ( +
    +
    +
    + Under Maintenance! 🚧 + Sorry for the inconvenience but we're performing some maintenance at the moment +
    + error-illustration + +
    + +
    + ) +} + +export default UnderMaintenance diff --git a/front-urban/src/views/usuarios/DetailUsuarioDialog.tsx b/front-urban/src/views/usuarios/DetailUsuarioDialog.tsx new file mode 100644 index 0000000..a9bb9a2 --- /dev/null +++ b/front-urban/src/views/usuarios/DetailUsuarioDialog.tsx @@ -0,0 +1,146 @@ +'use client'; + +import { useUserAuth } from '@/app/context/UserAuth'; +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Grid, + List, + ListItem, + ListItemText, + Typography +} from '@mui/material'; +import apiClient from '@/lib/apiClient'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { Usuario } from './usuarios.dto'; + +type ClaseUsuario = { + id: string; + title: string; + startDate?: string | null; + endDate?: string | null; +}; + +type Props = { + open: boolean; + onClose: () => void; + usuario: Usuario | null; +}; + +const fmtDate = (iso?: string | null) => { + if (!iso) return '—'; + const d = new Date(iso); + return isNaN(+d) ? '—' : d.toLocaleString('es-AR'); +}; + +export const DetailUsuarioDialog = ({ + open, + onClose, + usuario, +}: Props) => { + const { token } = useUserAuth() + + const [expanded, setExpanded] = useState(false); + const [loadingClases, setLoadingClases] = useState(false); + const [clases, setClases] = useState([]); + const isInstructor = usuario?.role === 'INSTRUCTOR'; + + useEffect(() => { + if (!open) { + setExpanded(false); + setClases([]); + setLoadingClases(false); + } + }, [open]); + + const fetchClases = useCallback(async () => { + if (!usuario?.id) return; + setLoadingClases(true); + try { + const { data } = await apiClient.get(`/users/${usuario.id}/classes`); + setClases(data ?? []); + } catch (e) { + console.error('Error al obtener clases del usuario', e); + } finally { + setLoadingClases(false); + } + }, [usuario?.id]); + + const handleAccordionChange = async (_: any, isOpen: boolean) => { + setExpanded(isOpen); + if (isOpen && clases.length === 0 && !loadingClases) { + await fetchClases(); + } + }; + + const details = useMemo(() => { + if (!usuario) return []; + return [ + { label: 'ID (custom)', value: usuario.customId || '—' }, + { label: 'Nombre', value: usuario.name || '—' }, + { label: 'DNI', value: usuario.dni || '—' }, + { label: 'Teléfono', value: usuario.phone || '—' }, + { label: 'Nacimiento', value: usuario.birth ? new Date(usuario.birth).toLocaleDateString('es-AR') : '—' }, + { label: 'RFID', value: usuario.rfid || '—' }, + { label: 'Rol', value: usuario.role || '—' }, + ]; + }, [usuario]); + + if (!usuario) return null; + + return ( + + Detalle del usuario + + + {details.map(({ label, value }) => ( + + + {label} + + {value} + + ))} + + + {isInstructor && ( + + }> + Clases del usuario + + + {loadingClases ? ( + Cargando clases… + ) : clases.length === 0 ? ( + No se encontraron clases. + ) : ( + + {clases.map((c) => ( + + + + ))} + + )} + + + )} + + + + + + ); +}; + +export default DetailUsuarioDialog; diff --git a/front-urban/src/views/usuarios/InvoiceUserDialog.tsx b/front-urban/src/views/usuarios/InvoiceUserDialog.tsx new file mode 100644 index 0000000..e389b1c --- /dev/null +++ b/front-urban/src/views/usuarios/InvoiceUserDialog.tsx @@ -0,0 +1,346 @@ +'use client'; +import { downloadInvoicePdf } from '@/@core/hooks/downloadInvoicePdf'; +import { InvoiceStatus, InvoiceWithDescription, useInvoices } from '@/@core/hooks/useInvoices'; +import { useUpdateInvoiceStatus } from '@/@core/hooks/useUpdateInvoiceStatus'; +import { useUserAuth } from '@/app/context/UserAuth'; +import CustomDialog from '@/utils/CustomDialog'; +import DownloadIcon from '@mui/icons-material/Download'; +import EditIcon from '@mui/icons-material/Edit'; +import { + Alert, + Box, + Button, + Chip, + ClickAwayListener, + Grow, + IconButton, + Paper, + Portal, + Snackbar, + Typography +} from '@mui/material'; +import { MaterialReactTable, MRT_ColumnDef } from 'material-react-table'; +import { MRT_Localization_ES } from 'material-react-table/locales/es'; +import { useMemo, useState } from 'react'; +import { Usuario } from './usuarios.dto'; + +type Props = { + open: boolean; + usuario: Usuario | null; + onClose: () => void; + onRefresh: () => Promise; +}; + +export const InvoiceUserDialog = ({ open, usuario, onClose, onRefresh }: Props) => { + + const { token } = useUserAuth(); + const { data, loading, error, refresh } = useInvoices(usuario?.id ?? '', { auto: open }); + + // Estado para controlar qué factura tiene el diálogo de acciones abierto + const [openActionDialog, setOpenActionDialog] = useState(null); + + // Estados para el Snackbar + const [snackbar, setSnackbar] = useState<{ + open: boolean; + message: string; + severity: 'success' | 'error'; + }>({ + open: false, + message: '', + severity: 'success' + }); + + // Hook para actualizar el estado de la factura + const { mutate: updateInvoiceStatus, loading: updating } = useUpdateInvoiceStatus({ + onSuccess: async () => { + setSnackbar({ + open: true, + message: 'Factura actualizada exitosamente', + severity: 'success' + }); + await refresh(); + }, + onError: (error: any) => { + setSnackbar({ + open: true, + message: error?.response?.data?.message || 'Error al actualizar la factura', + severity: 'error' + }); + } + }); + + // Función para cambiar el estado de la factura + const handleUpdateInvoiceStatus = async (invoiceId: string, newStatus: 'PAID' | 'CANCELED') => { + if (!usuario?.id) return; + + try { + await updateInvoiceStatus({ + userId: usuario.id, + invoiceId, + status: newStatus + }); + } catch (error) { + // El error ya se maneja en onError del hook + console.error('Error al actualizar factura:', error); + } + }; + + // Función para cerrar el Snackbar + const handleCloseSnackbar = () => { + setSnackbar(prev => ({ ...prev, open: false })); + }; + + // Función para obtener el mes y año en formato "Mes/AAAA" + const getMonthYear = (dateString: string) => { + const date = new Date(dateString); + const months = [ + 'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', + 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre' + ]; + const month = months[date.getMonth()]; + const year = date.getFullYear(); + return `${month}/${year}`; + }; + + // Componente simplificado para el botón de editar + const ActionButton = ({ invoice }: { invoice: InvoiceWithDescription }) => { + const isOpen = openActionDialog === invoice.id; + const isDisabled = invoice.status === 'PAID' || invoice.status === 'CANCELED'; + + const handleClick = () => { + if (isDisabled) return; + setOpenActionDialog(isOpen ? null : invoice.id); + }; + + return ( + + + + ); + }; const columns = useMemo[]>(() => [ + { + header: 'Estado', + accessorKey: 'status', + size: 15, + Cell: ({ cell }) => { + const estado = (cell.getValue() ?? '') as InvoiceStatus | ''; + const colorMap: Record = { + PENDING: 'warning', + PAID: 'success', + FAILED: 'error', + CANCELED: 'default', + }; + return ; + }, + }, + { + header: 'Descripción', + accessorKey: 'description', + size: 20, + Cell: ({ cell }) => { + const description = (cell.getValue() ?? '') as string | ''; + return {description || '—'}; + }, + }, + { + header: 'Mes', + accessorKey: 'createdAt', + size: 15, + Cell: ({ cell }) => { + const createdAt = cell.getValue(); + return {createdAt ? getMonthYear(createdAt) : '—'}; + }, + }, + { + header: 'Monto', + accessorKey: 'amount', + size: 15, + Cell: ({ cell }) => { + const amount = cell.getValue(); + return {amount ? `$${amount}` : '—'}; + }, + }, + { + header: 'Acciones', + id: 'acciones', + size: 180, + Cell: ({ row }) => ( + + + {/* console.log('Ver:', row.original)}> + + */} + downloadInvoicePdf(row.original.id)}> + + + + ), + enableSorting: false, + enableColumnFilter: false, + }, + ], []); + + return ( + + + + {/* Diálogo flotante para las acciones */} + {openActionDialog && ( + + setOpenActionDialog(null)}> + + + + + Cambiar estado de factura + + + + + + + + + + + )} + + {/* Snackbar para notificaciones */} + + + {snackbar.message} + + + + ); +}; + +export default InvoiceUserDialog; diff --git a/front-urban/src/views/usuarios/ListUsuarios.tsx b/front-urban/src/views/usuarios/ListUsuarios.tsx new file mode 100644 index 0000000..88829d6 --- /dev/null +++ b/front-urban/src/views/usuarios/ListUsuarios.tsx @@ -0,0 +1,113 @@ +'use client'; +import EditIcon from '@mui/icons-material/Edit'; +import ReceiptIcon from '@mui/icons-material/Receipt'; +import { Chip, Grid, IconButton, Tooltip } from '@mui/material'; +import { MaterialReactTable, MRT_ColumnDef } from 'material-react-table'; +import { MRT_Localization_ES } from 'material-react-table/locales/es'; +import { + useMemo +} from 'react'; +import { UserRole, Usuario } from './usuarios.dto'; + +export type ListUsuariosHandle = { fetchUsers: () => Promise }; + +type Props = { + data: Usuario[] + loading: boolean + error: unknown + refresh: () => Promise + onEdit?: (u: Usuario) => void; + onView?: (u: Usuario) => void; +}; + +const ListUsuarios = ({ data, loading, error, refresh, onEdit, onView }: Props) => { + + + const columns = useMemo[]>(() => [ + { header: 'Nombre', accessorKey: 'name', size: 20 }, + { header: 'DNI', accessorKey: 'dni', size: 10 }, + // { + // header: 'Teléfono', + // accessorKey: 'phone', + // size: 10, + // Cell: ({ cell }) => cell.getValue() ?? '', + // }, + { + header: 'Rol', + accessorKey: 'role', + size: 10, + Cell: ({ cell }) => { + const role = (cell.getValue() ?? '') as UserRole | ''; + const colorMap: Record = { + ADMIN: 'error', + INSTRUCTOR: 'secondary', + USER: 'primary', + GUEST: 'default', + }; + return ; + }, + }, + { + header: 'Acciones', + id: 'acciones', + size: 120, + Cell: ({ row }) => ( + <> + + onEdit?.(row.original)}> + + + + + onView?.(row.original)}> + + + + + ), + enableSorting: false, + enableColumnFilter: false, + }, + ], [onEdit, onView]); + + return ( + + + + ); +} + +export default ListUsuarios; diff --git a/front-urban/src/views/usuarios/UpsertUsuarioDialog.tsx b/front-urban/src/views/usuarios/UpsertUsuarioDialog.tsx new file mode 100644 index 0000000..040d86a --- /dev/null +++ b/front-urban/src/views/usuarios/UpsertUsuarioDialog.tsx @@ -0,0 +1,433 @@ +'use client'; + +import { useUserAuth } from '@/app/context/UserAuth'; +import CustomDialog from '@/utils/CustomDialog'; +import { + Alert, + Avatar, + Box, + Button, + Grid, + IconButton, + MenuItem, + Stack, + Switch, + TextField, + Tooltip, + Typography, +} from '@mui/material'; +import apiClient from '@/lib/apiClient'; +import { useEffect, useState } from 'react'; +import { UserRole, Usuario } from './usuarios.dto'; +import { useToggleUserActive } from '@/@core/hooks/useToggleUserActive'; +import { useProfilePicture } from '@/@core/hooks/useProfilePicture'; +import { DIALOG_INFO } from '@/configs/dialogInfoContent'; + +type Props = { + open: boolean; + usuario: Usuario | null; + onClose: () => void; + onRefresh: () => Promise; +}; + +export const UpsertUsuarioDialog = ({ open, usuario, onClose, onRefresh }: Props) => { + + const { token } = useUserAuth() + const { toggleActive, loading: toggleLoading } = useToggleUserActive(); + + // Hook para obtener la foto de perfil del usuario + const { profilePicture, loading: loadingPicture } = useProfilePicture(usuario?.id || '', { + auto: !!usuario?.id, + }); + + const [form, setForm] = useState({ + id: usuario?.id, + customId: usuario?.customId ?? '', + name: usuario?.name ?? '', + dni: usuario?.dni ?? '', + phone: usuario?.phone ?? '', + birth: usuario?.birth ? usuario.birth.slice(0, 10) : '', + rfid: usuario?.rfid ?? '', + role: usuario?.role ?? 'USER', + deleted: usuario?.deleted ?? null, + }); + const [saving, setSaving] = useState(false); + + const isEdit = Boolean(form.id); + + // Detectar si hay cambios en los campos (excluyendo isActive) + const hasChanges = () => { + if (!usuario) return false; + const birthForm = form.birth ? form.birth.slice(0, 10) : ''; + const birthUsuario = usuario.birth ? usuario.birth.slice(0, 10) : ''; + + return ( + form.name !== usuario.name || + (form.dni ?? '') !== (usuario.dni ?? '') || + (form.phone ?? '') !== (usuario.phone ?? '') || + birthForm !== birthUsuario || + (form.rfid ?? '') !== (usuario.rfid ?? '') || + (form.role ?? 'USER') !== (usuario.role ?? 'USER') + ); + }; + + // Hidratar al abrir con el usuario recibido + useEffect(() => { + setForm({ + id: usuario?.id, + customId: usuario?.customId ?? '', + name: usuario?.name ?? '', + dni: usuario?.dni ?? '', + phone: usuario?.phone ?? '', + birth: usuario?.birth ? usuario.birth.slice(0, 10) : '', + rfid: usuario?.rfid ?? '', + role: usuario?.role ?? 'USER', + deleted: usuario?.deleted ?? null, + }); + }, [usuario]); + + const handleChange = (key: keyof Usuario) => (e: React.ChangeEvent) => { + setForm(prev => ({ ...prev, [key]: e.target.value })); + }; + + const handleToggleActive = async (e: React.ChangeEvent) => { + const newValue = e.target.checked; + const isActive = !form.deleted; + + if (!form.id) { + console.warn('⚠️ No user ID found'); + return; + } + + const success = await toggleActive(form.id, newValue); + if (success) { + setForm(prev => ({ ...prev, deleted: newValue ? null : new Date() })); + await onRefresh(); + } else { + console.error('❌ Failed to toggle, reverting state'); + } + }; + + const handleResetForm = () => { + if (usuario) { + setForm({ + id: usuario.id, + customId: usuario.customId ?? '', + name: usuario.name ?? '', + dni: usuario.dni ?? '', + phone: usuario.phone ?? '', + birth: usuario.birth ? usuario.birth.slice(0, 10) : '', + rfid: usuario.rfid ?? '', + role: usuario.role ?? 'USER', + deleted: usuario.deleted ?? null, + }); + } + }; + + // Helper para verificar si un campo específico cambió + const hasFieldChanged = (field: keyof Usuario): boolean => { + if (!usuario) return false; + + if (field === 'birth') { + const birthForm = form.birth ? form.birth.slice(0, 10) : ''; + const birthUsuario = usuario.birth ? usuario.birth.slice(0, 10) : ''; + return birthForm !== birthUsuario; + } + + return (form[field] ?? '') !== (usuario[field] ?? ''); + }; + + // Helper para obtener el valor original + const getOriginalValue = (field: keyof Usuario): string => { + if (!usuario) return ''; + + if (field === 'birth' && usuario.birth) { + return new Date(usuario.birth).toLocaleDateString('es-AR', { + year: 'numeric', + month: 'long', + day: 'numeric' + }); + } + + if (field === 'role') { + return usuario.role ?? 'USER'; + } + + return (usuario[field] as string) ?? 'Sin valor'; + }; + + const handleSubmit = async (e?: React.FormEvent) => { + e?.preventDefault(); + setSaving(true); + try { + const body = { ...form, birth: form.birth ? new Date(form.birth).toISOString() : undefined }; + await apiClient.post('/users', body); + await onRefresh(); + onClose(); + } catch (err) { + console.error('Error al upsert usuario', err); + } finally { + setSaving(false); + } + }; + + const filledSx = { + '& .MuiFilledInput-root': { + backgroundColor: 'rgba(255,255,255,0.04)', + borderRadius: 2, + '&:hover': { backgroundColor: 'rgba(255,255,255,0.06)' }, + '&.Mui-focused': { backgroundColor: 'rgba(255,255,255,0.07)' }, + }, + }; + + return ( + { } : onClose} + maxWidth="sm" + title={isEdit ? 'Editar usuario' : 'Crear usuario'} + contentProps={{ dividers: true }} + infoContent={DIALOG_INFO.usuarioForm} + actions={ + <> + {isEdit && hasChanges() && ( + + )} + + + } + > +
    + + {/* Avatar del usuario (solo en edición) */} + {isEdit && ( + + + {!profilePicture && form.name?.charAt(0).toUpperCase()} + + + )} + + {!form.id && !form.rfid && ( + + Al crear un usuario sin el flujo del llavero, necesitás asignarle manualmente un RFID para poder tomar asistencia. + + )} + + + {isEdit && ( + + + + {!form.deleted ? 'Activo' : 'Inactivo'} + + + + + )} + + + + + + + ) + }} + /> + + + + + + + + ) + }} + /> + + + + + + ) + }} + /> + + + + + + + + + ) + }} + /> + + + + + + ) + }} + /> + + + + + + + + ) + }} + > + {(['ADMIN', 'INSTRUCTOR', 'USER', 'GUEST'] as UserRole[]).map(r => ( + + {r} + + ))} + + + +
    + ); +}; + +export default UpsertUsuarioDialog; diff --git a/front-urban/src/views/usuarios/index.tsx b/front-urban/src/views/usuarios/index.tsx new file mode 100644 index 0000000..7a0b6a4 --- /dev/null +++ b/front-urban/src/views/usuarios/index.tsx @@ -0,0 +1,122 @@ +'use client'; + +import { useUsuarios } from '@/@core/hooks/useUsuarios'; +import { useUserAuth } from '@/app/context/UserAuth'; +import { Add } from '@mui/icons-material'; +import { alpha, Box, Card, CardActionArea, CardContent, Grid, Typography } from '@mui/material'; +import { useState } from 'react'; +import { InvoiceUserDialog } from './InvoiceUserDialog'; +import ListUsuarios from './ListUsuarios'; +import { UpsertUsuarioDialog } from './UpsertUsuarioDialog'; +import { Usuario } from './usuarios.dto'; + +const UsuariosComponent = () => { + const [openUpsert, setOpenUpsert] = useState(false); + const [usuarioSel, setUsuarioSel] = useState(null); + const [openDialogInvoice, setOpenDialogInvoice] = useState(false); + + const { token } = useUserAuth(); + const { data, loading, error, refresh: refreshUsers } = useUsuarios(); + + const handleNuevoUsuario = () => { + setUsuarioSel(null); // modo creación + setOpenUpsert(true); + }; + + return ( + + + + ({ + borderRadius: 3, + backdropFilter: 'blur(6px)', + backgroundImage: `linear-gradient(180deg, ${alpha(theme.palette.background.paper, 0.9)} 0%, ${alpha( + theme.palette.background.paper, + 0.72 + )} 100%)`, + border: `1px solid ${alpha(theme.palette.primary.main, 0.25)}`, + boxShadow: `0 10px 30px ${alpha('#000', 0.18)}`, + transition: 'transform .15s ease, box-shadow .2s ease, border-color .2s ease', + '&:hover': { + transform: 'translateY(-2px) scale(1.02)', + boxShadow: `0 14px 40px ${alpha(theme.palette.primary.main, 0.35)}`, + borderColor: alpha(theme.palette.primary.main, 0.5), + cursor: 'pointer' + }, + '&:active': { transform: 'translateY(0) scale(0.998)' } + })} + > + + + ({ + width: 56, + height: 56, + borderRadius: '14px', + display: 'grid', + placeItems: 'center', + background: `linear-gradient(135deg, ${alpha(theme.palette.primary.main, 0.18)} 0%, ${alpha( + theme.palette.primary.light, + 0.12 + )} 100%)`, + border: `1px solid ${alpha(theme.palette.primary.main, 0.35)}` + })} + > + + + + + Nuevo usuario + + + Crear una cuenta para alumno o instructor + + + + + + + { + setUsuarioSel(u); + setOpenUpsert(true); + }} + onView={(u) => { + setUsuarioSel(u); + setOpenDialogInvoice(true); + }} + /> + + + setOpenUpsert(false)} + usuario={usuarioSel} + onRefresh={refreshUsers} + /> + + setOpenDialogInvoice(false)} + usuario={usuarioSel} + onRefresh={refreshUsers} + /> + + ); +}; + +export default UsuariosComponent; diff --git a/front-urban/src/views/usuarios/usuarios.dto.ts b/front-urban/src/views/usuarios/usuarios.dto.ts new file mode 100644 index 0000000..9c4ccd5 --- /dev/null +++ b/front-urban/src/views/usuarios/usuarios.dto.ts @@ -0,0 +1,12 @@ +export type UserRole = 'ADMIN' | 'INSTRUCTOR' | 'USER' | 'GUEST'; +export type Usuario = { + id?: string; + customId: string; + name: string; + dni?: string | null; + phone?: string | null; + birth?: string | null; + rfid?: string | null; + role?: UserRole; + deleted?: Date | string | null; +}; diff --git a/front-urban/src/views/whatsapp/index.tsx b/front-urban/src/views/whatsapp/index.tsx new file mode 100644 index 0000000..9f5ca72 --- /dev/null +++ b/front-urban/src/views/whatsapp/index.tsx @@ -0,0 +1,168 @@ +'use client'; + +import { + Box, Grid, Card, CardContent, Typography, Chip, Button, CircularProgress, +} from '@mui/material'; +import { useEffect, useRef, useState } from 'react'; +import { useUserAuth } from '@/app/context/UserAuth'; +import apiClient from '@/lib/apiClient'; + +const WHATSAPP_STATUS_URL = '/whatsapp/status'; + +type WhatsappStatusResp = { + status: 'Correcto' | 'Sin session' | string; + phone: string | null; + qr: string | null; +}; + +const ensureDataUrl = (qr: string | null) => (qr ? (qr.startsWith('data:') ? qr : `data:image/png;base64,${qr}`) : null); + +const WhatsAppComponent = () => { + const { token } = useUserAuth(); + + const [qrSrc, setQrSrc] = useState(null); + const [waStatus, setWaStatus] = useState('Sin session'); + const [phone, setPhone] = useState('No disponible'); + const [loading, setLoading] = useState(false); + const [err, setErr] = useState(null); + + const inFlight = useRef(false); // evita solapar requests del polling + + const applyStatus = (json: WhatsappStatusResp) => { + setWaStatus(json.status ?? 'Sin session'); + setPhone(json.phone ?? 'No disponible'); + setQrSrc(ensureDataUrl(json.qr ?? null)); + setErr(null); + }; + + const fetchStatus = async (opts?: { silent?: boolean }) => { + if (!token) return; + + const silent = opts?.silent === true; + if (!silent) { + setLoading(true); + setErr(null); + } + + try { + const res = await apiClient.get(WHATSAPP_STATUS_URL); + applyStatus(res.data); + } catch (e: any) { + if (!silent) { + setErr(e?.response?.data?.message || e?.message || 'Error obteniendo estado de WhatsApp'); + setWaStatus('Sin session'); + setPhone('No disponible'); + setQrSrc(null); + } + } finally { + if (!silent) setLoading(false); + } + }; + + // Primer fetch + useEffect(() => { + fetchStatus(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [token]); + + // Polling cada 5s (silencioso) + useEffect(() => { + if (!token) return; + + const tick = async () => { + if (document.hidden) return; // opcional: no refrescar si la pestaña está oculta + if (inFlight.current) return; // evita superposición + inFlight.current = true; + try { + await fetchStatus({ silent: true }); + } finally { + inFlight.current = false; + } + }; + + const id = setInterval(tick, 5000); + // correr una vez al montar para no esperar 5s + tick(); + + return () => clearInterval(id); + }, [token]); + + const chipColor = err ? 'error' : waStatus === 'Correcto' ? 'success' : 'warning'; + + return ( + + + + + + {loading ? ( + + + + ) : qrSrc ? ( + + ) : ( + + {err || 'No hay QR disponible'} + + )} + + + + + + Bot de WhatsApp + + + + + + + + + + Teléfono:{' '} + + {phone} + + + + + + + + ); +}; + +export default WhatsAppComponent; diff --git a/front-urban/tailwind.config.ts b/front-urban/tailwind.config.ts new file mode 100644 index 0000000..e47b1f0 --- /dev/null +++ b/front-urban/tailwind.config.ts @@ -0,0 +1,15 @@ +import type { Config } from 'tailwindcss' + +const config: Config = { + content: ['./src/**/*.{js,ts,jsx,tsx,css}'], + corePlugins: { + preflight: false + }, + important: '#__next', + plugins: [require('tailwindcss-logical'), require('./src/@core/tailwind/plugin')], + theme: { + extend: {} + } +} + +export default config diff --git a/front-urban/tsconfig.json b/front-urban/tsconfig.json new file mode 100644 index 0000000..d0d1b1c --- /dev/null +++ b/front-urban/tsconfig.json @@ -0,0 +1,65 @@ +{ + "compilerOptions": { + "target": "ESNext", + "downlevelIteration": true, + "lib": [ + "DOM", + "DOM.Iterable", + "ESNext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./src/*" + ], + "@core/*": [ + "./src/@core/*" + ], + "@layouts/*": [ + "./src/@layouts/*" + ], + "@menu/*": [ + "./src/@menu/*" + ], + "@assets/*": [ + "./src/assets/*" + ], + "@components/*": [ + "./src/components/*" + ], + "@configs/*": [ + "./src/configs/*" + ], + "@views/*": [ + "./src/views/*" + ] + } + }, + "include": [ + "next.config.mjs", + "tailwind.config.ts", + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +}