From dd5da8b82ccd766963f499c22e4f9ead0ebad641 Mon Sep 17 00:00:00 2001 From: OliverBryant <2713999266@qq.com> Date: Wed, 8 Jul 2026 18:23:23 +0800 Subject: [PATCH] chore: remove legacy React web UI now that Next.js frontend is the default The old xinference/ui/web/ui frontend was fully superseded by the Next.js app under frontend/ (#5111), which is already wired into the build, packaging, and serving pipeline. Removing the unused directory and updating AGENTS.md to point at the current frontend. --- AGENTS.md | 16 +- xinference/ui/web/ui/.eslintignore | 5 - xinference/ui/web/ui/.eslintrc.yml | 30 - xinference/ui/web/ui/.gitignore | 23 - xinference/ui/web/ui/.prettierignore | 5 - xinference/ui/web/ui/.prettierrc.yml | 9 - xinference/ui/web/ui/package-lock.json | 19562 ---------------- xinference/ui/web/ui/package.json | 78 - xinference/ui/web/ui/public/favicon.png | Bin 23192 -> 0 bytes xinference/ui/web/ui/public/index.html | 43 - xinference/ui/web/ui/src/App.js | 86 - .../ui/web/ui/src/components/MenuSide.js | 499 - xinference/ui/web/ui/src/components/Title.js | 15 - .../web/ui/src/components/alertComponent.js | 8 - .../ui/web/ui/src/components/apiContext.js | 31 - .../web/ui/src/components/authAlertDialog.js | 104 - .../ui/web/ui/src/components/copyComponent.js | 43 - .../ui/web/ui/src/components/deleteDialog.js | 49 - .../ui/src/components/errorMessageSnackBar.js | 31 - .../ui/web/ui/src/components/fetchWrapper.js | 194 - .../ui/web/ui/src/components/fetcher.js | 43 - .../ui/web/ui/src/components/grafanaUtils.js | 108 - .../ui/src/components/hotkeyFocusTextField.js | 59 - .../src/components/successMessageSnackBar.js | 31 - .../ui/web/ui/src/components/tableTitle.js | 21 - .../ui/web/ui/src/components/themeButton.js | 20 - .../ui/web/ui/src/components/themeContext.js | 36 - .../web/ui/src/components/titleTypography.js | 22 - .../web/ui/src/components/translateButton.js | 111 - xinference/ui/web/ui/src/components/utils.js | 49 - .../ui/web/ui/src/components/versionLabel.js | 27 - xinference/ui/web/ui/src/i18n.js | 43 - xinference/ui/web/ui/src/index.css | 30 - xinference/ui/web/ui/src/index.js | 16 - xinference/ui/web/ui/src/locales/en.json | 596 - xinference/ui/web/ui/src/locales/ja.json | 587 - xinference/ui/web/ui/src/locales/ko.json | 587 - xinference/ui/web/ui/src/locales/zh.json | 596 - xinference/ui/web/ui/src/media/icon.png | Bin 23192 -> 0 bytes xinference/ui/web/ui/src/router/index.js | 165 - .../ui/web/ui/src/scenes/_layout/index.js | 18 - .../ui/src/scenes/apikey_management/index.js | 907 - .../ui/web/ui/src/scenes/audit_log/index.js | 1011 - .../ui/src/scenes/change_password/index.js | 103 - .../web/ui/src/scenes/cluster_info/index.js | 116 - .../ui/src/scenes/cluster_info/nodeInfo.js | 366 - .../web/ui/src/scenes/cluster_info/style.js | 30 - .../ui/src/scenes/launch_model/LaunchModel.js | 468 - .../components/cachedListDialog.js | 257 - .../launch_model/components/commandBuilder.js | 116 - .../components/dynamicFieldList.js | 169 - .../components/editCustomModelDialog.js | 66 - .../components/launchModelDrawer.js | 2121 -- .../components/modelFormConfig.js | 1287 - .../launch_model/components/pasteDialog.js | 147 - .../launch_model/components/progress.js | 12 - .../launch_model/components/selectField.js | 112 - .../components/virtualenvListDialog.js | 242 - .../ui/src/scenes/launch_model/data/data.js | 81 - .../web/ui/src/scenes/launch_model/index.js | 204 - .../src/scenes/launch_model/launchCustom.js | 184 - .../ui/src/scenes/launch_model/modelCard.js | 562 - .../launch_model/styles/modelCardStyle.css | 93 - .../ui/web/ui/src/scenes/login/header.js | 36 - .../ui/web/ui/src/scenes/login/login.js | 151 - xinference/ui/web/ui/src/scenes/logs/index.js | 1522 -- .../scenes/monitoring/MonitorConfigDialog.js | 367 - .../ui/web/ui/src/scenes/monitoring/index.js | 478 - .../components/addControlnet.js | 181 - .../components/addModelSpecs.js | 454 - .../register_model/components/addStop.js | 109 - .../components/addVirtualenv.js | 89 - .../scenes/register_model/data/languages.js | 192 - .../web/ui/src/scenes/register_model/index.js | 191 - .../scenes/register_model/registerModel.js | 1890 -- .../styles/registerModelStyle.css | 157 - .../web/ui/src/scenes/running_models/index.js | 1392 -- .../ui/src/scenes/security_settings/index.js | 399 - .../ui/src/scenes/user_management/index.js | 546 - xinference/ui/web/ui/src/theme.js | 44 - xinference/ui/web/ui/src/utils/jwt.js | 39 - 81 files changed, 8 insertions(+), 40879 deletions(-) delete mode 100644 xinference/ui/web/ui/.eslintignore delete mode 100644 xinference/ui/web/ui/.eslintrc.yml delete mode 100644 xinference/ui/web/ui/.gitignore delete mode 100644 xinference/ui/web/ui/.prettierignore delete mode 100644 xinference/ui/web/ui/.prettierrc.yml delete mode 100644 xinference/ui/web/ui/package-lock.json delete mode 100644 xinference/ui/web/ui/package.json delete mode 100644 xinference/ui/web/ui/public/favicon.png delete mode 100644 xinference/ui/web/ui/public/index.html delete mode 100644 xinference/ui/web/ui/src/App.js delete mode 100644 xinference/ui/web/ui/src/components/MenuSide.js delete mode 100644 xinference/ui/web/ui/src/components/Title.js delete mode 100644 xinference/ui/web/ui/src/components/alertComponent.js delete mode 100644 xinference/ui/web/ui/src/components/apiContext.js delete mode 100644 xinference/ui/web/ui/src/components/authAlertDialog.js delete mode 100644 xinference/ui/web/ui/src/components/copyComponent.js delete mode 100644 xinference/ui/web/ui/src/components/deleteDialog.js delete mode 100644 xinference/ui/web/ui/src/components/errorMessageSnackBar.js delete mode 100644 xinference/ui/web/ui/src/components/fetchWrapper.js delete mode 100644 xinference/ui/web/ui/src/components/fetcher.js delete mode 100644 xinference/ui/web/ui/src/components/grafanaUtils.js delete mode 100644 xinference/ui/web/ui/src/components/hotkeyFocusTextField.js delete mode 100644 xinference/ui/web/ui/src/components/successMessageSnackBar.js delete mode 100644 xinference/ui/web/ui/src/components/tableTitle.js delete mode 100644 xinference/ui/web/ui/src/components/themeButton.js delete mode 100644 xinference/ui/web/ui/src/components/themeContext.js delete mode 100644 xinference/ui/web/ui/src/components/titleTypography.js delete mode 100644 xinference/ui/web/ui/src/components/translateButton.js delete mode 100644 xinference/ui/web/ui/src/components/utils.js delete mode 100644 xinference/ui/web/ui/src/components/versionLabel.js delete mode 100644 xinference/ui/web/ui/src/i18n.js delete mode 100644 xinference/ui/web/ui/src/index.css delete mode 100644 xinference/ui/web/ui/src/index.js delete mode 100644 xinference/ui/web/ui/src/locales/en.json delete mode 100644 xinference/ui/web/ui/src/locales/ja.json delete mode 100644 xinference/ui/web/ui/src/locales/ko.json delete mode 100644 xinference/ui/web/ui/src/locales/zh.json delete mode 100644 xinference/ui/web/ui/src/media/icon.png delete mode 100644 xinference/ui/web/ui/src/router/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/_layout/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/apikey_management/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/audit_log/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/change_password/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/cluster_info/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/cluster_info/nodeInfo.js delete mode 100644 xinference/ui/web/ui/src/scenes/cluster_info/style.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/LaunchModel.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/cachedListDialog.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/commandBuilder.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/dynamicFieldList.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/editCustomModelDialog.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/launchModelDrawer.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/modelFormConfig.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/pasteDialog.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/progress.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/selectField.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/components/virtualenvListDialog.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/data/data.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/launchCustom.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/modelCard.js delete mode 100644 xinference/ui/web/ui/src/scenes/launch_model/styles/modelCardStyle.css delete mode 100644 xinference/ui/web/ui/src/scenes/login/header.js delete mode 100644 xinference/ui/web/ui/src/scenes/login/login.js delete mode 100644 xinference/ui/web/ui/src/scenes/logs/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/monitoring/MonitorConfigDialog.js delete mode 100644 xinference/ui/web/ui/src/scenes/monitoring/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/components/addControlnet.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/components/addModelSpecs.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/components/addStop.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/components/addVirtualenv.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/data/languages.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/registerModel.js delete mode 100644 xinference/ui/web/ui/src/scenes/register_model/styles/registerModelStyle.css delete mode 100644 xinference/ui/web/ui/src/scenes/running_models/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/security_settings/index.js delete mode 100644 xinference/ui/web/ui/src/scenes/user_management/index.js delete mode 100644 xinference/ui/web/ui/src/theme.js delete mode 100644 xinference/ui/web/ui/src/utils/jwt.js diff --git a/AGENTS.md b/AGENTS.md index ea564bce80..04afa1e13f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -19,7 +19,7 @@ Primary package and entry points: tests. - `xinference/api/`: API server and OpenAI-compatible routes. - `xinference/client/`: sync and async Python clients. -- `xinference/ui/web/ui/`: React Web UI. +- `frontend/`: Next.js Web UI. - `doc/source/`: Sphinx documentation. - `.github/workflows/python.yaml`: main lint and test CI. @@ -111,22 +111,22 @@ dependencies, GPU, Metal, network access, or model downloads. ## Frontend -The Web UI is under `xinference/ui/web/ui` and uses React 18, Material UI, -react-router, i18next, ESLint, and Prettier. +The Web UI is under `frontend` and is a Next.js app (React, TypeScript, +Tailwind CSS), built as a static export and served by the Python backend from +`xinference/ui/web/dist`. Common commands: ```bash -cd xinference/ui/web/ui +cd frontend npm ci -npm start +npm run dev npm run build npx eslint . -npx prettier --check . ``` -Use `npm run format` only when you intentionally want ESLint autofixes and -Prettier writes across the UI tree. +Use `npm run format` only when you intentionally want Prettier writes across +the frontend tree. ## Documentation diff --git a/xinference/ui/web/ui/.eslintignore b/xinference/ui/web/ui/.eslintignore deleted file mode 100644 index 563fcbd9ad..0000000000 --- a/xinference/ui/web/ui/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -.idea -.github -node_modules -build -public diff --git a/xinference/ui/web/ui/.eslintrc.yml b/xinference/ui/web/ui/.eslintrc.yml deleted file mode 100644 index 194a169d94..0000000000 --- a/xinference/ui/web/ui/.eslintrc.yml +++ /dev/null @@ -1,30 +0,0 @@ -env: - browser: true - es2021: true - node: true -extends: - - 'eslint:recommended' - - 'plugin:react/recommended' - - 'prettier' -parserOptions: - parser: '@babel/eslint-parser' - requireConfigFile: false - ecmaFeatures: - jsx: true - ecmaVersion: 12 - sourceType: module -plugins: - - react - - simple-import-sort -rules: - new-cap: 'error' - no-var: 'error' - simple-import-sort/imports: 'error' - simple-import-sort/exports: 'error' - quote-props: ['error', 'consistent'] - 'react/react-in-jsx-scope': 'off' - 'react/prop-types': 'off' - 'react/jsx-key': 'off' -settings: - react: - version: 'detect' diff --git a/xinference/ui/web/ui/.gitignore b/xinference/ui/web/ui/.gitignore deleted file mode 100644 index 4d29575de8..0000000000 --- a/xinference/ui/web/ui/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/xinference/ui/web/ui/.prettierignore b/xinference/ui/web/ui/.prettierignore deleted file mode 100644 index 563fcbd9ad..0000000000 --- a/xinference/ui/web/ui/.prettierignore +++ /dev/null @@ -1,5 +0,0 @@ -.idea -.github -node_modules -build -public diff --git a/xinference/ui/web/ui/.prettierrc.yml b/xinference/ui/web/ui/.prettierrc.yml deleted file mode 100644 index a794136336..0000000000 --- a/xinference/ui/web/ui/.prettierrc.yml +++ /dev/null @@ -1,9 +0,0 @@ -trailingComma: 'es5' -tabWidth: 2 -semi: false -singleQuote: true -printWidth: 80 -bracketSpacing: true -bracketSameLine: false -arrowParens: 'always' -quoteProps: 'consistent' diff --git a/xinference/ui/web/ui/package-lock.json b/xinference/ui/web/ui/package-lock.json deleted file mode 100644 index b0fb0e9e45..0000000000 --- a/xinference/ui/web/ui/package-lock.json +++ /dev/null @@ -1,19562 +0,0 @@ -{ - "name": "xinference-ui", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "xinference-ui", - "version": "0.1.0", - "dependencies": { - "@emotion/react": "^11.11.1", - "@emotion/styled": "^11.11.0", - "@fullcalendar/core": "^6.1.8", - "@fullcalendar/daygrid": "^6.1.8", - "@fullcalendar/list": "^6.1.8", - "@fullcalendar/timegrid": "^6.1.8", - "@mui/icons-material": "^5.14.0", - "@mui/lab": "^5.0.0-alpha.173", - "@mui/material": "^5.14.0", - "@mui/system": "^5.15.9", - "@mui/x-data-grid": "^6.20.4", - "@mui/x-date-pickers": "^6.20.0", - "@nivo/bar": "^0.83.0", - "@nivo/core": "^0.83.0", - "@nivo/geo": "^0.83.0", - "@nivo/line": "^0.83.0", - "@nivo/pie": "^0.83.0", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "dayjs": "^1.11.0", - "formik": "^2.4.2", - "i18next": "^23.0.0", - "nunjucks": "^3.2.4", - "prop-types": "^15.8.1", - "react": "^18.2.0", - "react-cookie": "^6.1.1", - "react-dom": "^18.2.0", - "react-i18next": "^15.4.0", - "react-pro-sidebar": "^1.1.0-alpha.1", - "react-router-dom": "^6.14.1", - "react-scripts": "5.0.1", - "uuid": "^9.0.0", - "web-vitals": "^2.1.4", - "yup": "^1.2.0" - }, - "devDependencies": { - "@babel/core": "^7.21.0", - "@babel/eslint-parser": "^7.19.1", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.24.0", - "eslint-plugin-simple-import-sort": "^8.0.0", - "prettier": "2.8.0" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@adobe/css-tools": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", - "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==" - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz", - "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.5", - "@babel/generator": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.6", - "@babel/parser": "^7.22.7", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.8", - "@babel/types": "^7.22.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/eslint-parser": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.9.tgz", - "integrity": "sha512-xdMkt39/nviO/4vpVdrEYPwXCsYIXSSAr6mC7WQsNIlGnuxKyKE7GZjalcnbSWiC4OXGNNN3UQPeHfjSC6sTDA==", - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.11.0", - "eslint": "^7.5.0 || ^8.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/@babel/eslint-parser/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", - "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", - "dependencies": { - "@babel/types": "^7.24.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz", - "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==", - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz", - "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz", - "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "regexpu-core": "^5.3.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz", - "integrity": "sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0-0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", - "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", - "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz", - "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz", - "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-wrap-function": "^7.22.9" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz", - "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", - "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz", - "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==", - "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz", - "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==", - "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.6", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", - "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz", - "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz", - "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" - } - }, - "node_modules/@babel/plugin-proposal-class-properties": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", - "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.7.tgz", - "integrity": "sha512-omXqPF7Onq4Bb7wHxXjM3jSMSJvUUbvDvmmds7KI5n9Cq6Ln5I05I1W2nRlRof1rGdiUxJrxwe285WF96XlBXQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/plugin-syntax-decorators": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-numeric-separator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", - "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-methods": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", - "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz", - "integrity": "sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.21.0", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-proposal-unicode-property-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", - "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.5.tgz", - "integrity": "sha512-avpUOBS7IU6al8MmF1XpAyj9QYeLPuSDJI5D4pVMSMdL7xQokKqJPYQC67RCT0aCTashUXPiGwMJ0DEXXCEmMA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-flow": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz", - "integrity": "sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", - "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", - "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz", - "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", - "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz", - "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5", - "@babel/plugin-syntax-async-generators": "^7.8.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", - "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", - "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz", - "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", - "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz", - "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" - } - }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz", - "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", - "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz", - "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", - "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", - "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz", - "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", - "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", - "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz", - "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-flow-strip-types": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz", - "integrity": "sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-flow": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz", - "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", - "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", - "dependencies": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz", - "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", - "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz", - "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", - "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", - "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz", - "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==", - "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz", - "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==", - "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", - "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", - "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", - "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz", - "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz", - "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz", - "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==", - "dependencies": { - "@babel/compat-data": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-object-super": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", - "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz", - "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz", - "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz", - "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", - "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz", - "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", - "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-constant-elements": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz", - "integrity": "sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-display-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz", - "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-development": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", - "dependencies": { - "@babel/plugin-transform-react-jsx": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-pure-annotations": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz", - "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz", - "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "regenerator-transform": "^0.15.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", - "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz", - "integrity": "sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.4", - "babel-plugin-polyfill-corejs3": "^0.8.2", - "babel-plugin-polyfill-regenerator": "^0.5.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", - "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", - "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", - "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", - "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", - "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz", - "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.9", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-typescript": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz", - "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", - "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", - "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", - "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/preset-env": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", - "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==", - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.9", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.22.5", - "@babel/plugin-syntax-import-attributes": "^7.22.5", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.7", - "@babel/plugin-transform-async-to-generator": "^7.22.5", - "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.22.5", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.5", - "@babel/plugin-transform-classes": "^7.22.6", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.5", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.5", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.5", - "@babel/plugin-transform-for-of": "^7.22.5", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.5", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.5", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-modules-systemjs": "^7.22.5", - "@babel/plugin-transform-modules-umd": "^7.22.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5", - "@babel/plugin-transform-numeric-separator": "^7.22.5", - "@babel/plugin-transform-object-rest-spread": "^7.22.5", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.6", - "@babel/plugin-transform-parameters": "^7.22.5", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.5", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.5", - "@babel/plugin-transform-reserved-words": "^7.22.5", - "@babel/plugin-transform-shorthand-properties": "^7.22.5", - "@babel/plugin-transform-spread": "^7.22.5", - "@babel/plugin-transform-sticky-regex": "^7.22.5", - "@babel/plugin-transform-template-literals": "^7.22.5", - "@babel/plugin-transform-typeof-symbol": "^7.22.5", - "@babel/plugin-transform-unicode-escapes": "^7.22.5", - "@babel/plugin-transform-unicode-property-regex": "^7.22.5", - "@babel/plugin-transform-unicode-regex": "^7.22.5", - "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", - "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.4", - "babel-plugin-polyfill-corejs3": "^0.8.2", - "babel-plugin-polyfill-regenerator": "^0.5.1", - "core-js-compat": "^3.31.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", - "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-react": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz", - "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-transform-react-display-name": "^7.22.5", - "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/plugin-transform-react-jsx-development": "^7.22.5", - "@babel/plugin-transform-react-pure-annotations": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/preset-typescript": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz", - "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.5", - "@babel/plugin-transform-typescript": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" - }, - "node_modules/@babel/runtime": { - "version": "7.26.0", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.0.tgz", - "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime/node_modules/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", - "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", - "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", - "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.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", - "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "node_modules/@csstools/normalize.css": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", - "integrity": "sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg==" - }, - "node_modules/@csstools/postcss-cascade-layers": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-1.1.1.tgz", - "integrity": "sha512-+KdYrpKC5TgomQr2DlZF4lDEpHcoxnj5IGddYYfBWJAKfj1JtuHUIqMa+E1pJJ+z3kvDViWMqyqPlG4Ja7amQA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.2", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-color-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-1.1.1.tgz", - "integrity": "sha512-Bc0f62WmHdtRDjf5f3e2STwRAl89N2CLb+9iAwzrv4L2hncrbDwnQD9PCq0gtAt7pOI2leIV08HIBUd4jxD8cw==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-font-format-keywords": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.1.tgz", - "integrity": "sha512-ZgrlzuUAjXIOc2JueK0X5sZDjCtgimVp/O5CEqTcs5ShWBa6smhWYbS0x5cVc/+rycTDbjjzoP0KTDnUneZGOg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-hwb-function": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.2.tgz", - "integrity": "sha512-YHdEru4o3Rsbjmu6vHy4UKOXZD+Rn2zmkAmLRfPet6+Jz4Ojw8cbWxe1n42VaXQhD3CQUXXTooIy8OkVbUcL+w==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-ic-unit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.1.tgz", - "integrity": "sha512-Ot1rcwRAaRHNKC9tAqoqNZhjdYBzKk1POgWfhN4uCOE47ebGcLRqXjKkApVDpjifL6u2/55ekkpnFcp+s/OZUw==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-is-pseudo-class": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.7.tgz", - "integrity": "sha512-7JPeVVZHd+jxYdULl87lvjgvWldYu+Bc62s9vD/ED6/QTGjy0jy0US/f6BG53sVMTBJ1lzKZFpYmofBN9eaRiA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-nested-calc": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-1.0.0.tgz", - "integrity": "sha512-JCsQsw1wjYwv1bJmgjKSoZNvf7R6+wuHDAbi5f/7MbFhl2d/+v+TvBTU4BJH3G1X1H87dHl0mh6TfYogbT/dJQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-normalize-display-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.1.tgz", - "integrity": "sha512-jcOanIbv55OFKQ3sYeFD/T0Ti7AMXc9nM1hZWu8m/2722gOTxFg7xYu4RDLJLeZmPUVQlGzo4jhzvTUq3x4ZUw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-oklab-function": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.1.tgz", - "integrity": "sha512-nJpJgsdA3dA9y5pgyb/UfEzE7W5Ka7u0CX0/HIMVBNWzWemdcTH3XwANECU6anWv/ao4vVNLTMxhiPNZsTK6iA==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-progressive-custom-properties": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz", - "integrity": "sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/@csstools/postcss-stepped-value-functions": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.1.tgz", - "integrity": "sha512-dz0LNoo3ijpTOQqEJLY8nyaapl6umbmDcgj4AD0lgVQ572b2eqA1iGZYTTWhrcrHztWDDRAX2DGYyw2VBjvCvQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-text-decoration-shorthand": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-1.0.0.tgz", - "integrity": "sha512-c1XwKJ2eMIWrzQenN0XbcfzckOLLJiczqy+YvfGmzoVXd7pT9FfObiSEfzs84bpE/VqfpEuAZ9tCRbZkZxxbdw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-trigonometric-functions": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-1.0.2.tgz", - "integrity": "sha512-woKaLO///4bb+zZC2s80l+7cm07M7268MsyG3M0ActXXEFi6SuhvriQYcb58iiKGbjwwIU7n45iRLEHypB47Og==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/postcss-unset-value": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.2.tgz", - "integrity": "sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz", - "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", - "engines": { - "node": "^14 || ^16 || >=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss-selector-parser": "^6.0.10" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", - "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/serialize": "^1.1.2", - "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/babel-plugin/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@emotion/babel-plugin/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", - "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", - "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" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", - "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", - "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", - "dependencies": { - "@emotion/memoize": "^0.8.1" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" - }, - "node_modules/@emotion/react": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", - "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/cache": "^11.11.0", - "@emotion/serialize": "^1.1.2", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1", - "@emotion/weak-memoize": "^0.3.1", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz", - "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==", - "dependencies": { - "@emotion/hash": "^0.9.1", - "@emotion/memoize": "^0.8.1", - "@emotion/unitless": "^0.8.1", - "@emotion/utils": "^1.2.1", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/sheet": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", - "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" - }, - "node_modules/@emotion/styled": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", - "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.11.0", - "@emotion/is-prop-valid": "^1.2.1", - "@emotion/serialize": "^1.1.2", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", - "@emotion/utils": "^1.2.1" - }, - "peerDependencies": { - "@emotion/react": "^11.0.0-rc.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", - "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", - "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", - "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@eslint/eslintrc/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.55.0.tgz", - "integrity": "sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", - "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", - "dependencies": { - "@floating-ui/utils": "^0.2.7" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.10", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", - "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.7" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", - "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" - }, - "node_modules/@fullcalendar/core": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.8.tgz", - "integrity": "sha512-i8JBIvZCWGO9dsMEDcx9bnsQZ9PtGSJdOXGgWbhLaGq2iq41OBdp9g9gM4b/Otv2oK8bL5Gl6CsMmb/HkDtA6Q==", - "dependencies": { - "preact": "~10.12.1" - } - }, - "node_modules/@fullcalendar/daygrid": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.8.tgz", - "integrity": "sha512-kCZxQFKb9Vqa3CZRX0v7rMSJ2mlTt4gDpyLfiNJKxUAq7W51uKurPaFZWicaXy1ESHVBxKNlbx5uNjBpyu50JQ==", - "peerDependencies": { - "@fullcalendar/core": "~6.1.8" - } - }, - "node_modules/@fullcalendar/list": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.8.tgz", - "integrity": "sha512-10N0T/vCtId1cE3JGLpnbAivWVnaWCCkVO7wmbsyr5Y+I939kr/zq4BUNwBoP/xSFVVxx59FETh3iyA+MkV8Fw==", - "peerDependencies": { - "@fullcalendar/core": "~6.1.8" - } - }, - "node_modules/@fullcalendar/timegrid": { - "version": "6.1.8", - "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.8.tgz", - "integrity": "sha512-3+3KHHCoNcaLs/gQt004hAqICbY5+WAffrZ0ePv+80HFB1OVh8BQ5XXLHSOUbTvXdgtUTcfBHuw9fhO31kt5gA==", - "dependencies": { - "@fullcalendar/daygrid": "~6.1.8" - }, - "peerDependencies": { - "@fullcalendar/core": "~6.1.8" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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==", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/console/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@jest/console/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/console/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==" - }, - "node_modules/@jest/console/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@jest/core/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/core/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==" - }, - "node_modules/@jest/core/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/core/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.6.1.tgz", - "integrity": "sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==", - "dependencies": { - "jest-get-type": "^29.4.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/expect-utils/node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^9.0.1", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@jest/reporters/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/reporters/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==" - }, - "node_modules/@jest/reporters/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/reporters/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/source-map/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@jest/transform/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/transform/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==" - }, - "node_modules/@jest/transform/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/transform/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/transform/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@jest/types/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/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==" - }, - "node_modules/@jest/types/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" - }, - "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==", - "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.16.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", - "integrity": "sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ==", - "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==", - "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.173", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.173.tgz", - "integrity": "sha512-Gt5zopIWwxDgGy/MXcp6GueD84xFFugFai4hYiXY0zowJpTVnIrTQCQXV004Q7rejJ7aaCntX9hpPJqCrioshA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.40", - "@mui/system": "^5.16.5", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.5", - "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.16.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", - "integrity": "sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/core-downloads-tracker": "^5.16.7", - "@mui/system": "^5.16.7", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.6", - "@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": "^18.3.1", - "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", - "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/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@mui/private-theming": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz", - "integrity": "sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.16.6", - "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" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/styled-engine": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz", - "integrity": "sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@emotion/cache": "^11.11.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.4.1", - "@emotion/styled": "^11.3.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - } - } - }, - "node_modules/@mui/system": { - "version": "5.16.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz", - "integrity": "sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA==", - "dependencies": { - "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.16.6", - "@mui/styled-engine": "^5.16.6", - "@mui/types": "^7.2.15", - "@mui/utils": "^5.16.6", - "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", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@emotion/react": { - "optional": true - }, - "@emotion/styled": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/types": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.16.tgz", - "integrity": "sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag==", - "peerDependencies": { - "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils": { - "version": "5.16.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz", - "integrity": "sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA==", - "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": "^18.3.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" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@mui/utils/node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" - }, - "node_modules/@mui/x-data-grid": { - "version": "6.20.4", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.20.4.tgz", - "integrity": "sha512-I0JhinVV4e25hD2dB+R6biPBtpGeFrXf8RwlMPQbr9gUggPmPmNtWKo8Kk2PtBBMlGtdMAgHWe7PqhmucUxU1w==", - "dependencies": { - "@babel/runtime": "^7.23.2", - "@mui/utils": "^5.14.16", - "clsx": "^2.0.0", - "prop-types": "^15.8.1", - "reselect": "^4.1.8" - }, - "engines": { - "node": ">=14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui" - }, - "peerDependencies": { - "@mui/material": "^5.4.1", - "@mui/system": "^5.4.1", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - } - }, - "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/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", - "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", - "dependencies": { - "eslint-scope": "5.1.1" - } - }, - "node_modules/@nicolo-ribaudo/semver-v6": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", - "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@nivo/annotations": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/annotations/-/annotations-0.83.0.tgz", - "integrity": "sha512-FkfCprk1a3WCCNcQOfI2+Ww7vqTP/nJjQDVhFYf1YAaEGwXi4+OO4uJAtKtNcGE5cJWdOp+f0Gt4aNPGx7RtEw==", - "dependencies": { - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2", - "@types/prop-types": "^15.7.2", - "lodash": "^4.17.21", - "prop-types": "^15.7.2" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/arcs": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/arcs/-/arcs-0.83.0.tgz", - "integrity": "sha512-UcbNbtp28lbI5V/Sm6TIgYzZmtuhSxW3eTma+YBsgXi1AN/THSwEg0gSV8owyDT/8kaL+jcBQ6c54gzSLClhkw==", - "dependencies": { - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2", - "@types/d3-shape": "^2.0.0", - "d3-shape": "^1.3.5" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/axes": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/axes/-/axes-0.83.0.tgz", - "integrity": "sha512-rHMl+DdXQlY2wl7VCSQNcJi4QNISUWOkcWzJeJeVaYR73Z13SVGgiC7kW0czJuogDTSnDAJ/EcFCGmyGVuznGQ==", - "dependencies": { - "@nivo/core": "0.83.0", - "@nivo/scales": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2", - "@types/d3-format": "^1.4.1", - "@types/d3-time-format": "^2.3.1", - "@types/prop-types": "^15.7.2", - "d3-format": "^1.4.4", - "d3-time-format": "^3.0.0", - "prop-types": "^15.7.2" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/bar": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/bar/-/bar-0.83.0.tgz", - "integrity": "sha512-QXN6BcT1PiT/YViyoDU4G5mytbOUP1jYbuQmJhDDxKPMLNcZ/pHfThedRGVfDoD1poHBRJtV6mbgeCpAVmlTtw==", - "dependencies": { - "@nivo/annotations": "0.83.0", - "@nivo/axes": "0.83.0", - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@nivo/legends": "0.83.0", - "@nivo/scales": "0.83.0", - "@nivo/tooltip": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2", - "@types/d3-scale": "^3.2.3", - "@types/d3-shape": "^2.0.0", - "d3-scale": "^3.2.3", - "d3-shape": "^1.3.5", - "lodash": "^4.17.21" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/colors": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.83.0.tgz", - "integrity": "sha512-n34LWYtE2hbd1fdCDP7TCHNZdbiO1PwcvXLo0VsKK5lNPY/FA5SXA7Z9Ubl/ChSwBwbzAsaAhjTy8KzKzSjDcA==", - "dependencies": { - "@nivo/core": "0.83.0", - "@types/d3-color": "^2.0.0", - "@types/d3-scale": "^3.2.3", - "@types/d3-scale-chromatic": "^2.0.0", - "@types/prop-types": "^15.7.2", - "d3-color": "^3.1.0", - "d3-scale": "^3.2.3", - "d3-scale-chromatic": "^2.0.0", - "lodash": "^4.17.21", - "prop-types": "^15.7.2" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/core": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.83.0.tgz", - "integrity": "sha512-I9fjZAbIPz41JA2WP8Avsud/xk0iiM1nWUzcvZBDebBGFDB5Y1lrldUt9l5kvOeMth3Qj/1lVFTiJxQuojxH4Q==", - "dependencies": { - "@nivo/recompose": "0.83.0", - "@nivo/tooltip": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2", - "@types/d3-shape": "^2.0.0", - "d3-color": "^3.1.0", - "d3-format": "^1.4.4", - "d3-interpolate": "^2.0.1", - "d3-scale": "^3.2.3", - "d3-scale-chromatic": "^2.0.0", - "d3-shape": "^1.3.5", - "d3-time-format": "^3.0.0", - "lodash": "^4.17.21" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nivo/donate" - }, - "peerDependencies": { - "prop-types": ">= 15.5.10 < 16.0.0", - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/geo": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/geo/-/geo-0.83.0.tgz", - "integrity": "sha512-Jl9EdhwYVGGmZynCTsvrAeANqKdZMZz5yeunHjQlG9tfb0k2KTevI9w+rrW0SO6XXIA+p8mCm6laGbIqEr+Ezw==", - "dependencies": { - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@nivo/legends": "0.83.0", - "@nivo/tooltip": "0.83.0", - "d3-format": "^1.4.4", - "d3-geo": "^1.11.3", - "lodash": "^4.17.21", - "prop-types": "^15.7.2" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/legends": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/legends/-/legends-0.83.0.tgz", - "integrity": "sha512-WWl3/hTpFJ7/2L0RG53Gbr9KQk+ZjD71a/RIPMJ5ArEvAvKKfWuWQCtEm3FpqAazX8eYMnsQ3Pi17c8ohEIXRg==", - "dependencies": { - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@types/d3-scale": "^3.2.3", - "@types/prop-types": "^15.7.2", - "d3-scale": "^3.2.3", - "prop-types": "^15.7.2" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/line": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/line/-/line-0.83.0.tgz", - "integrity": "sha512-tF/HcUM7dRf+0uk4E0Ywg7nMYD7NsmF03tp5nIbBSB35PRFoVnczxlzHWw2qoRYwUhCFy2gL6Dyf/6kTHXnIdA==", - "dependencies": { - "@nivo/annotations": "0.83.0", - "@nivo/axes": "0.83.0", - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@nivo/legends": "0.83.0", - "@nivo/scales": "0.83.0", - "@nivo/tooltip": "0.83.0", - "@nivo/voronoi": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2", - "d3-shape": "^1.3.5", - "prop-types": "^15.7.2" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/pie": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/pie/-/pie-0.83.0.tgz", - "integrity": "sha512-98j/h4T/QmQ10gFh1cMh6uLfcGurFcYZN97Lu3ig3D9bbsLuLgpUED/d5O+8w7qLJtnlg3zptqy+N9UgRAqbOg==", - "dependencies": { - "@nivo/arcs": "0.83.0", - "@nivo/colors": "0.83.0", - "@nivo/core": "0.83.0", - "@nivo/legends": "0.83.0", - "@nivo/tooltip": "0.83.0", - "@types/d3-shape": "^2.0.0", - "d3-shape": "^1.3.5" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/recompose": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/recompose/-/recompose-0.83.0.tgz", - "integrity": "sha512-3cLEoi9ZoE4LTn6B98oUVd0MRAy5bWK7W3yb0u4EkjLoXXCRvUAI08Wr2AAagOzVOg5PmvghIDgvkz1tlFZTGQ==", - "dependencies": { - "@types/prop-types": "^15.7.2", - "@types/react-lifecycles-compat": "^3.0.1", - "prop-types": "^15.7.2", - "react-lifecycles-compat": "^3.0.4" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "node_modules/@nivo/scales": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/scales/-/scales-0.83.0.tgz", - "integrity": "sha512-DZn5IcMJErCURDuQPmYltu6GTPphTDVLMvbeN/Id/VSVbD1uYKvdXPKUNOe/N2IvnE8wjjCPv88DLcRhw6VTVg==", - "dependencies": { - "@types/d3-scale": "^3.2.3", - "@types/d3-time": "^1.1.1", - "@types/d3-time-format": "^3.0.0", - "d3-scale": "^3.2.3", - "d3-time": "^1.0.11", - "d3-time-format": "^3.0.0", - "lodash": "^4.17.21" - } - }, - "node_modules/@nivo/scales/node_modules/@types/d3-time-format": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.1.tgz", - "integrity": "sha512-5GIimz5IqaRsdnxs4YlyTZPwAMfALu/wA4jqSiuqgdbCxUZ2WjrnwANqOtoBJQgeaUTdYNfALJO0Yb0YrDqduA==" - }, - "node_modules/@nivo/tooltip": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.83.0.tgz", - "integrity": "sha512-HewujRqZNmcVnAv/LPLVyYwViad+rYTsFMdzLRzuTPq2hju1R+cfxokTomunG8e1SDtUPtULEVXtPg2ATIzNYg==", - "dependencies": { - "@nivo/core": "0.83.0", - "@react-spring/web": "9.4.5 || ^9.7.2" - } - }, - "node_modules/@nivo/voronoi": { - "version": "0.83.0", - "resolved": "https://registry.npmjs.org/@nivo/voronoi/-/voronoi-0.83.0.tgz", - "integrity": "sha512-wVpskesX2IEJHG82v0rbIUZ2y3MpvzTYM+DQl2gx8K1/Hucxwzk5ltg/aF9e/gfKU8gt24uct3M9TQTEfyhzgg==", - "dependencies": { - "@nivo/core": "0.83.0", - "@types/d3-delaunay": "^5.3.0", - "@types/d3-scale": "^3.2.3", - "d3-delaunay": "^5.3.0", - "d3-scale": "^3.2.3" - }, - "peerDependencies": { - "react": ">= 16.14.0 < 19.0.0" - } - }, - "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==", - "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==", - "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==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", - "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", - "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.23.3", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.4", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.13" - }, - "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <4.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" - }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } - } - }, - "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==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } - }, - "node_modules/@react-spring/animated": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.3.tgz", - "integrity": "sha512-5CWeNJt9pNgyvuSzQH+uy2pvTg8Y4/OisoscZIR8/ZNLIOI+CatFBhGZpDGTF/OzdNFsAoGk3wiUYTwoJ0YIvw==", - "dependencies": { - "@react-spring/shared": "~9.7.3", - "@react-spring/types": "~9.7.3" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@react-spring/core": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.3.tgz", - "integrity": "sha512-IqFdPVf3ZOC1Cx7+M0cXf4odNLxDC+n7IN3MDcVCTIOSBfqEcBebSv+vlY5AhM0zw05PDbjKrNmBpzv/AqpjnQ==", - "dependencies": { - "@react-spring/animated": "~9.7.3", - "@react-spring/shared": "~9.7.3", - "@react-spring/types": "~9.7.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-spring/donate" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@react-spring/shared": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.3.tgz", - "integrity": "sha512-NEopD+9S5xYyQ0pGtioacLhL2luflh6HACSSDUZOwLHoxA5eku1UPuqcJqjwSD6luKjjLfiLOspxo43FUHKKSA==", - "dependencies": { - "@react-spring/types": "~9.7.3" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@react-spring/types": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.3.tgz", - "integrity": "sha512-Kpx/fQ/ZFX31OtlqVEFfgaD1ACzul4NksrvIgYfIFq9JpDHFwQkMVZ10tbo0FU/grje4rcL4EIrjekl3kYwgWw==" - }, - "node_modules/@react-spring/web": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/@react-spring/web/-/web-9.7.3.tgz", - "integrity": "sha512-BXt6BpS9aJL/QdVqEIX9YoUy8CE6TJrU0mNCqSoxdXlIeNcEBWOfIyE6B14ENNsyQKS3wOWkiJfco0tCr/9tUg==", - "dependencies": { - "@react-spring/animated": "~9.7.3", - "@react-spring/core": "~9.7.3", - "@react-spring/shared": "~9.7.3", - "@react-spring/types": "~9.7.3" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@remix-run/router": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.1.tgz", - "integrity": "sha512-bgVQM4ZJ2u2CM8k1ey70o1ePFXsEzYVZoWghh6WjM8p59jQ7HxzbHW4SbnWFG7V9ig9chLawQxDTZ3xzOF8MkQ==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@rollup/plugin-babel": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", - "integrity": "sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==", - "dependencies": { - "@babel/helper-module-imports": "^7.10.4", - "@rollup/pluginutils": "^3.1.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "@types/babel__core": "^7.1.9", - "rollup": "^1.20.0||^2.0.0" - }, - "peerDependenciesMeta": { - "@types/babel__core": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz", - "integrity": "sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "@types/resolve": "1.17.1", - "builtin-modules": "^3.1.0", - "deepmerge": "^4.2.2", - "is-module": "^1.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/plugin-replace": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz", - "integrity": "sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==", - "dependencies": { - "@rollup/pluginutils": "^3.1.0", - "magic-string": "^0.25.7" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, - "node_modules/@rollup/pluginutils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", - "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", - "dependencies": { - "@types/estree": "0.0.39", - "estree-walker": "^1.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0" - } - }, - "node_modules/@rollup/pluginutils/node_modules/@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" - }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz", - "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==" - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@surma/rollup-plugin-off-main-thread": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", - "integrity": "sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==", - "dependencies": { - "ejs": "^3.1.6", - "json5": "^2.2.0", - "magic-string": "^0.25.0", - "string.prototype.matchall": "^4.0.6" - } - }, - "node_modules/@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-plugin-transform-svg-component": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", - "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/babel-preset": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", - "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", - "dependencies": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", - "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", - "dependencies": { - "@svgr/plugin-jsx": "^5.5.0", - "camelcase": "^6.2.0", - "cosmiconfig": "^7.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/hast-util-to-babel-ast": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", - "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", - "dependencies": { - "@babel/types": "^7.12.6" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-jsx": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", - "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", - "dependencies": { - "@babel/core": "^7.12.3", - "@svgr/babel-preset": "^5.5.0", - "@svgr/hast-util-to-babel-ast": "^5.5.0", - "svg-parser": "^2.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/plugin-svgo": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", - "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "deepmerge": "^4.2.2", - "svgo": "^1.2.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@svgr/webpack": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", - "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/plugin-transform-react-constant-elements": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/preset-react": "^7.12.5", - "@svgr/core": "^5.5.0", - "@svgr/plugin-jsx": "^5.5.0", - "@svgr/plugin-svgo": "^5.5.0", - "loader-utils": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/gregberge" - } - }, - "node_modules/@testing-library/dom": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", - "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@testing-library/dom/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==", - "peer": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/dom/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "peer": true, - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/@testing-library/dom/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "peer": true, - "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/@testing-library/dom/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==", - "peer": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/dom/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==", - "peer": true - }, - "node_modules/@testing-library/dom/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==", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/dom/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==", - "peer": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "5.16.5", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", - "integrity": "sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA==", - "dependencies": { - "@adobe/css-tools": "^4.0.1", - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=8", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/jest-dom/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/jest-dom/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==" - }, - "node_modules/@testing-library/jest-dom/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/jest-dom/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react": { - "version": "13.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.4.0.tgz", - "integrity": "sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "^18.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/@testing-library/react/node_modules/@testing-library/dom": { - "version": "8.20.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", - "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/react/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@testing-library/react/node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dependencies": { - "deep-equal": "^2.0.5" - } - }, - "node_modules/@testing-library/react/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@testing-library/react/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@testing-library/react/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==" - }, - "node_modules/@testing-library/react/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "engines": { - "node": ">= 6" - } - }, - "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==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@types/aria-query": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", - "integrity": "sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==" - }, - "node_modules/@types/babel__core": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", - "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", - "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/cookie": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.4.tgz", - "integrity": "sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==" - }, - "node_modules/@types/d3-color": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz", - "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==" - }, - "node_modules/@types/d3-delaunay": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-5.3.1.tgz", - "integrity": "sha512-F6itHi2DxdatHil1rJ2yEFUNhejj8+0Acd55LZ6Ggwbdoks0+DxVY2cawNj16sjCBiWvubVlh6eBMVsYRNGLew==" - }, - "node_modules/@types/d3-format": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.2.tgz", - "integrity": "sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ==" - }, - "node_modules/@types/d3-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.2.tgz", - "integrity": "sha512-3YHpvDw9LzONaJzejXLOwZ3LqwwkoXb9LI2YN7Hbd6pkGo5nIlJ09ul4bQhBN4hQZJKmUpX8HkVqbzgUKY48cg==" - }, - "node_modules/@types/d3-scale": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", - "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", - "dependencies": { - "@types/d3-time": "^2" - } - }, - "node_modules/@types/d3-scale-chromatic": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-2.0.1.tgz", - "integrity": "sha512-3EuZlbPu+pvclZcb1DhlymTWT2W+lYsRKBjvkH2ojDbCWDYavifqu1vYX9WGzlPgCgcS4Alhk1+zapXbGEGylQ==" - }, - "node_modules/@types/d3-scale/node_modules/@types/d3-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", - "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==" - }, - "node_modules/@types/d3-shape": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz", - "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==", - "dependencies": { - "@types/d3-path": "^2" - } - }, - "node_modules/@types/d3-time": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.1.1.tgz", - "integrity": "sha512-ULX7LoqXTCYtM+tLYOaeAJK7IwCT+4Gxlm2MaH0ErKLi07R5lh8NHCAyWcDkCCmx1AfRcBEV6H9QE9R25uP7jw==" - }, - "node_modules/@types/d3-time-format": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.1.tgz", - "integrity": "sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA==" - }, - "node_modules/@types/eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw==", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" - }, - "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.35", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.35.tgz", - "integrity": "sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", - "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" - }, - "node_modules/@types/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==" - }, - "node_modules/@types/http-proxy": { - "version": "1.17.11", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", - "integrity": "sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "29.5.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.3.tgz", - "integrity": "sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/jest/node_modules/@jest/schemas": { - "version": "29.6.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.0.tgz", - "integrity": "sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/@jest/types": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", - "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", - "dependencies": { - "@jest/schemas": "^29.6.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" - }, - "node_modules/@types/jest/node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/jest/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/@types/jest/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@types/jest/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==" - }, - "node_modules/@types/jest/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/expect": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.6.1.tgz", - "integrity": "sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==", - "dependencies": { - "@jest/expect-utils": "^29.6.1", - "@types/node": "*", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.6.1", - "jest-message-util": "^29.6.1", - "jest-util": "^29.6.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/jest/node_modules/jest-diff": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.6.1.tgz", - "integrity": "sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-matcher-utils": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.6.1.tgz", - "integrity": "sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.6.1", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.6.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-message-util": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.1.tgz", - "integrity": "sha512-KoAW2zAmNSd3Gk88uJ56qXUWbFk787QKmjjJVOjtGFmmGSZgDBrlIL4AfQw1xyMYPNVD7dNInfIbur9B2rd/wQ==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.6.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/jest-util": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.1.tgz", - "integrity": "sha512-NRFCcjc+/uO3ijUVyNOQJluf8PtGCe/W6cix36+M3cTFgiYqFOOW5MgN4JOOcvbUhcKTYVd1CvHz/LWi8d16Mg==", - "dependencies": { - "@jest/types": "^29.6.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/pretty-format": { - "version": "29.6.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.1.tgz", - "integrity": "sha512-7jRj+yXO0W7e4/tSJKoR7HRIHLPPjtNaUGG2xxKQnGvPNRkgWcQ0AZX6P4KBRJN4FcTBWb3sa7DVUJmocYuoog==", - "dependencies": { - "@jest/schemas": "^29.6.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "node_modules/@types/jest/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==" - }, - "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==" - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" - }, - "node_modules/@types/node": { - "version": "20.4.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz", - "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==" - }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" - }, - "node_modules/@types/prettier": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", - "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" - }, - "node_modules/@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/react": { - "version": "18.2.15", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz", - "integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.2.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.7.tgz", - "integrity": "sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-lifecycles-compat": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/react-lifecycles-compat/-/react-lifecycles-compat-3.0.1.tgz", - "integrity": "sha512-4KiU5s1Go4xRbf7t6VxUUpBeN5PGjpjpBv9VvET4uiPHC500VNYBclU13f8ehHkHoZL39b2cfwHu6RzbV3b44A==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-transition-group": { - "version": "4.4.11", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", - "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/resolve": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", - "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" - }, - "node_modules/@types/scheduler": { - "version": "0.16.3", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", - "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" - }, - "node_modules/@types/semver": { - "version": "7.5.6", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz", - "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==" - }, - "node_modules/@types/send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", - "integrity": "sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.2.tgz", - "integrity": "sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" - }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.8", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.8.tgz", - "integrity": "sha512-NRfJE9Cgpmu4fx716q9SYmU4jxxhYRU1BQo239Txt/9N3EC745XZX1Yl7h/SBIDlo1ANVOCRB4YDXjaQdoKCHQ==", - "dependencies": { - "@types/jest": "*" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", - "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" - }, - "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "16.0.5", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", - "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", - "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", - "dependencies": { - "@typescript-eslint/utils": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "node_modules/a-sync-waterfall": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", - "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "peerDependencies": { - "acorn": "^8" - } - }, - "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==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.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==", - "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/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/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==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==" - }, - "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==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "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==" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==" - }, - "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "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==" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "node_modules/asynciterator.prototype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", - "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", - "dependencies": { - "has-symbols": "^1.0.3" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.14", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", - "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - ], - "dependencies": { - "browserslist": "^4.21.5", - "caniuse-lite": "^1.0.30001464", - "fraction.js": "^4.2.0", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "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.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-jest/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/babel-jest/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/babel-jest/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==" - }, - "node_modules/babel-jest/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-jest/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", - "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" - }, - "engines": { - "node": ">= 8.9" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" - } - }, - "node_modules/babel-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/babel-plugin-named-asset-import": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz", - "integrity": "sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q==", - "peerDependencies": { - "@babel/core": "^7.1.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz", - "integrity": "sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==", - "dependencies": { - "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.1", - "@nicolo-ribaudo/semver-v6": "^6.3.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz", - "integrity": "sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.1", - "core-js-compat": "^3.31.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz", - "integrity": "sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/babel-plugin-transform-react-remove-prop-types": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz", - "integrity": "sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA==" - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-react-app": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-react-app/-/babel-preset-react-app-10.0.1.tgz", - "integrity": "sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/plugin-proposal-class-properties": "^7.16.0", - "@babel/plugin-proposal-decorators": "^7.16.4", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-numeric-separator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@babel/plugin-proposal-private-methods": "^7.16.0", - "@babel/plugin-transform-flow-strip-types": "^7.16.0", - "@babel/plugin-transform-react-display-name": "^7.16.0", - "@babel/plugin-transform-runtime": "^7.16.4", - "@babel/preset-env": "^7.16.4", - "@babel/preset-react": "^7.16.0", - "@babel/preset-typescript": "^7.16.0", - "@babel/runtime": "^7.16.3", - "babel-plugin-macros": "^3.1.0", - "babel-plugin-transform-react-remove-prop-types": "^0.4.24" - } - }, - "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==" - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "node_modules/bfj": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", - "integrity": "sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw==", - "dependencies": { - "bluebird": "^3.5.5", - "check-types": "^11.1.1", - "hoopy": "^0.1.4", - "tryer": "^1.0.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "^4.0.1", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bonjour-service": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz", - "integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==", - "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "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==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "node_modules/browserslist": { - "version": "4.21.9", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", - "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", - "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" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001503", - "electron-to-chromium": "^1.4.431", - "node-releases": "^2.0.12", - "update-browserslist-db": "^1.0.11" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", - "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001515", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz", - "integrity": "sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA==", - "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" - } - ] - }, - "node_modules/case-sensitive-paths-webpack-plugin": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", - "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/check-types": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/check-types/-/check-types-11.2.2.tgz", - "integrity": "sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA==" - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "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==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", - "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" - }, - "node_modules/classnames": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz", - "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==" - }, - "node_modules/clean-css": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.2.tgz", - "integrity": "sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==" - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "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==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "^4.0.1", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==" - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "engines": { - "node": ">= 0.6" - } - }, - "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==" - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/core-js": { - "version": "3.31.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.31.1.tgz", - "integrity": "sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-compat": { - "version": "3.31.1", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz", - "integrity": "sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==", - "dependencies": { - "browserslist": "^4.21.9" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.31.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.31.1.tgz", - "integrity": "sha512-w+C62kvWti0EPs4KPMCMVv9DriHSXfQOCQ94bGGBiEW5rrbtt/Rz8n5Krhfw9cpFyzXBjf3DB3QnPdEzGDY4Fw==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "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.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/css-blank-pseudo": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz", - "integrity": "sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-blank-pseudo": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "node_modules/css-has-pseudo": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz", - "integrity": "sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "bin": { - "css-has-pseudo": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-loader": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.8.1.tgz", - "integrity": "sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g==", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.21", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.3", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.8" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", - "dependencies": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/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==" - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/css-minimizer-webpack-plugin/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-prefers-color-scheme": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz", - "integrity": "sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA==", - "bin": { - "css-prefers-color-scheme": "dist/cli.cjs" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==" - }, - "node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dependencies": { - "mdn-data": "2.0.4", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" - }, - "node_modules/cssdb": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.6.0.tgz", - "integrity": "sha512-Nna7rph8V0jC6+JBY4Vk4ndErUmfJfV6NJCaZdurL0omggabiy+QB2HCQtu5c/ACLZ0I7REv7A4QyPIoYzZx0w==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - } - ] - }, - "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==", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", - "dependencies": { - "cssnano-preset-default": "^5.2.14", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", - "dependencies": { - "css-declaration-sorter": "^6.3.1", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.1", - "postcss-convert-values": "^5.1.3", - "postcss-discard-comments": "^5.1.2", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.7", - "postcss-merge-rules": "^5.1.4", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.4", - "postcss-minify-selectors": "^5.2.1", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.1", - "postcss-normalize-repeat-style": "^5.1.1", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.1", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.3", - "postcss-reduce-initial": "^5.1.2", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/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==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/csso/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==" - }, - "node_modules/csso/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" - }, - "node_modules/d3-array": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", - "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" - }, - "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==", - "engines": { - "node": ">=12" - } - }, - "node_modules/d3-delaunay": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", - "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", - "dependencies": { - "delaunator": "4" - } - }, - "node_modules/d3-format": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", - "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" - }, - "node_modules/d3-geo": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.12.1.tgz", - "integrity": "sha512-XG4d1c/UJSEX9NfU02KwBL6BYPj8YKHxgBEw5om2ZnTRSbIcego6dhHwcxuSR3clxh0EpE38os1DVPOmnYtTPg==", - "dependencies": { - "d3-array": "1" - } - }, - "node_modules/d3-interpolate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", - "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", - "dependencies": { - "d3-color": "1 - 3" - } - }, - "node_modules/d3-path": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" - }, - "node_modules/d3-scale": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", - "integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==", - "dependencies": { - "d3-array": "^2.3.0", - "d3-format": "1 - 2", - "d3-interpolate": "1.2.0 - 2", - "d3-time": "^2.1.1", - "d3-time-format": "2 - 3" - } - }, - "node_modules/d3-scale-chromatic": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz", - "integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==", - "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 2" - } - }, - "node_modules/d3-scale/node_modules/d3-array": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", - "dependencies": { - "internmap": "^1.0.0" - } - }, - "node_modules/d3-scale/node_modules/d3-time": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.1.1.tgz", - "integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==", - "dependencies": { - "d3-array": "2" - } - }, - "node_modules/d3-shape": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", - "dependencies": { - "d3-path": "1" - } - }, - "node_modules/d3-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", - "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" - }, - "node_modules/d3-time-format": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", - "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", - "dependencies": { - "d3-time": "1 - 2" - } - }, - "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==" - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/dayjs": { - "version": "1.11.20", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.20.tgz", - "integrity": "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==" - }, - "node_modules/deep-equal": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.2.tgz", - "integrity": "sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.1", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", - "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "engines": { - "node": ">=8" - } - }, - "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==", - "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/delaunator": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", - "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "node_modules/detect-port-alt": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", - "dependencies": { - "address": "^1.0.1", - "debug": "^4.0.1" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.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==", - "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==" - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" - }, - "node_modules/dns-packet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", - "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==" - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dependencies": { - "utila": "~0.4" - } - }, - "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==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==" - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.460", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.460.tgz", - "integrity": "sha512-kKiHnbrHME7z8E6AYaw0ehyxY5+hdaRmeUbjBO22LZMdqTYCO29EvF0T1cQ3pJ1RN5fyMcHl1Lmcsdt9WWJpJQ==" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "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==" - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "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==", - "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==", - "dependencies": { - "stackframe": "^1.3.4" - } - }, - "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-iterator-helpers": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", - "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", - "dependencies": { - "asynciterator.prototype": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.1", - "es-set-tostringtag": "^2.0.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.2.1", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.0.1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==" - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/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==", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "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==", - "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==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "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==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", - "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.14.2" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "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==", - "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==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jest": { - "version": "25.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", - "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", - "dependencies": { - "@typescript-eslint/experimental-utils": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", - "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", - "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", - "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.15", - "hasown": "^2.0.0", - "jsx-ast-utils": "^3.3.5", - "language-tags": "^1.0.9", - "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.32.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", - "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "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/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", - "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", - "dependencies": { - "is-core-module": "^2.9.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==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-simple-import-sort": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz", - "integrity": "sha512-bXgJQ+lqhtQBCuWY/FUWdB27j4+lqcvXv5rUARkzbeWLwea+S5eBZEQrhnO+WgX3ZoJHVj0cn943iyXwByHHQw==", - "dev": true, - "peerDependencies": { - "eslint": ">=5.0.0" - } - }, - "node_modules/eslint-plugin-testing-library": { - "version": "5.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", - "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", - "dependencies": { - "@typescript-eslint/utils": "^5.58.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0", - "npm": ">=6" - }, - "peerDependencies": { - "eslint": "^7.5.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-scope/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "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==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", - "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/eslint-webpack-plugin/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/eslint-webpack-plugin/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==" - }, - "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/eslint/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/eslint/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==" - }, - "node_modules/eslint/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/eslint/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/eslint/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/eslint/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "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==", - "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==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", - "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "^4.0.1", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, - "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==" - }, - "node_modules/fast-glob": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", - "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "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==" - }, - "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==" - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dependencies": { - "bser": "2.1.1" - } - }, - "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==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/filesize": { - "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dependencies": { - "debug": "^4.0.1", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "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==" - }, - "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==", - "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.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^9.0.1", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/fork-ts-checker-webpack-plugin/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/formik": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.2.tgz", - "integrity": "sha512-C6nx0hifW2uENP3M6HpPmnAE6HFWCcd8/sqBZEOHZY6lpHJ5qehsfAy43ktpFLEmkBmhiZDei726utcUB9leqg==", - "funding": [ - { - "type": "individual", - "url": "https://opencollective.com/formik" - } - ], - "dependencies": { - "deepmerge": "^2.1.1", - "hoist-non-react-statics": "^3.3.0", - "lodash": "^4.17.21", - "lodash-es": "^4.17.21", - "react-fast-compare": "^2.0.1", - "tiny-warning": "^1.0.2", - "tslib": "^2.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/formik/node_modules/deepmerge": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", - "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fraction.js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", - "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://www.patreon.com/infusion" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.4.tgz", - "integrity": "sha512-INM/fWAxMICjttnD0DX1rBvinKskj5G1w+oy/pnm9u/tSlnBrzFonJMcalKJ30P8RRsPzKcCG7Q8l0jx5Fh9YQ==" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==" - }, - "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", - "dependencies": { - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "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==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "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==", - "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==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dependencies": { - "define-properties": "^1.1.3" - }, - "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==", - "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/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "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==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "node_modules/harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "bin": { - "he": "bin/he" - } - }, - "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==", - "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==" - }, - "node_modules/hoopy": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", - "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-entities": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ] - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", - "license": "MIT", - "dependencies": { - "void-elements": "3.1.0" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", - "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "webpack": "^5.20.0" - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/i18next": { - "version": "23.16.8", - "resolved": "https://registry.npmmirror.com/i18next/-/i18next-23.16.8.tgz", - "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", - "funding": [ - { - "type": "individual", - "url": "https://locize.com" - }, - { - "type": "individual", - "url": "https://locize.com/i18next.html" - }, - { - "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" - } - ], - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.23.2" - } - }, - "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==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/idb": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", - "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" - }, - "node_modules/identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==", - "dependencies": { - "harmony-reflect": "^1.4.6" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "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==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/internmap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==" - }, - "node_modules/ipaddr.js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "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==" - }, - "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "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==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-finalizationregistry": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", - "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.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==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==" - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "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==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-root": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", - "dependencies": { - "which-typed-array": "^1.1.11" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/iterator.prototype": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", - "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", - "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" - } - }, - "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jake/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jake/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jake/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==" - }, - "node_modules/jake/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jake/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-circus/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-circus/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==" - }, - "node_modules/jest-circus/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-circus/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-cli/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-cli/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-cli/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-cli/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==" - }, - "node_modules/jest-cli/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-cli/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^9.0.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-config/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-config/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==" - }, - "node_modules/jest-config/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-diff/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-diff/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-diff/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==" - }, - "node_modules/jest-diff/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-diff/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-each/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-each/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-each/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==" - }, - "node_modules/jest-each/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-each/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-jasmine2/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-jasmine2/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==" - }, - "node_modules/jest-jasmine2/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-jasmine2/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-matcher-utils/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-matcher-utils/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==" - }, - "node_modules/jest-matcher-utils/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-matcher-utils/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-message-util/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-message-util/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==" - }, - "node_modules/jest-message-util/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-message-util/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-resolve/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-resolve/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-resolve/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==" - }, - "node_modules/jest-resolve/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-runner/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runner/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==" - }, - "node_modules/jest-runner/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^9.0.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-runtime/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-runtime/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==" - }, - "node_modules/jest-runtime/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runtime/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-snapshot/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-snapshot/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==" - }, - "node_modules/jest-snapshot/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-snapshot/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-util/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-util/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-util/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==" - }, - "node_modules/jest-util/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-util/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-validate/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/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==" - }, - "node_modules/jest-validate/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz", - "integrity": "sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw==", - "dependencies": { - "ansi-escapes": "^4.3.1", - "chalk": "^4.0.0", - "jest-regex-util": "^28.0.0", - "jest-watcher": "^28.0.0", - "slash": "^4.0.0", - "string-length": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "jest": "^27.0.0 || ^28.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/console/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", - "dependencies": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/jest-watch-typeahead/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-watch-typeahead/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watch-typeahead/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==" - }, - "node_modules/jest-watch-typeahead/node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-message-util/node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", - "dependencies": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher/node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest-watch-typeahead/node_modules/jest-watcher/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==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-watch-typeahead/node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "node_modules/jest-watch-typeahead/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watch-typeahead/node_modules/string-length": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-5.0.1.tgz", - "integrity": "sha512-9Ep08KAMUn0OadnVaBuRdE2l615CQ508kr0XMadjClfYpdCyvrbFp6Taebo8yyxokQ4viUd/xPPUA4FGgUa0ow==", - "dependencies": { - "char-regex": "^2.0.0", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watch-typeahead/node_modules/string-length/node_modules/char-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-2.0.1.tgz", - "integrity": "sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw==", - "engines": { - "node": ">=12.20" - } - }, - "node_modules/jest-watch-typeahead/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==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/jest-watch-typeahead/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/jest-watcher/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-watcher/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==" - }, - "node_modules/jest-watcher/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-watcher/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.19.1.tgz", - "integrity": "sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg==", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "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==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "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==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "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==" - }, - "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==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "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/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/language-subtag-registry": { - "version": "0.3.22", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", - "integrity": "sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==" - }, - "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==", - "dependencies": { - "language-subtag-registry": "^0.3.20" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/launch-editor": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.0.tgz", - "integrity": "sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ==", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.7.3" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "engines": { - "node": ">=6" - } - }, - "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==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "engines": { - "node": ">=10" - } - }, - "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==" - }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "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==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" - }, - "node_modules/lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "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==" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==" - }, - "node_modules/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" - }, - "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==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.7.6", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz", - "integrity": "sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==", - "dependencies": { - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/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==" - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" - }, - "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" - }, - "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==", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/nunjucks": { - "version": "3.2.4", - "resolved": "https://registry.npmmirror.com/nunjucks/-/nunjucks-3.2.4.tgz", - "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", - "dependencies": { - "a-sync-waterfall": "^1.0.0", - "asap": "^2.0.3", - "commander": "^5.1.0" - }, - "bin": { - "nunjucks-precompile": "bin/precompile" - }, - "engines": { - "node": ">= 6.9.0" - }, - "peerDependencies": { - "chokidar": "^3.3.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/nunjucks/node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==" - }, - "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==", - "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==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "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==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", - "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" - } - }, - "node_modules/object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", - "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "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==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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==", - "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==", - "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": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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==", - "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==", - "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==" - }, - "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==", - "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/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "engines": { - "node": "14 || >=16.14" - } - }, - "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==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "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" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-attribute-case-insensitive": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.2.tgz", - "integrity": "sha512-XIidXV8fDr0kKt28vqki84fRK8VW8eTuIa4PChv2MqKuT6C9UjmSKzen6KaWhWEoYvwxFCa7n/tC1SZ3tyq4SQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-browser-comments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-browser-comments/-/postcss-browser-comments-4.0.0.tgz", - "integrity": "sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==", - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "browserslist": ">=4", - "postcss": ">=8" - } - }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-clamp": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": ">=7.6.0" - }, - "peerDependencies": { - "postcss": "^8.4.6" - } - }, - "node_modules/postcss-color-functional-notation": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.4.tgz", - "integrity": "sha512-2yrTAUZUab9s6CpxkxC4rVgFEVaR6/2Pipvi6qcgvnYiVqZcbDHEoBDhrXzyb7Efh2CCfHQNtcqWcIruDTIUeg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-color-hex-alpha": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.4.tgz", - "integrity": "sha512-nLo2DCRC9eE4w2JmuKgVA3fGL3d01kGq752pVALF68qpGLmx2Qrk91QTKkdUqqp45T1K1XV8IhQpcu1hoAQflQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-color-rebeccapurple": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.1.1.tgz", - "integrity": "sha512-pGxkuVEInwLHgkNxUc4sdg4g3py7zUeCQ9sMfwyHAT+Ezk8a4OaaVZ8lIY5+oNqA/BXXgLyXv0+5wHP68R79hg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-custom-media": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-8.0.2.tgz", - "integrity": "sha512-7yi25vDAoHAkbhAzX9dHx2yc6ntS4jQvejrNcC+csQJAXjj15e7VcWfMgLqBNAbOvqi5uIa9huOVwdHbf+sKqg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/postcss-custom-properties": { - "version": "12.1.11", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-12.1.11.tgz", - "integrity": "sha512-0IDJYhgU8xDv1KY6+VgUwuQkVtmYzRwu+dMjnmdMafXYv86SWqfxkc7qdDvWS38vsjaEtv8e0vGOUQrAiMBLpQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-custom-selectors": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-6.0.3.tgz", - "integrity": "sha512-fgVkmyiWDwmD3JbpCmB45SvvlCD6z9CG6Ie6Iere22W5aHea6oWa7EM2bpnv2Fj3I94L3VbtvX9KqwSi5aFzSg==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3" - } - }, - "node_modules/postcss-dir-pseudo-class": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.5.tgz", - "integrity": "sha512-eqn4m70P031PF7ZQIvSgy9RSJ5uI2171O/OO/zcRNYpJbvaeKFUlar1aJ7rmgiQtbm0FSPsRewjpdS0Oew7MPA==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-double-position-gradients": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.2.tgz", - "integrity": "sha512-GX+FuE/uBR6eskOK+4vkXgT6pDkexLokPaz/AbJna9s5Kzp/yl488pKPjhy0obB475ovfT1Wv8ho7U/cHNaRgQ==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-env-function": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/postcss-env-function/-/postcss-env-function-4.0.6.tgz", - "integrity": "sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-flexbugs-fixes": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-5.0.2.tgz", - "integrity": "sha512-18f9voByak7bTktR2QgDveglpn9DTbBWPUzSOe9g0N4WR/2eSt6Vrcbf0hmspvMI6YWGywz6B9f7jzpFNJJgnQ==", - "peerDependencies": { - "postcss": "^8.1.4" - } - }, - "node_modules/postcss-focus-visible": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz", - "integrity": "sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-focus-within": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz", - "integrity": "sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.9" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-font-variant": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-gap-properties": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-3.0.5.tgz", - "integrity": "sha512-IuE6gKSdoUNcvkGIqdtjtcMtZIFyXZhmFd5RUlg97iVEvp1BZKV5ngsAjCjrVy+14uhGBQl9tzmi1Qwq4kqVOg==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-image-set-function": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-4.0.7.tgz", - "integrity": "sha512-9T2r9rsvYzm5ndsBE8WgtrMlIT7VbtTfE7b3BQnudUqnBcBo7L758oc+o+pdj/dUV0l5wjwSdjeOH2DZtfv8qw==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "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==", - "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-initial": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-4.0.1.tgz", - "integrity": "sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ==", - "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==", - "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-lab-function": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-4.2.1.tgz", - "integrity": "sha512-xuXll4isR03CrQsmxyz92LJB2xX9n+pZJ5jE9JgcnmsCammLyKdlzrBin+25dy6wIjfhJpKBAN80gsTlCgRk2w==", - "dependencies": { - "@csstools/postcss-progressive-custom-properties": "^1.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-load-config": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", - "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", - "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^2.1.1" - }, - "engines": { - "node": ">= 14" - }, - "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/postcss-load-config/node_modules/yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", - "engines": { - "node": ">= 14" - } - }, - "node_modules/postcss-loader": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz", - "integrity": "sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q==", - "dependencies": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.5", - "semver": "^7.3.5" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - } - }, - "node_modules/postcss-logical": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", - "integrity": "sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g==", - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.4" - } - }, - "node_modules/postcss-media-minmax": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz", - "integrity": "sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-merge-longhand": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", - "dependencies": { - "browserslist": "^4.21.4", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.11" - }, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nesting": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-10.2.0.tgz", - "integrity": "sha512-EwMkYchxiDiKUhlJGzWsD9b2zvq/r2SSubcRrgP+jujMXFzqvANLt16lJANC+5uZ6hjI7lpRmI6O8JIl+8l1KA==", - "dependencies": { - "@csstools/selector-specificity": "^2.0.0", - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-normalize": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize/-/postcss-normalize-10.0.1.tgz", - "integrity": "sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==", - "dependencies": { - "@csstools/normalize.css": "*", - "postcss-browser-comments": "^4", - "sanitize.css": "*" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "browserslist": ">= 4", - "postcss": ">= 8" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-opacity-percentage": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.3.tgz", - "integrity": "sha512-An6Ba4pHBiDtyVpSLymUUERMo2cU7s+Obz6BTrS+gxkbnSBNKSuD0AVUc+CpBMrpVPKKfoVz0WQCX+Tnst0i4A==", - "funding": [ - { - "type": "kofi", - "url": "https://ko-fi.com/mrcgrtz" - }, - { - "type": "liberapay", - "url": "https://liberapay.com/mrcgrtz" - } - ], - "engines": { - "node": "^12 || ^14 || >=16" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-overflow-shorthand": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.4.tgz", - "integrity": "sha512-otYl/ylHK8Y9bcBnPLo3foYFLL6a6Ak+3EQBPOTR7luMYCOsiVTUk1iLvNf6tVPNGXcoL9Hoz37kpfriRIFb4A==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-page-break": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", - "peerDependencies": { - "postcss": "^8" - } - }, - "node_modules/postcss-place": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-7.0.5.tgz", - "integrity": "sha512-wR8igaZROA6Z4pv0d+bvVrvGY4GVHihBCBQieXFY3kuSuMyOmEnnfFzHl/tQuqHZkfkIVBEbDvYcFfHmpSet9g==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-preset-env": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", - "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", - "dependencies": { - "@csstools/postcss-cascade-layers": "^1.1.1", - "@csstools/postcss-color-function": "^1.1.1", - "@csstools/postcss-font-format-keywords": "^1.0.1", - "@csstools/postcss-hwb-function": "^1.0.2", - "@csstools/postcss-ic-unit": "^1.0.1", - "@csstools/postcss-is-pseudo-class": "^2.0.7", - "@csstools/postcss-nested-calc": "^1.0.0", - "@csstools/postcss-normalize-display-values": "^1.0.1", - "@csstools/postcss-oklab-function": "^1.1.1", - "@csstools/postcss-progressive-custom-properties": "^1.3.0", - "@csstools/postcss-stepped-value-functions": "^1.0.1", - "@csstools/postcss-text-decoration-shorthand": "^1.0.0", - "@csstools/postcss-trigonometric-functions": "^1.0.2", - "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.13", - "browserslist": "^4.21.4", - "css-blank-pseudo": "^3.0.3", - "css-has-pseudo": "^3.0.4", - "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.1.0", - "postcss-attribute-case-insensitive": "^5.0.2", - "postcss-clamp": "^4.1.0", - "postcss-color-functional-notation": "^4.2.4", - "postcss-color-hex-alpha": "^8.0.4", - "postcss-color-rebeccapurple": "^7.1.1", - "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.10", - "postcss-custom-selectors": "^6.0.3", - "postcss-dir-pseudo-class": "^6.0.5", - "postcss-double-position-gradients": "^3.1.2", - "postcss-env-function": "^4.0.6", - "postcss-focus-visible": "^6.0.4", - "postcss-focus-within": "^5.0.4", - "postcss-font-variant": "^5.0.0", - "postcss-gap-properties": "^3.0.5", - "postcss-image-set-function": "^4.0.7", - "postcss-initial": "^4.0.1", - "postcss-lab-function": "^4.2.1", - "postcss-logical": "^5.0.4", - "postcss-media-minmax": "^5.0.0", - "postcss-nesting": "^10.2.0", - "postcss-opacity-percentage": "^1.1.2", - "postcss-overflow-shorthand": "^3.0.4", - "postcss-page-break": "^3.0.4", - "postcss-place": "^7.0.5", - "postcss-pseudo-class-any-link": "^7.1.6", - "postcss-replace-overflow-wrap": "^4.0.0", - "postcss-selector-not": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-pseudo-class-any-link": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.6.tgz", - "integrity": "sha512-9sCtZkO6f/5ML9WcTLcIyV1yz9D1rf0tWc+ulKcvV30s0iZKS/ONyETvoWsr6vnrmW+X+KmuK3gV/w5EWnT37w==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", - "dependencies": { - "browserslist": "^4.21.4", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-replace-overflow-wrap": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", - "peerDependencies": { - "postcss": "^8.0.3" - } - }, - "node_modules/postcss-selector-not": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-6.0.1.tgz", - "integrity": "sha512-1i9affjAe9xu/y9uqWH+tD4r6/hDaXJruk8xn2x1vzxC2U3J3LKO3zJW4CyxlNhA56pADJ/djpEwpH1RClI2rQ==", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.2" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-svgo/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==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/postcss-svgo/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==", - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/postcss-svgo/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==" - }, - "node_modules/postcss-svgo/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-svgo/node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "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==" - }, - "node_modules/preact": { - "version": "10.12.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", - "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, - "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==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", - "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", - "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==" - }, - "node_modules/property-expr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", - "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "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" - } - ] - }, - "node_modules/raf": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", - "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", - "dependencies": { - "performance-now": "^2.1.0" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-app-polyfill": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz", - "integrity": "sha512-sZ41cxiU5llIB003yxxQBYrARBqe0repqPTTYBTmMqTz9szeBbE37BehCE891NZsmdZqqP+xWKdT3eo3vOzN8w==", - "dependencies": { - "core-js": "^3.19.2", - "object-assign": "^4.1.1", - "promise": "^8.1.0", - "raf": "^3.4.1", - "regenerator-runtime": "^0.13.9", - "whatwg-fetch": "^3.6.2" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-cookie": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-6.1.1.tgz", - "integrity": "sha512-fuFRpf8LH6SfmVMowDUIRywJF5jAUDUWrm0EI5VdXfTl5bPcJ7B0zWbuYpT0Tvikx7Gs18MlvAT+P+744dUz2g==", - "dependencies": { - "@types/hoist-non-react-statics": "^3.3.1", - "hoist-non-react-statics": "^3.3.2", - "universal-cookie": "^6.0.0" - }, - "peerDependencies": { - "react": ">= 16.3.0" - } - }, - "node_modules/react-dev-utils": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "address": "^1.1.2", - "browserslist": "^4.18.1", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "detect-port-alt": "^1.1.6", - "escape-string-regexp": "^4.0.0", - "filesize": "^8.0.6", - "find-up": "^5.0.0", - "fork-ts-checker-webpack-plugin": "^6.5.0", - "global-modules": "^2.0.0", - "globby": "^11.0.4", - "gzip-size": "^6.0.0", - "immer": "^9.0.7", - "is-root": "^2.1.0", - "loader-utils": "^3.2.0", - "open": "^8.4.0", - "pkg-up": "^3.1.0", - "prompts": "^2.4.2", - "react-error-overlay": "^6.0.11", - "recursive-readdir": "^2.2.2", - "shell-quote": "^1.7.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/react-dev-utils/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/react-dev-utils/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/react-dev-utils/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==" - }, - "node_modules/react-dev-utils/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-dev-utils/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/react-dev-utils/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/react-error-overlay": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" - }, - "node_modules/react-fast-compare": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", - "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" - }, - "node_modules/react-i18next": { - "version": "15.4.0", - "resolved": "https://registry.npmmirror.com/react-i18next/-/react-i18next-15.4.0.tgz", - "integrity": "sha512-Py6UkX3zV08RTvL6ZANRoBh9sL/ne6rQq79XlkHEdd82cZr2H9usbWpUNVadJntIZP2pu3M2rL1CN+5rQYfYFw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.25.0", - "html-parse-stringify": "^3.0.1" - }, - "peerDependencies": { - "i18next": ">= 23.2.3", - "react": ">= 16.8.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/react-lifecycles-compat": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", - "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" - }, - "node_modules/react-pro-sidebar": { - "version": "1.1.0-alpha.1", - "resolved": "https://registry.npmjs.org/react-pro-sidebar/-/react-pro-sidebar-1.1.0-alpha.1.tgz", - "integrity": "sha512-kIo4p3gHIdxqANG2KXv7V8KXDmDFsRhk23AGLbXsicCV39k32EP3Os2DXyOj9S6UCDYB+4G3WoeJFiMIkkHe0w==", - "dependencies": { - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", - "@popperjs/core": "^2.11.6", - "classnames": "^2.3.2" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/react-refresh": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-router": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.1.tgz", - "integrity": "sha512-U4PfgvG55LdvbQjg5Y9QRWyVxIdO1LlpYT7x+tMAxd9/vmiPuJhIwdxZuIQLN/9e3O4KFDHYfR9gzGeYMasW8g==", - "dependencies": { - "@remix-run/router": "1.7.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/react-router-dom": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.1.tgz", - "integrity": "sha512-ssF6M5UkQjHK70fgukCJyjlda0Dgono2QGwqGvuk7D+EDGHdacEN3Yke2LTMjkrpHuFwBfDFsEjGVXBDmL+bWw==", - "dependencies": { - "@remix-run/router": "1.7.1", - "react-router": "6.14.1" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/react-scripts": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", - "integrity": "sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==", - "dependencies": { - "@babel/core": "^7.16.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", - "@svgr/webpack": "^5.5.0", - "babel-jest": "^27.4.2", - "babel-loader": "^8.2.3", - "babel-plugin-named-asset-import": "^0.3.8", - "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", - "browserslist": "^4.18.1", - "camelcase": "^6.2.1", - "case-sensitive-paths-webpack-plugin": "^2.4.0", - "css-loader": "^6.5.1", - "css-minimizer-webpack-plugin": "^3.2.0", - "dotenv": "^10.0.0", - "dotenv-expand": "^5.1.0", - "eslint": "^8.3.0", - "eslint-config-react-app": "^7.0.1", - "eslint-webpack-plugin": "^3.1.1", - "file-loader": "^6.2.0", - "fs-extra": "^10.0.0", - "html-webpack-plugin": "^5.5.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.4.3", - "jest-resolve": "^27.4.2", - "jest-watch-typeahead": "^1.0.0", - "mini-css-extract-plugin": "^2.4.5", - "postcss": "^8.4.4", - "postcss-flexbugs-fixes": "^5.0.2", - "postcss-loader": "^6.2.1", - "postcss-normalize": "^10.0.1", - "postcss-preset-env": "^7.0.1", - "prompts": "^2.4.2", - "react-app-polyfill": "^3.0.0", - "react-dev-utils": "^12.0.1", - "react-refresh": "^0.11.0", - "resolve": "^1.20.0", - "resolve-url-loader": "^4.0.0", - "sass-loader": "^12.3.0", - "semver": "^7.3.5", - "source-map-loader": "^3.0.0", - "style-loader": "^3.3.1", - "tailwindcss": "^3.0.2", - "terser-webpack-plugin": "^5.2.5", - "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" - }, - "bin": { - "react-scripts": "bin/react-scripts.js" - }, - "engines": { - "node": ">=14.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - }, - "peerDependencies": { - "react": ">= 16", - "typescript": "^3.2.1 || ^4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/react-scripts/node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "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/react-scripts/node_modules/@humanwhocodes/config-array": { - "version": "0.11.13", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", - "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/react-scripts/node_modules/@humanwhocodes/object-schema": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", - "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==" - }, - "node_modules/react-scripts/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/react-scripts/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==" - }, - "node_modules/react-scripts/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "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/react-scripts/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/react-scripts/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==" - }, - "node_modules/react-scripts/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-scripts/node_modules/eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.55.0.tgz", - "integrity": "sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.55.0", - "@humanwhocodes/config-array": "^0.11.13", - "@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/react-scripts/node_modules/eslint-config-react-app": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", - "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.0" - } - }, - "node_modules/react-scripts/node_modules/eslint-plugin-flowtype": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", - "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", - "dependencies": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@babel/plugin-syntax-flow": "^7.14.5", - "@babel/plugin-transform-react-jsx": "^7.14.9", - "eslint": "^8.1.0" - } - }, - "node_modules/react-scripts/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==", - "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/react-scripts/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==", - "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/react-scripts/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-scripts/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-scripts/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==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/react-scripts/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/react-scripts/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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "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/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==", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz", - "integrity": "sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "globalthis": "^1.0.3", - "which-builtin-type": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", - "dependencies": { - "regenerate": "^1.4.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/regenerator-transform": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz", - "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regex-parser": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", - "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", - "dependencies": { - "@babel/regjsgen": "^0.8.0", - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" - }, - "node_modules/reselect": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", - "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "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/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz", - "integrity": "sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA==", - "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^8.0.1", - "source-map": "0.6.1" - }, - "engines": { - "node": ">=8.9" - }, - "peerDependencies": { - "rework": "1.0.1", - "rework-visit": "1.0.0" - }, - "peerDependenciesMeta": { - "rework": { - "optional": true - }, - "rework-visit": { - "optional": true - } - } - }, - "node_modules/resolve-url-loader/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "engines": { - "node": ">=10" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^9.0.1" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "2.79.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz", - "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==", - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-terser": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", - "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "jest-worker": "^26.2.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.0.0" - }, - "peerDependencies": { - "rollup": "^2.0.0" - } - }, - "node_modules/rollup-plugin-terser/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/rollup-plugin-terser/node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/rollup-plugin-terser/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz", - "integrity": "sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.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==" - }, - "node_modules/sanitize.css": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/sanitize.css/-/sanitize.css-13.0.0.tgz", - "integrity": "sha512-ZRwKbh/eQ6w9vmTjkuG0Ioi3HBwPFce0O+v//ve+aOq1oeCy7jMV2qzzAlpsNuqpqCBjjriM1lbtZbF/Q8jVyA==" - }, - "node_modules/sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "dependencies": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "node_modules/selfsigned": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", - "integrity": "sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ==", - "dependencies": { - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "^4.0.1", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "extraneous": true - }, - "node_modules/send/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==" - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "^4.0.1", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-function-length": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", - "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", - "dependencies": { - "define-data-property": "^1.1.1", - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", - "dependencies": { - "define-data-property": "^1.0.1", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "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==", - "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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "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==", - "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/slice-ansi/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/slice-ansi/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==" - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/sockjs/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==" - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-3.0.2.tgz", - "integrity": "sha512-BokxPoLjyl3iOrgkWaakaxqnelAJSS+0V+De0kKIq6lyWrXuiPgYTGp6z3iHmqljKAaLXwZa+ctD8GccRJeVvg==", - "dependencies": { - "abab": "^2.0.5", - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead" - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==" - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-natural-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", - "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" - }, - "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==", - "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/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==" - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", - "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-comments/-/strip-comments-2.0.1.tgz", - "integrity": "sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==", - "engines": { - "node": ">=10" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-loader": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.3.tgz", - "integrity": "sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw==", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/stylehacks": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", - "dependencies": { - "browserslist": "^4.21.4", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/stylis": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", - "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" - }, - "node_modules/sucrase": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz", - "integrity": "sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^9.0.1", - "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": ">=8" - } - }, - "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==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/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==", - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks/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==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-parser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" - }, - "node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", - "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/svgo/node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domutils": "^1.7.0", - "nth-check": "^2.0.1" - } - }, - "node_modules/svgo/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/svgo/node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/svgo/node_modules/domutils/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "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.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "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==" - }, - "node_modules/tailwindcss": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz", - "integrity": "sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "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.18.2", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/temp-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", - "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/tempy": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.6.0.tgz", - "integrity": "sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==", - "dependencies": { - "is-stream": "^2.0.0", - "temp-dir": "^2.0.0", - "type-fest": "^0.16.0", - "unique-string": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tempy/node_modules/type-fest": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", - "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.0.tgz", - "integrity": "sha512-JpcpGOQLOXm2jsomozdMDpd5f8ZHh1rR48OFgWUH3QsyZcfPgv2qDCYbcDEAYNd4OZRj2bWYKpwdll/udZCk/Q==", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^9.0.1", - "minimatch": "^3.0.4" - }, - "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==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "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==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/throat": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "node_modules/tiny-case": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", - "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "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==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/toposort": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", - "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==" - }, - "node_modules/tough-cookie": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", - "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tryer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", - "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" - }, - "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==" - }, - "node_modules/tsconfig-paths": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz", - "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/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==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "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==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "engines": { - "node": ">=4" - } - }, - "node_modules/unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dependencies": { - "crypto-random-string": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/universal-cookie": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-6.1.1.tgz", - "integrity": "sha512-33S9x3CpdUnnjwTNs2Fgc41WGve2tdLtvaK2kPSbZRc5pGpz2vQFbRWMxlATsxNNe/Cy8SzmnmbuBM85jpZPtA==", - "dependencies": { - "@types/cookie": "^0.5.1", - "cookie": "^0.5.0" - } - }, - "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==" - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "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" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "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==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.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==" - }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==" - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/web-vitals": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", - "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "5.88.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", - "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/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==" - }, - "node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/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==" - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-manifest-plugin": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz", - "integrity": "sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow==", - "dependencies": { - "tapable": "^2.0.0", - "webpack-sources": "^2.2.0" - }, - "engines": { - "node": ">=12.22.0" - }, - "peerDependencies": { - "webpack": "^4.44.2 || ^5.47.0" - } - }, - "node_modules/webpack-manifest-plugin/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/webpack-manifest-plugin/node_modules/webpack-sources": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.3.1.tgz", - "integrity": "sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==", - "dependencies": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-encoding/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==" - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", - "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", - "dependencies": { - "function.prototype.name": "^1.1.5", - "has-tostringtag": "^1.0.0", - "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.1", - "which-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/workbox-background-sync": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", - "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-broadcast-update": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", - "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-build": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", - "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", - "dependencies": { - "@apideck/better-ajv-errors": "^0.3.1", - "@babel/core": "^7.11.1", - "@babel/preset-env": "^7.11.0", - "@babel/runtime": "^7.11.2", - "@rollup/plugin-babel": "^5.2.0", - "@rollup/plugin-node-resolve": "^11.2.1", - "@rollup/plugin-replace": "^2.4.1", - "@surma/rollup-plugin-off-main-thread": "^2.2.3", - "ajv": "^8.6.0", - "common-tags": "^1.8.0", - "fast-json-stable-stringify": "^2.1.0", - "fs-extra": "^9.0.1", - "glob": "^9.0.1", - "lodash": "^4.17.20", - "pretty-bytes": "^5.3.0", - "rollup": "^2.43.1", - "rollup-plugin-terser": "^7.0.0", - "source-map": "^0.8.0-beta.0", - "stringify-object": "^3.3.0", - "strip-comments": "^2.0.1", - "tempy": "^0.6.0", - "upath": "^1.2.0", - "workbox-background-sync": "6.6.0", - "workbox-broadcast-update": "6.6.0", - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-google-analytics": "6.6.0", - "workbox-navigation-preload": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-range-requests": "6.6.0", - "workbox-recipes": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0", - "workbox-streams": "6.6.0", - "workbox-sw": "6.6.0", - "workbox-window": "6.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", - "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", - "dependencies": { - "json-schema": "^0.4.0", - "jsonpointer": "^5.0.0", - "leven": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "ajv": ">=8" - } - }, - "node_modules/workbox-build/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/workbox-build/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/workbox-build/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==" - }, - "node_modules/workbox-build/node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dependencies": { - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/workbox-build/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/workbox-build/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "node_modules/workbox-build/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "node_modules/workbox-cacheable-response": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", - "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", - "deprecated": "workbox-background-sync@6.6.0", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-core": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", - "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" - }, - "node_modules/workbox-expiration": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", - "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", - "dependencies": { - "idb": "^7.0.1", - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-google-analytics": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", - "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", - "dependencies": { - "workbox-background-sync": "6.6.0", - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-navigation-preload": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", - "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-precaching": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", - "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", - "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-range-requests": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", - "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-recipes": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", - "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", - "dependencies": { - "workbox-cacheable-response": "6.6.0", - "workbox-core": "6.6.0", - "workbox-expiration": "6.6.0", - "workbox-precaching": "6.6.0", - "workbox-routing": "6.6.0", - "workbox-strategies": "6.6.0" - } - }, - "node_modules/workbox-routing": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", - "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-strategies": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", - "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", - "dependencies": { - "workbox-core": "6.6.0" - } - }, - "node_modules/workbox-streams": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", - "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", - "dependencies": { - "workbox-core": "6.6.0", - "workbox-routing": "6.6.0" - } - }, - "node_modules/workbox-sw": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", - "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" - }, - "node_modules/workbox-webpack-plugin": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", - "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", - "dependencies": { - "fast-json-stable-stringify": "^2.1.0", - "pretty-bytes": "^5.4.1", - "upath": "^1.2.0", - "webpack-sources": "^1.4.3", - "workbox-build": "6.6.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "webpack": "^4.4.0 || ^5.9.0" - } - }, - "node_modules/workbox-webpack-plugin/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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "node_modules/workbox-window": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", - "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", - "dependencies": { - "@types/trusted-types": "^2.0.2", - "workbox-core": "6.6.0" - } - }, - "node_modules/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==", - "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/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==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/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==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/wrap-ansi/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==" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "engines": { - "node": ">=10" - } - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yup": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/yup/-/yup-1.2.0.tgz", - "integrity": "sha512-PPqYKSAXjpRCgLgLKVGPA33v5c/WgEx3wi6NFjIiegz90zSwyMpvTFp/uGcVnnbx6to28pgnzp/q8ih3QRjLMQ==", - "dependencies": { - "property-expr": "^2.0.5", - "tiny-case": "^1.0.3", - "toposort": "^2.0.2", - "type-fest": "^2.19.0" - } - }, - "node_modules/yup/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/xinference/ui/web/ui/package.json b/xinference/ui/web/ui/package.json deleted file mode 100644 index 7865fefe1c..0000000000 --- a/xinference/ui/web/ui/package.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "name": "xinference-ui", - "version": "0.1.0", - "private": true, - "homepage": ".", - "dependencies": { - "@emotion/react": "^11.11.1", - "@emotion/styled": "^11.11.0", - "@fullcalendar/core": "^6.1.8", - "@fullcalendar/daygrid": "^6.1.8", - "@fullcalendar/list": "^6.1.8", - "@fullcalendar/timegrid": "^6.1.8", - "@mui/icons-material": "^5.14.0", - "@mui/lab": "^5.0.0-alpha.173", - "@mui/material": "^5.14.0", - "@mui/system": "^5.15.9", - "@mui/x-data-grid": "^6.20.4", - "@mui/x-date-pickers": "^6.20.0", - "@nivo/bar": "^0.83.0", - "@nivo/core": "^0.83.0", - "@nivo/geo": "^0.83.0", - "@nivo/line": "^0.83.0", - "@nivo/pie": "^0.83.0", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^13.4.0", - "@testing-library/user-event": "^13.5.0", - "formik": "^2.4.2", - "dayjs": "^1.11.0", - "i18next": "^23.0.0", - "nunjucks": "^3.2.4", - "prop-types": "^15.8.1", - "react": "^18.2.0", - "react-cookie": "^6.1.1", - "react-dom": "^18.2.0", - "react-i18next": "^15.4.0", - "react-pro-sidebar": "^1.1.0-alpha.1", - "react-router-dom": "^6.14.1", - "react-scripts": "5.0.1", - "uuid": "^9.0.0", - "web-vitals": "^2.1.4", - "yup": "^1.2.0" - }, - "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "test": "react-scripts test", - "eject": "react-scripts eject", - "format": "eslint --fix . && prettier . --write" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - }, - "devDependencies": { - "@babel/core": "^7.21.0", - "@babel/eslint-parser": "^7.19.1", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", - "eslint": "^7.32.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-react": "^7.24.0", - "eslint-plugin-simple-import-sort": "^8.0.0", - "prettier": "2.8.0" - } -} diff --git a/xinference/ui/web/ui/public/favicon.png b/xinference/ui/web/ui/public/favicon.png deleted file mode 100644 index 059f5f63e43493acaee731b9be0d333261335938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23192 zcmeFZ2{@E(|1dl=rVNTfl8~{J-Po5g_Od2r$-a}_*w-N>vXphm61Oc`DlJGTTa0~6 z))qrUR7ke^PTgD2^WM+*|9|iMz29-X$MM}Aadlni?_7TScHY;{8E7A+K1mIMK#rb0 zqj4Srfo>f9MH~iiddKGy!7nK8ytW#orl0Kt_{SF~v$M|n`jFG$83Cb$GC(K}hJZg1 z=t;<-pU)78J(TsY=gUxmKgPho7zqgY3E>2P{h*RRpO1m(jH_-C_#dzp;P=6!@WGEi zf2%rr+dHAoxqAD1<6OOcP?EBuQYZm^I|nzfgExW@h@`lrjDk2?K@yD;ms60GRFIa0 zK;UWczt)&7g8seNBG{knK{tvh{(e4K`Oldo&?pIM1u&VEG~|3lj4}8`<#Way2Z4xk zAN+*|m#PFpAoQ2rE|~e7>FX&tczcT49c)xI*wg1=CWun70(kUv^0z|;dwO``6oQqx zevVK8&j+u?xKKZb_`54}ndzTHseAi5p=3nGMa8)=)F>26$6$%3QAg z{yqv~VnIPcqCsd;Z$B3?33+*WF>y&TNl6hfLIfA$eUd-t(Qv{!___J` zyLo$|4(7G9_YUw^=Hfb7=&%2N-=|Zs+utjB;r=)lIH1_U7cmJ@aj|~_b9DG?dp-ev z9zQqd=pg3g;pFM$<&Oh!68{JXkfg8w7wEsN7i{PAb2(4Xe}u&OYX*Wd{DG5ygv4D4 z@o^G6?}YOX@N;m|3-#hV%FK3;E@w;JiP@$k@sEU*G=u!NcvRIQZE4;hYY5MVaeQ zX8B8g{t}M^n4dhSfb(|t53=)fQgs0gh54@(l#!O2-x-a$^%?$6nO0sqfy*f|{N6O4nOlbyelHVA^yKgI(u0Ow79grortUiAefXi zT3p25(Lq8)!d^;7+CfIrNnHLf{Qo~89nLQB|0f)+L(JAh^W5?KX#X$MCc2`M=dDG5mj5j!U-@IxBJBvN)x z60(v~lCttnQhy%km&yLeg?<+}tphc2;4}Q!&KYo=fJ3g}{lAKg|2WOxd;DF_4_5ny zEB^Gb{=3@#-@yNAc7WXfIfDLvhF`${p8YT6|Bc{ZysfRfoJUzaG>!odb#;yB$dSe>Gi)u0S*Uz{nJojB>n*T_1(XZH~V`T4En%b{<+An zZ~q;_{2w8HeftXpIHiKVx1*bLhz4+a|8mp+K{Nf^$bXwd{ioCXFLV5ZtA8-ZFC+hH z4sX8;-rgSnjUeQ&x&DCox5@NDO2X03-|k)2oB`CAwK3@!nloG@r5v448~ z2h{IM@0aYvPlo*cEy#Ufr~%LZnMc7;Cj>HXLm*hlSq;?-!O)NSVRcqx5pxr-O`jT} zEMEp%zAX|mzj+j~?h~h{^a>g~<5qTbi#qLk$Rtw5exlD&l0f_|{e#{Qw{)48{wJ@5 zaP#QgP-HRee8_X;o-rIV;{8=7d z6!F!edTwofYAbThTRHPB1r&jWz>s(d90mFRAOBl;VBjjU+G+gS!`_l37*Y9hbV_u2 zvq7|ELzgnp=11Ltj6EyBWpqqyqfnrSxOrgdILXX6B}$QMDPE!8du^OO-}H{+gS(Bz zin{&v)(#mvhC1K7%Fkkj9z@J!D$YKPT6?5|r#c`3A9IJ{Gqoo;$¬?x-{=XdYp?v)xmt$|C(ReZo4T zF)F%8Gh#oJ?niD^nH@bGl|~H}B6VdpXbP@>xDZY|V+fxaK+M`oKDb5-Qn_;FA~GQ# z%SpOaHRZ4+&G!T8Z&TtnDzh^hag;Vt6=e-umR;LBr=FLGT>oT$y=a#mt*GqCZTxzV zmSJ2KbsQ#xmeqQ4^+y-V;(I~3=4$HiOLmwboi*V!y)*7xzIa(v|`0JgkQOd}42}T$afyauHhFxlq z>yYBHISqKT3P){?40E9PA~)GO?vMitDGbilSLwDvpk!?iiRWHgw~h4?n0hxOyskE2 z6SdGkhiJ3*h=suSc+MrrmrU+o9}qC%Tq-$Nwap?#K3d(cIqFUeA5%x2gKhiOT#BHU zpp(KY6SW4z@SpeVnF1!`zD6W8uHAT!L44C}O>Dpv?4K5D-Db*`ysJ9cTV!U+a{rkm zA=K(qB{S>|eO=$mof{EZ4<}zF&7h8RFI_qJ<=d&;Ib~YfGSyb@12mbxd(h`AcZwxm zu#_G3hymQYFpHuc_Hy59^}#OQrI+hpDaT}5(4~Fp zc-zBpCC)TDd@qr?ovkTDsxW~{j>+G%{;qI$`DvJp@qqt3Sk|@bMDYbRlrU@?BKMN$ zR8sC~XP)w~1nF~nNsG07Ga1IS;gZO-fZQD9zP67%k&0(pCoT=>3ObVB-9AEcD~IXE zuacU(cVDi=i{=GI4(TV4!k~z68bv4i3K@TrOHO%tth; z+^ZPBNvdbkXui~wK?_}kQ%htgs=RyZcX}fc60>?y?zBu9a#JWMyz*_Xz$qBg2a96H zm0|=ha*}9+cdZWr4vp=3G?3VsKOA3?t)KM;HJ^dCAU@o_HIi6Kw16QRAK$JVtz-2s z6LloK(qS={gP-Oe^m5iF3OTUZw;@6kjD*^po91J!_>LQiLHRVXt(?)1az==&X`v@B zaxU4mS276EZ|c;Y7XW~1-u1bI<@=|E z7n+S#`PFSsvu#?5X++FiRE&Ip5vpK;Aq>m)N0X9#0RU_peUqWwIbhsyhv z0w&&9iUq)`E8Pm2X#q+sG`qxGO!NU zz#XDHjp{Kb?j@txp=*q?@0;p@PSxapXha2=GHr_>gk!ZYIMXWRKLU_irx$m_-+1F_ zPX%3#`smDHS=JJjl=cI|=}x8fCH0T(s^u}O?cAp;bMfqVAJ7}soZ|H;=|zhqKO#gT%EiKvgzu#^HQhYAmFEY(vlj^7iOGBu2ajG zU#d4&bvb95QEQIdP%J*>9bD25xW<=bBW*>DZj?_>7pw1BpM9xXciJ#(+tvhm(8*eoR(}dvF!aj}}W7JQTn` ze__zgZ|zj9S-%W(r}*N7&C9~{9jU%RFWvH@fqTw_DYi=Rcph6cZmb*AOYNf`^X}_CpvyMyRhQ!H5Uv4LlA-KJ*4~QEaJKrM3p0%)$pheR%6DQoUl{W`b6vktj{@cJ)~V}6cO+J z*jTlkPI-^nnTJkel=V`6Qbnpp>QxvD@S5y>v4qONbuJ9DA`X8rtU2pMn30>rxs(vH zbu0z94i7#j8l~^3 zJV4p8WFNbGIdO-SZ==^{9)A5QFafMR)A2c7j3Z`Bs)G*K9CIS2wv4q$UtG72F_|J- z%JO*`2PPlFAU|CP%FZ0iAl3C%#mn+)1^=DgbIm2lHrC-Z9s_>21`?-|@PCLp^P2_wY*CL}8Q5`4x_ zZImM1f-P^_^2v)^1EQWOZTyz`eMF}TDMGFmI_!C^s$fm;n%LqF`RViR->8kUaW(}} z1rCT~@I0qi8rK{=rnrn)6i#sZ~k4_(Byx2uGtRnF#FD(a>tkjDzKd8)%n1yVRMm9+myBxJ? zBDa*kE!pHhyxcp`{iUY%(QH%NOk3bpAZ@z3yUhU!4FMxGs*mIAHTIb_W`^fSGVvzN zJs}#+LTmS)$W?iu?jt1N-nbCpfQ?INRK0o zYBKHU58YTXoL5_%w&iG_R`{4%WN{_8II@rak2Mk$BFI)ReeOHL zG|N&dvX96Vzdi73XKYN-yWttLRE^TKMui+)DNXcs5qTz~{HEUKA}#(uil>xsUBR-z zk(-hNT9@LDwsM54oFJC6#n#k~(#MR}j*Is9@!M)DkB~U{O!W)7*LscDYkiMIOH!f8 zPQ%xK6Q;*)vu_m95kgc)EmR*L<|1q6e0wYljffVW`@~Q@n};;*;k4C^=pcVskYrqx zF00RcA@%C~CHrT0(&n!ExCj|gXw7Wnd1L$eC5}rH()%=yZ7^KvIF1I505stuXTb`25eXGl+(IS;w~{NwR1Ij^dX)x#UzI8?c3XP0Z;V z96;jzYV=!a&2lwIr67W1MhP{&a%DXvk+?R?8wb2|q=W!ICsOg}F#3k{c0jC|= z^Ah}I9s?SudNNMH^ zdd|G^snLK{>+L)4jOxZ-GBz?HE>BB)UU+=vxc{=h@o4#EspqIHDtS?+?wj7p=$fhC zacqO}iGAxJ9xbpWJNQr)uW3D=p zAMSq*`?97U0J+q+#;-fFJ4H0EO~EnoGTWchDcrU{Y=meGxFdfqMK8h^zl|xx-xVky zP4ZZhETrnXh^*^d+g94tYvx>-s>}#i;zu^-SUep95b>lS-DpD<*iGpOY)#7(zsscN ztF)`3_ve}|ue8d+zmT>rS{P)TsApYcr~K`TivvKF;Az#zv`ob{53@+30oRnfC}HbB z;9XQUw>9Ky60uc=5g}QGLY?&{PtLdRSfJH?6i1bP4HF_rNk&@yOXF=>6)inWTODsm zVX6SbEhxgyCCSYg>K`VmK-OmlHAxSeUx%*Usfd@bW1vw zWD2J}oV>ar{7lt%26C)eG=lu)Dhq3)KM1KC)J6%zSvz^>ntvpOZe9-?pWluoDStfm zNo|8AwC%Pad1ct-)BKzP%w!bp`Q6TMY(rl1@Vm->MLCLSKg6-({-rIyVA=~h@9n)< zc!0c^Ys{RVA1TD*H03p#Rd{Ps3;{CO_fslT2mD?#Fd%WgC_#XB3nQ21i@Gs}-Y`iU zvt@OU=GQ;<#kmB9q=AeV58MT>B{Xa*%Y&oKme&vMd6|Fua28)}8dm&9jR3z}QER3g zk-JB~U6ug^!RfjF8KTG|9)JOZvY(9KdYCXC=-5FfJor^Tpw4!Vr1v@5r|NJnrdT5B z`svT;5v$+5q;3qDbtX%-STKa|AmuoW*3_@+meRW(%}~6UJC~|^drho*{uqtUIihDy z`f-06h|%L?--K0LWv=uOmp_B^il*up@sa~o0yH8ta<_{mZuFyVsLy_h@q!MOKO1#_ z9>9q$RH%(+geB}Oo9tIZ6A`w!$9axIC(=((|OUDSEIT~=YJ|08CPzFTRNN6k7l zy*k>D|E0az(R+B(7W8=YX%l0TsqSqJws%676h zJ1pw`|67LxqRlV8eSh;ZZ!ifmdOi5f((Bd#=icLTkXJ+sU zb658@vm73qgnhPoXE>_mPgTGmj;u(;?+tzPC$lyl>suLEeYR?G(UfJaw>%>RbR62 zc`Q9&+M*S|mBWoH_Nw2J=v%{`k-HO*z(k6kSvx=3ObGQ?ClBWeQN- zv62i3nJ^1?hQ|)6*he*xiF>gjS9@N^nKN)^qV;jD{1bfv(w*jOW~g`eOOIOz+9iYtYS3?-7w>0ME8JnDNeN}>MsH?TJ$kx3*rwewu`Vi# zwbg?K7Tvll5R~Xh?kW`!(^URx)Ip$ye)UBz27`H#!q7dcnC4TQ-nu=!7nuV#cEqKJ zcaUtnb$--bs%+Yfduic|M|Nk%BN=MiP)6G#OK%xV!5jG0;*^~16Z0lUh|q1lDPAtJ z=P|YozQJRgl^<-^RnCuo`XA12su zF!Z)-u~^jJx(rm?OD}QW_3vj8lNHnaBez z_%KD#^HLsV{m_;Kq~_+Jq(IHdyZNQZi$zUSdZM!ZXWLj1-HCoW&E2A&PpK|40;h<- zmpa~C$13o&(*j2xftxgD&!=9SwH7lBm@ZZ?0($%z5bq#2hvl<lZt}*n&z~=EBNw zf>|CxcB5U{qyD_P+JcdNQ|cN7@S8*iB-f2Um_8QKD2+-a zvPp=sdum4`LMd;O4b6-SZ{2d*h@Ux2>j?N2F@*+{7t`C(ADfSGs0> zK-gb@ZgwGsZOu4l377dmHx`)4LEba@FQQ<)BI~`!-M3dN?U+*~h zt%OobLNe}yN-pw7r8a}^zzo2fMa}g{&Dfdm z67pXtB{*1S%;>n59Nw`0u*;q6ayb!3wNcr1$}VcpUEfU+cS~<3F~oUvU+O_qs!+^o zL5Oy;X4!$6eo!PzeiF_2lCiG12EERByzuPzixq5G_o8VQ?rV)JxmovybQUDY7ojn; zN!Q=4_v!8Da$j-@tWwvQk@z8g$Kf+U{Oz%4nQ;|#(mVMg=iKR(Vywduq$94*KtvfebF@bfZ-@2i06?T640!DIYQ{9hJ&zJp_o!r z%uy@*BQ>TNree{sqfa^G18j_FCARpS5sk99bI|S1@O|961y!fyU*BBkU!BpkaU$z~A zIiAwXm*zq?wlJ`$yG>(nEknB33lgqcW>(OI&;Sqa)7#-1%EhjsD~U{-OjYHECVc79 zE9A3;kk6>5vTY`Dkbn>NH+z9?pyj!>#DlL0l6<3g2>yO+XhdjSkHhrn`u={Z=ahvi z(=qwO&~5G{Lj-)>dv=@CVM9cRV0hJ5OlDlow#jk%N7#?m>Zl94A1_ct5u-ZzBOn&P zV(O*cQfrA;?iKaCg4X@ifAsCTFvSAHbtO@CECRIzZ9WX}Do;%GgC6Q@uGBYj(a8(@ zGKz@Kr9v%9Q`){FzZ|{FoArL5)p7Qdt}tVs9SjkQZ}S$#yoe-2~X1f!!38bZL1s(m(GeT}7VBgT$Qj z*|UfsYo8Ec_CX5C%&ZP~Mv|G-%YqTXY7o^e9%M@WRb09a$clW(0h{$mw4~I@pX<({oQL;LY2B@3fH^J+wosUi&PhnG-zU1byH<-D z5Dq=t;sME=viePU`ys?PHT;p8>@%Z|S2u1vtMlt4+I=;y6@=Jbn7TFmD3p{B9QPlw zc9JG)C}lwHP>HoqPY9LX@)~8c(eaEpxQweOZEvSac~XUna!@We0^7qb3j$HLBHZBSO|T782)DUH#sFgGqORn!6NK5w&G3B?sn6X|p3nA6|vvO$H& zq@~1*=vp?QdAA$Z*;FC007mTKathvM^D#(J2MoM@n=Q{pCcKOcBEZPZ$?jt1y_98?`xlWAXdq^2ZT2P>X#CDm3ouYe5}HGS(F_ z)@Fb$374Fm=`f8GG-2W}*fp>gV-$3!!RAOtiD5HGX?rcpLmL@fi0sHDLlm9Q-0yPr zX#$Zux1XHMoOL$KD?`D5Jl8#yEpm0}$6}oR323wiAl9|RktZJ07@6wyu6YFvi4XXB z@4@TObDZmB%ly8vHdJ^j>gne}8-T5rd!Kvm18;tS3zWY)SRGb|+X#eU-P~D@txka> z(O7$so^OX?QkoKWwf4!RS{^*v%?sQ31dhBC4D(C@B!($yoksNl`&VUi|VMe0NXe1I0oD_B9tPHRI0})1Iny3%C^djzcMbO<~gD8 znHNQ|whYCm)H2BTh6MIYg7iG)9m|!+9iR`@Q2H?QT(5TlEby-%XLo+PyBtw_B%`V7 z`WFFiT9_nuHL!%0BlQLAQ#@7<-aYu@T4r|E&B`#Atk=mmh4;Np4Lk{H!uy2R$!!n> z58ycE8(7m1e1yJNRx zKIbU===9)uJ~#>S$#fm~c{+T9Yy#yUjKv7<2^~(!?^cGH?dR*{f8PuBfZ5@mIOYdB z!sDSc4W=sh%WmEmJO)E{1EzV3$Yc~a+%r^eEq}RC=o`@px1v;dv|R=fYXDKDQ;vy# zm0Cf`P(j^CydL>O8}sGced?+rR|JnfMAcAX&nsU{1LS198g|d;8Ie_!~8e1-lNKGhRz->rIQ%cew9;FXhTyn1+bd6|h z;0SrY@%kvBm&O?YD_+6*v2(nXSiWD6tm@>fTUl!V z!lC5*(fwUU+XE!Nl?^JnA%C1LM61X(lHYhsSbTx-BGGr@-fujJx(%T<{2T~!%MEAN zo)U@xp6b$5YE>k5 z^a^4mP3z>iKgZ1zkJXDffNJMpuL;ovX-^4quQf}&L<#+1BHz|f_vd5qMu6QW`!~PU z!gC|YWZ;{T=9y@8M6#oIs~C>dYlogq^s>sn_HGE`!r+(FB40 z3oHE5E?=#GWLSkCHrhgCD9oKkuL+Byk%C?^tys93nKMdn`n?eJc;RPh$t#naIPJNB z=ZuEo8?S7GaLjPjU@C+qR7JsZy#VhSDO=Vid2d$xPE+(i)nax)%X4$E4)7Cp>e`>o zDZ(hfdhOz>`zn#~c{7jW*^B_LL6ZDh zfK7);RXvtRR5cV{dSW362(0t@eDFn3ubX99_q;f!+Q7un4uwHt8_9=O2^Itko!l6AOA z5vqs$hoq1j_~&tzP#`rFi1TE=M|qR<>lM~cYj|$SwR2!$2EH^Y`)PAIDM^gJID-RD5_O_@W683SlH{S!V6&MH%x3oxpkflFaToL^ZL+rqV?6x$+mecLia< z(1wvlpCn*)i7KMyldu5#yb~=w9G(OBdoNwT(NW$AxFA3q^?7Fg z?TwLC(d#s4i^HqKjwIp`d3TO8xEkn>By6h*8%3qB>^&>tXA9%J%o02O@I~b;kxy%KAo{CJ6lLE)Qk3Y_mQ(efx^E>vxEND%@#}sCd%HYh z^b80Rw7vs)4`U+-gJ}o%(rtHscOm{jUo^WF0SL4wS5z+RC%OXAT`roTpp*nTfD;>F)lKqbdc8p!q@(e=C%!&uZjk_DgCX z+28uPF8**5pN=XB4r7TaAk*OI3;_Qbh?iSj19i$y5BrIF|2gP#hP0o%B>Lx z+#-7`y|N>*;rxzdyAmO7E8s$8n^M?3YvDKRxx6O`C?Z1*j{#Yg^9i6H*5Fa^ht@!) zxh(di<*%Q{w$cMnhJNW))jj(Hw@tfk-bja)XK&|<;2U$NUNvnFP&Vi7f(EkB;K1)b zzjOQ9Ob{WzP7Gmx4Zr@~n^8x3==ZJ4gRT0t`tV{7bV-YWM$@yvnM?f~Yx$e2>U zXM*0ns0HHh-#Ab8iIl9~V4`%C#%$)nG_Bb3(<lcg@wk2O-CIxvvGD2osy$bV-sg8={E z^MLDAj(L;3ApbaWB+90?ba??&+GnG*p1l0yK2R^9h3YgnzQ{CQrY6QBf+Y2zi)noL z>C24mq3<&mYl78S>KF(-o)2F{mn_^&iCo{X$Nbi1Qy|y4l6o~feu@(keG?pvmm<0P ziM>?QH_gHjk2aC6!jDJuKkh-p^0U=JXd`|Y3XeDvd{5#xi&9+m+}@{;fRTG``Hv@G}G{PkI$zLkWKcHdK7 z568pTRg~(&rc%2EueyM zP*_*rF)hq&L!QJ>Cgfi71oUct2UfFJGyv^g;zy{iP0SJx+h zd)O#1J|Z!}9{o{=5au+J$v<=Ptp3lPy-)SRR5G~I;zzPy>iXdB9Qo9w0-aR;2pt>T zTAgazy!JiFj|qmX$OATbhQ6XQQiwz_;gE@k`bfvM?p|Jp`sgS>;gHzEn4CaBb%EpE zwuRz=ly5A&Rahr7UjKm=WerH}A*$~NdGC_2TR27_qX(YKYxVhYyb?Nl!IF0usGP@3 zFDj2p(D9p?QAdY>GcL9z?E4rHrR`6J)oFh$23U{YnxGYT2~8cR z%sdl9Y@shK5yC(biM7%%GPf)BKgn8VvbPpB)VTsW#Wrp?xvbWA2IK|J-nq_&4$@Js z??J8)a>X|zmw@BCrp0>`Cj)qxo66bA3q{JjU22Pv<7>UNniAb~r{9@$$xRYx+NyrH zE5+FbVwrH`g)_pR7aKpzr2C5Bg0Ow@ZHL~g0^5j-@ReeTFB5xL?%!HwJh0B7oAaP8 z%wjfkV*Dh;rDN}Pk5EYrit2rD!zGEiD>;-b*z56FI$$8TAdGK6SP~z8uXvS`bM*vP zR;Cwp!$gt@P0{)yNT0JHhUWc9y?oh;l--MZ;>l#9KE%nGCUWj$jax!Uw`zMJVuKHC zC{JJ9^lr{nvPrw`xHBE!Wv`=SJxap%k+SxyS&9!;TY00YvNMfLw?R%R@>`&r+J4%~ z1Dx@8sj>YL&}t{Uld>Q7Ncq$im2aS#*q0Bbb1>(QM4!_}GaXAkP z8*m#J5Fo2zwlgOG#qTt6mzX@u!#Y2E$>3TB11q#$=~2R4I`|Hw?K#URjJ0*&?>eIS zNGgZcONiWu#D=gR1=WV%?2snF!@3CEr`lYfmkXdxWv5rHgwX6*=gaiiiZwvCZ^icz zlQ*jF7?5#6wNqBwL}lvu^0N0yol+ak2@U1Y=fa2!XYhPm)NiuP>zQzh(tRfa90&{N zO_bojUE9ZeCbjK{xjCou-vPcv8;~!${yUEp54hGw^sxBA(?xm1XBXWNOb2Z0myM5POh#S-qaYi6~2fz?vmwePHwcLRExM|SA^oxdZEwuHtJ zjW(anZ1rb}HKR;gAC{Rd=V{=t;pCZty<4f%VWhMC1$*xH{kzC7f#-(hu%pdM=$KWj zGr5N!=1xvZ_lQLC=W#^VldTK=F#3Y-tQ8ChRj8w@svrZS6Ru zS%}vX*d?}j_+|-1Y<zkWYN7AA6+({zcQ_azU=MXXwZ3iSKd5#&4S)Uq7?Mkl6>gm^sZ{ z?wIzf=UTWY6J~ynTS!}Iz0UDP&~6$*JN|f(S6B=^Cef(pB%ry98Yu zo~E*gl|JHypvzfn?oD1!VUdBH%$z|ACupnFh(PH%O~)2xtNOM|di<1JDT`U9dG6_~ z6QJo?tEzUi+5M92O4r6`hx-Dr)&iP3EK-oYZ$sctm(SMdm?szy{xT zT<|iM&d1mf9^OYx!mi9c*z6jh9+^Ic-vf0!@*NN^y?RSsf z8-w0q@PFeqr7A*0By>=WEI}M+dN@G+cX%hof~Dw#w8-yHEnDT)-)HSIKuFZP&PgTM%by zQFVCyGu^`pYu8nYG>`9A7#j5L-QBz4rxD3vV|HuN25}ube|~a`%c3FBnS-!{*mzHW zP|&0)xO}YvG!68|(1b^0^FYu847~I11s=)=Af;RdN*_^LJEK30V)rR-Jc(o7M5cX6 zyQE*Ulj-6@7rA*xnJ?BtC94WFf7`EC&LEI!7pHHPi(az4N9^^24Ss1Cfk7X6o zgAT2JPl5h*F}N104(Ja~V~!NI1BkCP2_dY9D4P+Wd3O!rSr8%?bXb1wa-@pB+kV+} z)OXZ?4;?%di85Y;mQA?9o0$oiMf!D&&yx(sx}?q}qKDyGK%~XKHRF+Tov58DP%X9g zEr{Y2hXEepEaF^JZ@vHc5s2~S9U;?cE9V=U8*aG=3$j=Q5S=og||yKDpTWb zUd^=EY`}Pf0v=^bvm+YEGQYvOt?56)@Yqk@=pex4E>QgXab`!O7?I@yb7LOtQlI5Tms=gz6f!v*3}vs9GdJig|W=QAU(k4#<$+cUJUK~yJeQm0Pi)O-d_xn~3JThk6H@!+=!DJJg+k}Wy8N9ThhE#s9 zc$%T;i4p|*$lB@%m8y-N#lzY8B7h zwVw}^jz;s@L#l;afj|43LoUeOGHew+$!#A=M=?(_X8HK)ptfkypB5qKTpF9CB@|bF zP)Y%+X!m zi97CvXMH!qzQh!`kaVm#?VpL{2c0s!$~8DG{gKlI&zku9oGfU1=`{x&7nhvZ#Mn*Q zQ*EY*n;)bLY98Ltk{jR?S&GZ)ZDj*Z=xKceH zKg)AASI3j^%JES17!fpRd{{pIl=49G@d*uHD?Dg#ipsqr5wZ^Zjkzvn6KhVUc0E)B z)56VT8(BFvBHoe~MV))^l(M`Nw#~kE20t0wi{x7$?ZS7L9E#S>G@5)rDoyEppcs55 z$D`62H$v<&jPB#GIiXqX6qiz@};e=aE%}t&42c83Ky9-M*o4p zWUx>_X0zgu^1y+IzXyAjOA1Sxpg_J7EvckmhhoPfdT(E8`X1UbN<7O@`_8_%Az(^< zUzHK`a=ao{Y6~q@I|rKgUyR^dnxK7G#a%Q;TiT~gMAy>#PVz1mKMUP)+~(fT$w;oq zJ}OuJr8uwrRB2J|L6AEvwUzWmec<(q+diIlrFv$-QnI-TxgLEZ1Xto2X(KO<v^&Hq2g`t$A4yw!&Ab8mHUSYC9MaL2 zqYkeIc|o@#q2Vqy55=ib5u=t!Iax_?Wnpq4+%a}m$rbcl-XWxymM$EXxO_!6-tJ5S z{L4|RS^0pOXK6uhNm_#-vgojk1d;A%&*vmE6^b;54zyCQGTfJPyW#MeW#Uswm7%v} zqn+CEO#!$v2gJoOh`n8@k>lQdw)^&=+X$q%oai^p*`~@d@(-OF_V!v%e}lgu8BKY4_qT_Mc@(_ZzY8ydfN~4E>#mP1NBEd>KR5-bt|7OHC=EH9CWch zJ&K|c0%EM({b}3TA1TxW`iFn!euSFMi^HqEZ*-orK_uiXcN%2jHhE8NP7NIoC`}RH zY5pDz_ln*sJ{4Q^SaLn}Wp5qtCuZ2X5H~&tWOF{nSoE#ANE(8h9XocBqU2|*<*UtL zAWn#cj%;TX+5^LOnHgJzK_80!=7t{&&sMJgq}6!Qj+U1hYK~IS7ORwnjg_zF7l9a*gtU1%Dit+rHYfZt8wWx= zSLZDe$v3YKYFo{x*M^O@t#H+yA7Qp+YO4pq=QX89NMaL zz0T2wm`n^`9;+mzBRA7ZmXbeO>$$CK4T4-4$Bj?n&-0LW2{v$W1;}&MDxtx~j%xCx zhVuKR5SOrz#j9~ei+wA7$tIW&Rte(WG_XJw+)Lt`2C*5TeL)LFHi~=T<#L&6^Yx)- zBo5pQ4bYC++2;YbRlYVnqmTe~76~)Z@$9#`AqZL=ICCHFp3AG4IK32tZW_w_ZD5b| zS{)CyX224gkLYG-F;OgBD4S)VBn%&S%E*@wsFWmWhLk^hcUPxX=?iGb^v{$TYF| zBX}TzX=a+vWqMbqy{^A@m{3R{N>BTq!G0I;kh?2d+tW~#PH3X_P22P|?U~ju3`x6} z^xRd5Jgl~nbH9rIOEeaBaC7N(pW^obzLLq8M2Zl_%i<$40X?JjP3F*=!{076;6XcJ zY2UkH>EMY2mlR)qa1&*Guv{{CW<<7);(-Ta`CgC;p@FikHTD*^YI}bwK|xFdaWD#j zt-Hqu8?Gk+i6n&R?^QnHkEQ?>U+m6ki^z|e$#p(aZ0kX|PpNulHkMT5Mt6h2|AQ}> z=HU9o2gyU=HmvuRSi8;ZepeMi*|A%!Tkk7+uK8mgZc#1<9|cd;1NAsD8M9FyY}&1%$w zt}&QS{a6g#^n0cOQ`F*4+p1*UmlNtq?o2Je16o&1Uu2#S1H?S&MLu`XHyhUOYL2)@ z_ec5SiobB(e#!=+oN*1V)W=+CL}I>Mn$okH z-B#f=HrzZ~G2snww*Ede?iF?WL;Mc4{VC4`-@BC1yh0%7A*ufX zW62tpXdFTDX(};vcCUXa$olYAkkr3gXIw!oVaVC@O%9YXHkzh;l{QuJz5}m7nera} zd8{f#LhQ^ZF?jC5+15cR+M0?IfKjHUS3H*y873BJRQUSI!Qv_&eBJe#ei9Z867Qdg z!Nuu#DZ!Ik4}$#OfFv1gdnw52l<~@Nr-#vL1O!6aeDMDQU^N2m4b5s#1drv5o#Zwi z$#E%AtN-lF23muY!O%$ZyL0a+Bf&l*{hy3yV`pOpfF;On7UL6DE7C7&E^NH1pZE=1 z&u21b&zobS;`( z3MU#+uy3%eUTL)l2(sr2x6yz|*uZ0JkrlC6jNwd$@_9M;7E?93@Bddj=l%|L7RT{s z`pRXDaT~NM<64`tavPRmMhxpxT9@o%Vuy7dQX-d;L1tovtrZf3hZJ%vW!%EZ)?&wH zANOm;gm}cT4B9h(+`nP}gY%s4=bZ03=lyzpEM+$SA)B%34OcRL-R$39(*W+C(;2yn zky487wTVzL(ieDutj5ts0rwzJwq$1OJblo9i(4d@uaZJb@|%4(H2&oNq9cwJFC@{q*_eEEd~VP zxh3L$;&*M^9%ZMyxx=18+43-&EZ{aZ@ebu;5U$93>-yhDpATwoDnoV{GXpaG8=v3; z=e+63dQ=q=!aZlWdWY?&b?{7qXF2nu24siHya+@f|BYC2U3DEe0Z?B_uTpYQmUm(? zP8P!2bMG+Y?{vhrn3RT6>RN z_oVL-1fWlLnq*cV>K=MN%L>OrW*Sb*1KF#|ydrAOhXU{_R}f7x9Mk&VEujKwfj-ZQ z0E1BGQ>1dw~Rm=-W+}7Ng^Z6#6WuGQ?hH zqwY?OYeDOuEB<{FS4kp3zjr!HYbe*>Y0-OQt_b=99D7t75}axR@MppYA2G-V6Ba)_ z9}f0CMRqNc2-r#<8OCVLxYVu%2sm%W!mQshDr9Su%bdM(QNotGl;+R01N-to>tEFS zLPaUFA?1!Dqz#u&oL@T}8I|`jqS-v);HE(-u0<+TVUX+JQ z;!1WD`US<`WcYLq;B)5GxIIJsVNQk3+!x6(2{3sCHO?(Rgv(jwDqX{~oEaZ|XhJU2 zt@*fJZgtj^CjZr9A~Y%TQDU*iA~O=n0 zx~Dn=qnSBl2X=L;;!flwiE9e`0l+^!RpLyb0~cxd2|&H;IFH>QJMr@Ir<-(^sC+QT zjOFcf8iHdov26#nhrqZW&S40j64E?E29hyN7nknQYSd&@*}D=Lr;C8s%GL;;09cg~lK>-f zsgikdZYdr>P$5R58%zd7VFHjPAv$;5d!8MT(B9^lHq`> zWU2E=UG^MLY~*jbv1oZF4POV1^{z7GQFF)f+!k@UUsfDX=|XVn03omJyAf+{`;wY{ zSOsi9BrB0~TWXR@fRBmL^tNfUFWe!YF&{){U{6j;u-#6^yl=#&VCJWi;pai7Rsb9y z>^Gz25Z-`Xe+R;lH(7UE!DW|Xi7U!jsz?t#ru;%{l8d~TD{_kwVTujfE-}YGMIr}{ zcb8W##@!lwM9{0MtZ68K}ai|fFFVS zT6VJPr`}DOM=qzAjMh0{2$27(K)N9ydDd?!c5j-;dfva3U-)%(SCF>8URb}7y4uAr zeYX?|+!6`p)CGkH)9(f2!W8o1ZO2{2|Gi - - - - - - - - - - - - Xinference - - - -
- - - diff --git a/xinference/ui/web/ui/src/App.js b/xinference/ui/web/ui/src/App.js deleted file mode 100644 index 8e77d54f1e..0000000000 --- a/xinference/ui/web/ui/src/App.js +++ /dev/null @@ -1,86 +0,0 @@ -import { CssBaseline } from '@mui/material' -import Snackbar from '@mui/material/Snackbar' -import React, { useEffect, useState } from 'react' -import { useCookies } from 'react-cookie' -import { HashRouter } from 'react-router-dom' - -import { Alert } from './components/alertComponent' -import { ApiContextProvider } from './components/apiContext' -import AuthAlertDialog from './components/authAlertDialog' -import { ThemeProvider } from './components/themeContext' -import { getEndpoint } from './components/utils' -import WraperRoutes from './router/index' - -function App() { - const [cookie, setCookie, removeCookie] = useCookies(['token']) - const [msg, setMsg] = useState('') - - const endPoint = getEndpoint() - - useEffect(() => { - // token possible value: no_auth / need_auth / - fetch(endPoint + '/v1/cluster/auth', { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }).then((res) => { - if (!res.ok) { - res.json().then((errorData) => { - setMsg( - `Server error: ${res.status} - ${ - errorData.detail || 'Unknown error' - }` - ) - }) - } else { - res.json().then((data) => { - if (!data.auth) { - setCookie('token', 'no_auth', { path: '/' }) - sessionStorage.setItem('token', 'no_auth') - } else if ( - data.auth && - sessionStorage.getItem('token') === 'no_auth' - ) { - removeCookie('token', { path: '/' }) - sessionStorage.removeItem('token') - } - sessionStorage.setItem('auth', String(data.auth)) // sessionStorage only can set string value - }) - } - }) - }, [cookie]) - - const handleClose = (event, reason) => { - if (reason === 'clickaway') { - return - } - setMsg('') - } - - return ( -
- - - - {msg} - - - - - - - - - - -
- ) -} - -export default App diff --git a/xinference/ui/web/ui/src/components/MenuSide.js b/xinference/ui/web/ui/src/components/MenuSide.js deleted file mode 100644 index 00a9edf503..0000000000 --- a/xinference/ui/web/ui/src/components/MenuSide.js +++ /dev/null @@ -1,499 +0,0 @@ -import { - AccountCircleOutlined, - AddBoxOutlined, - ArticleOutlined, - ChevronLeftOutlined, - ChevronRightOutlined, - DescriptionOutlined, - DnsOutlined, - GitHub, - Language, - LogoutOutlined, - MonitorHeartOutlined, - OpenInNew, - PeopleOutlined, - Psychology, - RocketLaunchOutlined, - SecurityOutlined, - SmartToyOutlined, - VpnKeyOutlined, -} from '@mui/icons-material' -import { - Box, - Drawer, - IconButton, - List, - ListItem, - ListItemButton, - ListItemIcon, - ListItemText, - Tooltip, - Typography, -} from '@mui/material' -import { useContext, useEffect, useState } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import icon from '../media/icon.png' -import { hasPermission, parseTokenFromSession } from '../utils/jwt' -import { ApiContext } from './apiContext' -import ThemeButton from './themeButton' -import TranslateButton from './translateButton' -import { isValidBearerToken } from './utils' -import VersionLabel from './versionLabel' - -const COLLAPSED_KEY = 'xinference_sidebar_collapsed' -const COLLAPSED_WIDTH = 64 - -function readCollapsed() { - try { - return localStorage.getItem(COLLAPSED_KEY) === 'true' - } catch { - return false - } -} - -function writeCollapsed(val) { - try { - localStorage.setItem(COLLAPSED_KEY, String(val)) - } catch { - // ignore - } -} - -const MenuSide = () => { - const navigate = useNavigate() - const [collapsed, setCollapsed] = useState(readCollapsed) - const [drawerWidth, setDrawerWidth] = useState( - `${Math.min(Math.max(window.innerWidth * 0.2, 287), 320)}px` - ) - const { i18n, t } = useTranslation() - const { endPoint } = useContext(ApiContext) - const [esEnabled, setEsEnabled] = useState(false) - const [authAdvanced, setAuthAdvanced] = useState(false) - const [scopes, setScopes] = useState([]) - const [, , removeCookie] = useCookies(['token']) - const [currentUser, setCurrentUser] = useState('') - - const currentWidth = collapsed ? `${COLLAPSED_WIDTH}px` : drawerWidth - - useEffect(() => { - fetch(endPoint + '/v1/cluster/ui_config') - .then((res) => { - if (!res.ok) throw new Error('Network response was not ok') - return res.json() - }) - .then((data) => { - setEsEnabled(data.es_enabled || false) - setAuthAdvanced(data.auth_advanced || false) - }) - .catch(() => setEsEnabled(false)) - - // Parse username + scopes from JWT token. The backend (advanced auth) - // enforces scopes against DB-current permissions on every request, so - // the menu's role is just to reflect what the current token allows. - const parsed = parseTokenFromSession() - if (parsed) { - setCurrentUser(parsed.username) - setScopes(parsed.scopes) - } - }, [endPoint]) - - // Re-parse JWT when the access token is refreshed by fetchWrapper, so the - // menu recomputes permission-gated items without a page reload. - useEffect(() => { - const handler = () => { - const parsed = parseTokenFromSession() - if (parsed) { - setCurrentUser(parsed.username) - setScopes(parsed.scopes) - } else { - setScopes([]) - setCurrentUser('') - } - } - window.addEventListener('auth-refreshed', handler) - return () => window.removeEventListener('auth-refreshed', handler) - }, []) - - const navItems = [ - { - text: 'launch_model', - label: t('menu.launchModel'), - icon: , - action: 'navigate', - path: '/launch_model/llm', - session: { - modelType: '/launch_model/llm', - lastActiveUrl: 'launch_model', - }, - }, - { - text: 'running_models', - label: t('menu.runningModels'), - icon: , - action: 'navigate', - path: '/running_models/LLM', - session: { - runningModelType: '/running_models/LLM', - lastActiveUrl: 'running_models', - }, - }, - { - text: 'register_model', - label: t('menu.registerModel'), - icon: , - action: 'navigate', - path: '/register_model/llm', - session: { - registerModelType: '/register_model/llm', - lastActiveUrl: 'register_model', - }, - }, - ...(hasPermission(scopes, 'admin') - ? [ - { - text: 'cluster_information', - label: t('menu.clusterInfo'), - icon: , - action: 'navigate', - path: '/cluster_info', - }, - ] - : []), - ...(hasPermission(scopes, 'monitor:view') - ? [ - { - text: 'monitoring', - label: t('menu.monitoring'), - icon: , - action: 'navigate', - path: '/monitoring', - }, - ] - : []), - ...(esEnabled && hasPermission(scopes, 'logs:list') - ? [ - { - text: 'logs', - label: t('menu.logs'), - icon: , - action: 'navigate', - path: '/logs', - }, - ] - : []), - ...(hasPermission(scopes, 'admin') - ? [ - { - text: 'audit_log', - label: t('menu.auditLog') || 'Audit Log', - icon: , - action: 'navigate', - path: '/audit_log', - }, - ] - : []), - ...(authAdvanced && hasPermission(scopes, 'users:manage') - ? [ - { - text: 'user_management', - label: t('menu.userManagement'), - icon: , - action: 'navigate', - path: '/user_management', - }, - ] - : []), - ...(authAdvanced && - (hasPermission(scopes, 'keys:create') || - hasPermission(scopes, 'keys:manage')) - ? [ - { - text: 'apikey_management', - label: t('menu.apikeyManagement'), - icon: , - action: 'navigate', - path: '/apikey_management', - }, - ] - : []), - ...(authAdvanced && hasPermission(scopes, 'admin') - ? [ - { - text: 'security_settings', - label: t('menu.securitySettings') || 'Security', - icon: , - action: 'navigate', - path: '/security_settings', - }, - ] - : []), - { - text: 'documentation', - label: t('menu.documentation'), - icon: , - action: 'external', - url: - 'https://inference.readthedocs.io/' + - (i18n.language === 'zh' ? 'zh-cn' : ''), - }, - { - text: 'contact_us', - label: t('menu.contactUs'), - icon: , - action: 'external', - url: 'https://github.com/xorbitsai/inference', - }, - { - text: 'website', - label: t('menu.website'), - icon: , - action: 'external', - url: - i18n.language === 'zh' - ? 'https://xinference.cn' - : 'https://xinference.io', - }, - { - text: 'xagent', - label: t('menu.xagent'), - icon: ( - - ), - action: 'external', - url: 'https://github.com/xorbitsai/xagent', - }, - ] - - useEffect(() => { - const handleResize = () => { - const screenWidth = window.innerWidth - const maxDrawerWidth = Math.min(Math.max(screenWidth * 0.2, 287), 320) - setDrawerWidth(`${maxDrawerWidth}px`) - } - - handleResize() - window.addEventListener('resize', handleResize) - return () => { - window.removeEventListener('resize', handleResize) - } - }, []) - - const toggleCollapsed = () => { - const next = !collapsed - setCollapsed(next) - writeCollapsed(next) - } - - const handleLogout = () => { - const refreshToken = sessionStorage.getItem('refresh_token') - if (refreshToken) { - fetch(endPoint + '/v1/auth/logout', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ refresh_token: refreshToken }), - }).catch(() => {}) - } - removeCookie('token', { path: '/' }) - sessionStorage.removeItem('token') - sessionStorage.removeItem('refresh_token') - sessionStorage.removeItem('auth') - sessionStorage.removeItem('modelType') - sessionStorage.removeItem('lastActiveUrl') - sessionStorage.removeItem('runningModelType') - sessionStorage.removeItem('registerModelType') - navigate('/login', { replace: true }) - } - - const handleNavClick = (item) => { - const { action, url, path, text, session } = item - if (action === 'external' && url) { - window.open(url, '_blank', 'noreferrer') - return - } - - if (action === 'navigate') { - if (session) { - Object.entries(session).forEach(([key, value]) => { - sessionStorage.setItem(key, value) - }) - } - navigate(path ?? `/${text}`) - return - } - - navigate(`/${text}`) - } - - const transition = 'width 0.2s ease' - - return ( - - {/* Logo */} - - - {!collapsed && ( - - - {'Xinference'} - - - )} - - - {/* Nav items */} - - - {navItems.map((item) => { - const { text, label, icon: navIcon, action } = item - return ( - - {collapsed ? ( - - handleNavClick(item)} - > - - {navIcon} - - - - ) : ( - handleNavClick(item)} - > - - {navIcon} - - - {action === 'external' ? ( - - ) : ( - - )} - - )} - - ) - })} - - - - {/* Bottom toolbar — collapses to zero height when sidebar collapsed */} - - - - - - - {/* User info + Logout + Collapse toggle */} - - {collapsed ? ( - - {isValidBearerToken(sessionStorage.getItem('token')) && ( - - - - - - )} - - - - - - - ) : ( - - {isValidBearerToken(sessionStorage.getItem('token')) && ( - <> - - - {currentUser || 'user'} - - - - - - - - )} - - - - - - - )} - - - ) -} - -export default MenuSide diff --git a/xinference/ui/web/ui/src/components/Title.js b/xinference/ui/web/ui/src/components/Title.js deleted file mode 100644 index fd0b459f96..0000000000 --- a/xinference/ui/web/ui/src/components/Title.js +++ /dev/null @@ -1,15 +0,0 @@ -import { Box, Stack, Typography } from '@mui/material' - -const Title = ({ title }) => { - return ( - - - - {title} - - - - ) -} - -export default Title diff --git a/xinference/ui/web/ui/src/components/alertComponent.js b/xinference/ui/web/ui/src/components/alertComponent.js deleted file mode 100644 index 4603b3f9c6..0000000000 --- a/xinference/ui/web/ui/src/components/alertComponent.js +++ /dev/null @@ -1,8 +0,0 @@ -import MuiAlert from '@mui/material/Alert' -import React from 'react' - -const Alert = React.forwardRef(function Alert(props, ref) { - return -}) - -export { Alert } diff --git a/xinference/ui/web/ui/src/components/apiContext.js b/xinference/ui/web/ui/src/components/apiContext.js deleted file mode 100644 index 6c6f87e22a..0000000000 --- a/xinference/ui/web/ui/src/components/apiContext.js +++ /dev/null @@ -1,31 +0,0 @@ -import React, { createContext, useState } from 'react' - -import { getEndpoint } from './utils' - -export const ApiContext = createContext() - -export const ApiContextProvider = ({ children }) => { - const [isCallingApi, setIsCallingApi] = useState(false) - const [isUpdatingModel, setIsUpdatingModel] = useState(false) - const [errorMsg, setErrorMsg] = useState('') - const [successMsg, setSuccessMsg] = useState('') - const endPoint = getEndpoint() - - return ( - - {children} - - ) -} diff --git a/xinference/ui/web/ui/src/components/authAlertDialog.js b/xinference/ui/web/ui/src/components/authAlertDialog.js deleted file mode 100644 index 414b693e40..0000000000 --- a/xinference/ui/web/ui/src/components/authAlertDialog.js +++ /dev/null @@ -1,104 +0,0 @@ -import { - Button, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, -} from '@mui/material' -import * as React from 'react' -import { useEffect, useState } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -export default function AuthAlertDialog() { - const { t } = useTranslation() - const navigate = useNavigate() - const [authStatus, setAuthStatus] = useState('') - const [, , removeCookie] = useCookies(['token']) - - const handleAuthStatus = () => { - const status = localStorage.getItem('authStatus') - if (status === '401') { - removeCookie('token', { path: '/' }) - localStorage.removeItem('authStatus') - sessionStorage.removeItem('token') - navigate('/login', { replace: true }) - return - } - if (status) { - setAuthStatus(status) - } else { - setAuthStatus('') - } - } - - useEffect(() => { - localStorage.removeItem('authStatus') - window.addEventListener('auth-status', handleAuthStatus) - - return () => { - window.removeEventListener('auth-status', handleAuthStatus) - } - }, []) - - const handleClose = () => { - // trigger first - const code = localStorage.getItem('authStatus') - localStorage.removeItem('authStatus') - setAuthStatus('') - if (code === '401') { - removeCookie('token', { path: '/' }) - sessionStorage.removeItem('token') - navigate('/login', { replace: true }) - } - } - - const handleDialogClose = (event, reason) => { - if (reason && reason === 'backdropClick') { - return - } - localStorage.removeItem('authStatus') - setAuthStatus('') - } - - return ( - - - {authStatus === '403' && ( - - {t('auth.permissionError')} - - )} - {authStatus === '401' && ( - - {t('auth.authenticationError')} - - )} - - {authStatus === '403' && ( - - {t('auth.noPermission')} - - )} - {authStatus === '401' && ( - - {t('auth.invalidCredentials')} - - )} - - - - - - - ) -} diff --git a/xinference/ui/web/ui/src/components/copyComponent.js b/xinference/ui/web/ui/src/components/copyComponent.js deleted file mode 100644 index 9970df67bd..0000000000 --- a/xinference/ui/web/ui/src/components/copyComponent.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Clear, ContentCopy, Done } from '@mui/icons-material' -import { IconButton, Tooltip } from '@mui/material' -import React, { useState } from 'react' - -import { copyToClipboard } from './utils' - -const CopyComponent = ({ tip, text }) => { - const [copyStatus, setCopyStatus] = useState('pending') - - const showTooltipTemporarily = (status) => { - setCopyStatus(status) - setTimeout(() => setCopyStatus('pending'), 1500) - } - - const handleCopy = async (event) => { - event.stopPropagation() - const textToCopy = String(text ?? '') - const success = await copyToClipboard(textToCopy) - showTooltipTemporarily(success ? 'success' : 'failed') - } - - return ( - <> - {copyStatus === 'pending' ? ( - - - - - - ) : copyStatus === 'success' ? ( - - - - ) : ( - - - - )} - - ) -} - -export default CopyComponent diff --git a/xinference/ui/web/ui/src/components/deleteDialog.js b/xinference/ui/web/ui/src/components/deleteDialog.js deleted file mode 100644 index a5036bd663..0000000000 --- a/xinference/ui/web/ui/src/components/deleteDialog.js +++ /dev/null @@ -1,49 +0,0 @@ -import { WarningAmber } from '@mui/icons-material' -import { - Button, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, -} from '@mui/material' -import React from 'react' -import { useTranslation } from 'react-i18next' - -const DeleteDialog = ({ text, isDelete, onHandleIsDelete, onHandleDelete }) => { - const { t } = useTranslation() - return ( - - - {t('components.warning')} - - - - -

{text}

-
-
- - - - -
- ) -} - -export default DeleteDialog diff --git a/xinference/ui/web/ui/src/components/errorMessageSnackBar.js b/xinference/ui/web/ui/src/components/errorMessageSnackBar.js deleted file mode 100644 index 905f84d50b..0000000000 --- a/xinference/ui/web/ui/src/components/errorMessageSnackBar.js +++ /dev/null @@ -1,31 +0,0 @@ -import Snackbar from '@mui/material/Snackbar' -import React, { useContext } from 'react' - -import { Alert } from './alertComponent' -import { ApiContext } from './apiContext' - -const ErrorMessageSnackBar = () => { - const { errorMsg, setErrorMsg } = useContext(ApiContext) - - const handleClose = (event, reason) => { - if (reason === 'clickaway') { - return - } - setErrorMsg('') - } - - return ( - - - {errorMsg} - - - ) -} - -export default ErrorMessageSnackBar diff --git a/xinference/ui/web/ui/src/components/fetchWrapper.js b/xinference/ui/web/ui/src/components/fetchWrapper.js deleted file mode 100644 index 4a91b6b82a..0000000000 --- a/xinference/ui/web/ui/src/components/fetchWrapper.js +++ /dev/null @@ -1,194 +0,0 @@ -import { Cookies } from 'react-cookie' - -const cookies = new Cookies() - -const getBaseUrl = () => { - let base_URL = '' - if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') { - base_URL = 'http://127.0.0.1:9997' - } else { - const fullUrl = window.location.href - base_URL = fullUrl.split('/ui')[0] - } - return base_URL -} - -const apiBase = getBaseUrl() - -let isRefreshing = false -let refreshPromise = null -let failedQueue = [] - -const processQueue = (success) => { - failedQueue.forEach((prom) => { - if (success) { - prom.resolve(success) - } else { - prom.reject() - } - }) - failedQueue = [] -} - -const tryRefreshToken = async () => { - if (isRefreshing) { - return new Promise((resolve, reject) => { - failedQueue.push({ resolve, reject }) - }) - } - const refreshToken = sessionStorage.getItem('refresh_token') - if (!refreshToken) return false - isRefreshing = true - refreshPromise = fetch(`${apiBase}/v1/auth/refresh`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ refresh_token: refreshToken }), - }) - .then(async (res) => { - if (res.ok) { - const data = await res.json() - cookies.set('token', data.access_token, { path: '/' }) - sessionStorage.setItem('token', data.access_token) - if (data.refresh_token) { - sessionStorage.setItem('refresh_token', data.refresh_token) - } - processQueue(true) - // Notify listeners (e.g., MenuSide) that the token was refreshed so - // they can re-read permissions from the new JWT without a page reload. - window.dispatchEvent(new Event('auth-refreshed')) - return true - } - processQueue(false) - return false - }) - .catch(() => { - processQueue(false) - return false - }) - .finally(() => { - isRefreshing = false - refreshPromise = null - }) - return refreshPromise -} - -const getAuthHeaders = () => { - const headers = {} - if ( - cookies.get('token') !== 'no_auth' && - sessionStorage.getItem('token') !== 'no_auth' - ) { - headers.Authorization = 'Bearer ' + sessionStorage.getItem('token') - } - return headers -} - -const fetchWithRetry = async (url, options) => { - const response = await fetch(url, options) - if (response.status === 401 && sessionStorage.getItem('refresh_token')) { - const refreshed = await tryRefreshToken() - if (refreshed) { - const newHeaders = { - ...options.headers, - Authorization: 'Bearer ' + sessionStorage.getItem('token'), - } - return fetch(url, { ...options, headers: newHeaders }) - } - } - return response -} - -const fetchWrapper = { - get: async (endpoint, config = {}) => { - const url = `${apiBase}${endpoint}` - const headers = { - 'Content-Type': 'application/json', - ...getAuthHeaders(), - ...config.headers, - } - const response = await fetchWithRetry(url, { - method: 'GET', - ...config, - headers, - }) - return fetchWrapper.handleResponse(response) - }, - - post: async (endpoint, body, config = {}) => { - const url = `${apiBase}${endpoint}` - const headers = { - 'Content-Type': 'application/json', - ...getAuthHeaders(), - ...config.headers, - } - const response = await fetchWithRetry(url, { - method: 'POST', - body: JSON.stringify(body), - ...config, - headers, - }) - return fetchWrapper.handleResponse(response) - }, - - put: async (endpoint, body, config = {}) => { - const url = `${apiBase}${endpoint}` - const headers = { - 'Content-Type': 'application/json', - ...getAuthHeaders(), - ...config.headers, - } - const response = await fetchWithRetry(url, { - method: 'PUT', - body: JSON.stringify(body), - ...config, - headers, - }) - return fetchWrapper.handleResponse(response) - }, - - delete: async (endpoint, config = {}) => { - const url = `${apiBase}${endpoint}` - const headers = { - 'Content-Type': 'application/json', - ...getAuthHeaders(), - ...config.headers, - } - const response = await fetchWithRetry(url, { - method: 'DELETE', - ...config, - headers, - }) - return fetchWrapper.handleResponse(response) - }, - - handleResponse: async (response) => { - if ( - response.status == 401 && - localStorage.getItem('authStatus') !== '401' - ) { - localStorage.setItem('authStatus', '401') - window.dispatchEvent(new Event('auth-status')) - } else if ( - response.status == 403 && - localStorage.getItem('authStatus') !== '403' - ) { - localStorage.setItem('authStatus', '403') - window.dispatchEvent(new Event('auth-status')) - } - - if (!response.ok) { - const errorData = await response.json() - const error = new Error( - `Server error: ${response.status} - ${ - errorData.detail || 'Unknown error' - }` - ) - error.response = response - throw error - } - const data = await response.json() - return data - }, -} - -export default fetchWrapper diff --git a/xinference/ui/web/ui/src/components/fetcher.js b/xinference/ui/web/ui/src/components/fetcher.js deleted file mode 100644 index cbd25cab68..0000000000 --- a/xinference/ui/web/ui/src/components/fetcher.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Cookies } from 'react-cookie' - -const cookies = new Cookies() - -const updateOptions = (url, options) => { - const update = { ...options } - if ( - cookies.get('token') !== 'no_auth' && - sessionStorage.getItem('token') !== 'no_auth' - ) { - update.headers = { - ...update.headers, - Authorization: 'Bearer ' + sessionStorage.getItem('token'), - } - } - return update -} - -function ensureProtocol(url) { - if (window.location.protocol === 'https:' && url.startsWith('http://')) { - return url.replace('http://', 'https://') - } - return url -} - -export default function fetcher(url, options) { - return fetch(ensureProtocol(url), updateOptions(url, options)).then((res) => { - // For the situation that server has already been restarted, the current token may become invalid, - // which leads to UI hangs. - if (res.status == 401 && localStorage.getItem('authStatus') !== '401') { - localStorage.setItem('authStatus', '401') - window.dispatchEvent(new Event('auth-status')) - } else if ( - res.status == 403 && - localStorage.getItem('authStatus') !== '403' - ) { - localStorage.setItem('authStatus', '403') - window.dispatchEvent(new Event('auth-status')) - } else { - return res - } - }) -} diff --git a/xinference/ui/web/ui/src/components/grafanaUtils.js b/xinference/ui/web/ui/src/components/grafanaUtils.js deleted file mode 100644 index 122c4df7b7..0000000000 --- a/xinference/ui/web/ui/src/components/grafanaUtils.js +++ /dev/null @@ -1,108 +0,0 @@ -/** - * Build Grafana iframe URL for a specific sub-dashboard (kiosk mode). - * @param {object} config - UI config from /v1/cluster/ui_config - * @param {string} dashboardKey - sub-dashboard key (overview, model_load, llm_slo, gpu, host, security) - * @param {string} theme - light/dark - * @param {string} from - time range start - * @param {string} to - time range end - * @param {string} refresh - auto-refresh interval - */ -export const buildGrafanaUrl = ( - config, - dashboardKey = 'overview', - theme = 'light', - from = 'now-1h', - to = 'now', - refresh -) => { - const { - grafana_url, - grafana_dashboard_uid, - grafana_dashboards, - grafana_datasource, - grafana_alert_datasource, - cluster_name, - } = config - if (!grafana_url) return null - - // Get dashboard UID from grafana_dashboards map, fallback to legacy field - const dashboardUid = - grafana_dashboards?.[dashboardKey] || - grafana_dashboard_uid || - 'xinference-overview' - - let url = `${grafana_url}/d/${dashboardUid}?orgId=1&kiosk&theme=${theme}&from=${encodeURIComponent( - from - )}&to=${encodeURIComponent(to)}` - - if (grafana_datasource) { - url += `&var-datasource=${encodeURIComponent(grafana_datasource)}` - } - if (grafana_alert_datasource) { - url += `&var-alert_datasource=${encodeURIComponent( - grafana_alert_datasource - )}` - } - if (cluster_name) { - url += `&var-cluster=${encodeURIComponent(cluster_name)}` - } - if (refresh !== undefined) { - url += `&refresh=${encodeURIComponent(refresh)}` - } - - return url -} - -/** - * Build Grafana single-panel embed URL (for model detail pages). - * @param {object} config - UI config - * @param {string} dashboardKey - sub-dashboard key - * @param {number} panelId - panel ID - * @param {string} modelName - model name filter - * @param {string} theme - light/dark - * @param {string} from - time range start - * @param {string} to - time range end - */ -export const buildGrafanaPanelUrl = ( - config, - dashboardKey = 'overview', - panelId, - modelName, - theme = 'light', - from = 'now-1h', - to = 'now' -) => { - const { - grafana_url, - grafana_dashboard_uid, - grafana_dashboards, - grafana_datasource, - grafana_alert_datasource, - cluster_name, - } = config - if (!grafana_url) return null - - const dashboardUid = - grafana_dashboards?.[dashboardKey] || - grafana_dashboard_uid || - 'xinference-overview' - - let url = `${grafana_url}/d-solo/${dashboardUid}?orgId=1&kiosk&theme=${theme}&panelId=${panelId}&from=${from}&to=${to}` - - if (grafana_datasource) { - url += `&var-datasource=${encodeURIComponent(grafana_datasource)}` - } - if (grafana_alert_datasource) { - url += `&var-alert_datasource=${encodeURIComponent( - grafana_alert_datasource - )}` - } - if (cluster_name) { - url += `&var-cluster=${encodeURIComponent(cluster_name)}` - } - if (modelName) { - url += `&var-model_name=${encodeURIComponent(modelName)}` - } - - return url -} diff --git a/xinference/ui/web/ui/src/components/hotkeyFocusTextField.js b/xinference/ui/web/ui/src/components/hotkeyFocusTextField.js deleted file mode 100644 index cc3b51a888..0000000000 --- a/xinference/ui/web/ui/src/components/hotkeyFocusTextField.js +++ /dev/null @@ -1,59 +0,0 @@ -import { TextField } from '@mui/material' -import InputAdornment from '@mui/material/InputAdornment' -import Typography from '@mui/material/Typography' -import React, { useEffect, useRef, useState } from 'react' - -const HotkeyFocusTextField = ({ - label, - value, - onChange, - hotkey = 'Enter', - t, - ...props -}) => { - const [isFocused, setIsFocused] = useState(false) - const textFieldRef = useRef(null) - const handleKeyDown = (event) => { - if ( - event.key === hotkey && - document.activeElement !== textFieldRef.current - ) { - event.preventDefault() - setIsFocused(true) - textFieldRef.current?.focus() - } - } - - useEffect(() => { - document.addEventListener('keydown', handleKeyDown) - - return () => { - document.removeEventListener('keydown', handleKeyDown) - } - }, [hotkey]) - - return ( - setIsFocused(false)} - onFocus={() => setIsFocused(true)} - InputProps={{ - endAdornment: - !isFocused && !value ? ( - - - {t('launchModel.searchInstruction', { hotkey })} - - - ) : null, - }} - /> - ) -} - -export default HotkeyFocusTextField diff --git a/xinference/ui/web/ui/src/components/successMessageSnackBar.js b/xinference/ui/web/ui/src/components/successMessageSnackBar.js deleted file mode 100644 index cd5211ad1b..0000000000 --- a/xinference/ui/web/ui/src/components/successMessageSnackBar.js +++ /dev/null @@ -1,31 +0,0 @@ -import Snackbar from '@mui/material/Snackbar' -import React, { useContext } from 'react' - -import { Alert } from './alertComponent' -import { ApiContext } from './apiContext' - -const SuccessMessageSnackBar = () => { - const { successMsg, setSuccessMsg } = useContext(ApiContext) - - const handleClose = (event, reason) => { - if (reason === 'clickaway') { - return - } - setSuccessMsg('') - } - - return ( - - - {successMsg} - - - ) -} - -export default SuccessMessageSnackBar diff --git a/xinference/ui/web/ui/src/components/tableTitle.js b/xinference/ui/web/ui/src/components/tableTitle.js deleted file mode 100644 index d237758b18..0000000000 --- a/xinference/ui/web/ui/src/components/tableTitle.js +++ /dev/null @@ -1,21 +0,0 @@ -import Typography from '@mui/material/Typography' -import PropTypes from 'prop-types' -import React from 'react' - -export default function TableTitle(props) { - return ( - - {props.children} - - ) -} - -TableTitle.propTypes = { - component: PropTypes.elementType, - children: PropTypes.node, -} diff --git a/xinference/ui/web/ui/src/components/themeButton.js b/xinference/ui/web/ui/src/components/themeButton.js deleted file mode 100644 index f85f648f91..0000000000 --- a/xinference/ui/web/ui/src/components/themeButton.js +++ /dev/null @@ -1,20 +0,0 @@ -import DarkModeIcon from '@mui/icons-material/DarkMode' -import LightModeIcon from '@mui/icons-material/LightMode' -import { Box, IconButton } from '@mui/material' -import React from 'react' - -import { useThemeContext } from './themeContext' - -const ThemeButton = ({ sx }) => { - const { themeMode, toggleTheme } = useThemeContext() - - return ( - - - {themeMode === 'light' ? : } - - - ) -} - -export default ThemeButton diff --git a/xinference/ui/web/ui/src/components/themeContext.js b/xinference/ui/web/ui/src/components/themeContext.js deleted file mode 100644 index ebebf86924..0000000000 --- a/xinference/ui/web/ui/src/components/themeContext.js +++ /dev/null @@ -1,36 +0,0 @@ -import { ThemeProvider as MuiThemeProvider } from '@mui/material' -import { createContext, useContext, useState } from 'react' - -import { useMode } from '../theme' - -const ThemeContext = createContext() - -export function useThemeContext() { - return useContext(ThemeContext) -} - -export const ThemeProvider = ({ children }) => { - const themeKey = 'theme' - const systemPreference = window.matchMedia('(prefers-color-scheme: dark)') - .matches - ? 'dark' - : 'light' - const initialMode = localStorage.getItem(themeKey) || systemPreference - - const [themeMode, setThemeMode] = useState(initialMode) - const theme = useMode(themeMode)[0] - - const switchTheme = () => { - const nextTheme = themeMode === 'light' ? 'dark' : 'light' - setThemeMode(nextTheme) - localStorage.setItem(themeKey, nextTheme) - } - - return ( - - - {children} - - - ) -} diff --git a/xinference/ui/web/ui/src/components/titleTypography.js b/xinference/ui/web/ui/src/components/titleTypography.js deleted file mode 100644 index dc4fcfd822..0000000000 --- a/xinference/ui/web/ui/src/components/titleTypography.js +++ /dev/null @@ -1,22 +0,0 @@ -import Typography from '@mui/material/Typography' -import React from 'react' - -const h2Style = { - margin: '10px 10px', - fontSize: '20px', - fontWeight: 'bold', -} - -export default function TitleTypography({ value }) { - return ( - - {value} - - ) -} diff --git a/xinference/ui/web/ui/src/components/translateButton.js b/xinference/ui/web/ui/src/components/translateButton.js deleted file mode 100644 index 1ed2d46a5b..0000000000 --- a/xinference/ui/web/ui/src/components/translateButton.js +++ /dev/null @@ -1,111 +0,0 @@ -import Translate from '@mui/icons-material/Translate' -import { - Box, - ClickAwayListener, - IconButton, - List, - ListItem, - ListItemButton, - ListItemText, - Tooltip, -} from '@mui/material' -import React from 'react' -import { useTranslation } from 'react-i18next' - -const TranslateButton = ({ sx }) => { - const [open, setOpen] = React.useState(false) - const { i18n } = useTranslation() - const languages = React.useMemo( - () => [ - { language: 'English', code: 'en', flag: '🇺🇸' }, - { language: '中文', code: 'zh', flag: '🇨🇳' }, - { language: '日本語', code: 'ja', flag: '🇯🇵' }, - { language: '한국어', code: 'ko', flag: '🇰🇷' }, - ], - [] - ) - - const normalizeLang = (lng) => - String(lng || '') - .toLowerCase() - .split('-')[0] - const currentLang = normalizeLang(i18n.language) - - const changeLanguage = (lng) => { - if (normalizeLang(i18n.language) === lng) { - handleTooltipClose() - return - } - i18n.changeLanguage(lng) - handleTooltipClose() - } - - const handleTooltipClose = () => { - setOpen(false) - } - - const handleKeyDown = (e) => { - if (e.key === 'Escape') { - handleTooltipClose() - } - } - - return ( - - - {languages.map((item, index) => { - return ( - changeLanguage(item.code)} - > - - - - - ) - })} - - } - > - - setOpen((prev) => !prev)} - > - - - - - - ) -} - -export default TranslateButton diff --git a/xinference/ui/web/ui/src/components/utils.js b/xinference/ui/web/ui/src/components/utils.js deleted file mode 100644 index 0bd8a3851f..0000000000 --- a/xinference/ui/web/ui/src/components/utils.js +++ /dev/null @@ -1,49 +0,0 @@ -export const getEndpoint = () => { - if (!process.env.NODE_ENV || process.env.NODE_ENV === 'development') { - return 'http://127.0.0.1:9997' - } - return window.location.origin -} - -export const isValidBearerToken = (token) => { - return ( - token !== '' && token !== undefined && token !== null && token.length > 10 - ) -} - -export const toReadableSize = (size) => { - const res_size = size / 1024.0 ** 2 - return res_size.toFixed(2) + 'MiB' -} - -export async function copyToClipboard(text) { - if (navigator.clipboard && window.isSecureContext) { - try { - await navigator.clipboard.writeText(text) - return true - } catch { - return false - } - } - - try { - const container = - document.querySelector('[role="dialog"]') || - document.querySelector('.drawerCard') || - document.body - - const textArea = document.createElement('textarea') - textArea.value = text - textArea.style.position = 'absolute' - textArea.style.left = '-9999px' - container.appendChild(textArea) - - textArea.select() - const success = document.execCommand('copy') - - container.removeChild(textArea) - return success - } catch { - return false - } -} diff --git a/xinference/ui/web/ui/src/components/versionLabel.js b/xinference/ui/web/ui/src/components/versionLabel.js deleted file mode 100644 index cbbad29900..0000000000 --- a/xinference/ui/web/ui/src/components/versionLabel.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Box, Typography } from '@mui/material' -import React, { useEffect, useState } from 'react' - -import fetchWrapper from '../components/fetchWrapper' - -const VersionLabel = ({ sx }) => { - const [version, setVersion] = useState('') - - useEffect(() => { - fetchWrapper - .get('/v1/cluster/version') - .then((data) => { - setVersion('v' + data['version']) - }) - .catch((error) => { - console.error('Error:', error) - }) - }, []) - - return ( - - {version} - - ) -} - -export default VersionLabel diff --git a/xinference/ui/web/ui/src/i18n.js b/xinference/ui/web/ui/src/i18n.js deleted file mode 100644 index 08dcc20770..0000000000 --- a/xinference/ui/web/ui/src/i18n.js +++ /dev/null @@ -1,43 +0,0 @@ -import i18n from 'i18next' -import { initReactI18next } from 'react-i18next' - -import en from './locales/en.json' -import ja from './locales/ja.json' -import ko from './locales/ko.json' -import zh from './locales/zh.json' - -const supportedLangs = ['en', 'zh', 'ja', 'ko'] -const detectBrowserLanguage = () => { - try { - const candidate = - (typeof navigator !== 'undefined' && - (navigator.languages?.[0] || navigator.language)) || - '' - const normalized = String(candidate).toLowerCase() - const prefix = normalized.split('-')[0] - return supportedLangs.includes(prefix) ? prefix : 'en' - } catch { - return 'en' - } -} - -i18n.use(initReactI18next).init({ - fallbackLng: 'en', - lng: localStorage.getItem('language') || detectBrowserLanguage(), - debug: true, - interpolation: { - escapeValue: false, - }, - resources: { - en: { translation: en }, - zh: { translation: zh }, - ja: { translation: ja }, - ko: { translation: ko }, - }, -}) - -i18n.on('languageChanged', (lng) => { - localStorage.setItem('language', lng) -}) - -export default i18n diff --git a/xinference/ui/web/ui/src/index.css b/xinference/ui/web/ui/src/index.css deleted file mode 100644 index 30eb6dbfd4..0000000000 --- a/xinference/ui/web/ui/src/index.css +++ /dev/null @@ -1,30 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap'); - -html, -body, -#root, -.app { - height: 100%; - width: 100%; - font-family: 'Inter', sans-serif; -} - -::-webkit-scrollbar { - width: 8px; -} - -/* Track */ -::-webkit-scrollbar-track { - background: #00000000; -} - -/* Handle */ -::-webkit-scrollbar-thumb { - background: #7c767640; - border-radius: 120px; -} - -/* Handle on Hover */ -::-webkit-scrollbar-track:hover { - background: #b3b4ba10; -} diff --git a/xinference/ui/web/ui/src/index.js b/xinference/ui/web/ui/src/index.js deleted file mode 100644 index c252da2d66..0000000000 --- a/xinference/ui/web/ui/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import './i18n' - -import React from 'react' -import { CookiesProvider } from 'react-cookie' -import ReactDOM from 'react-dom/client' - -import App from './App' - -const root = ReactDOM.createRoot(document.getElementById('root')) -root.render( - - - - - -) diff --git a/xinference/ui/web/ui/src/locales/en.json b/xinference/ui/web/ui/src/locales/en.json deleted file mode 100644 index 1289fb026e..0000000000 --- a/xinference/ui/web/ui/src/locales/en.json +++ /dev/null @@ -1,596 +0,0 @@ -{ - "menu": { - "launchModel": "Launch Model", - "runningModels": "Running Models", - "registerModel": "Register Model", - "clusterInfo": "Cluster Information", - "monitoring": "Monitoring", - "logs": "Log Center", - "xagent": "Build AI Agents with Xagent", - "contactUs": "Contact Us", - "documentation": "Documentation", - "website": "Official Website", - "expand": "Expand", - "collapse": "Collapse", - "userManagement": "User Management", - "apikeyManagement": "API Key Management", - "securitySettings": "Security Settings", - "auditLog": "Audit Center", - "logout": "Log Out" - }, - "auth": { - "permissionError": "Permission Error", - "authenticationError": "Authentication Error", - "noPermission": "You do not have permissions to do this!", - "invalidCredentials": "Invalid credentials! Please login.", - "confirmed": "CONFIRMED" - }, - "model": { - "languageModels": "Language Models", - "embeddingModels": "Embedding Models", - "rerankModels": "Rerank Models", - "imageModels": "Image Models", - "audioModels": "Audio Models", - "videoModels": "Video Models", - "customModels": "Custom Models", - "flexibleModels": "Flexible Models" - }, - "launchModel": { - "modelAbility": "Model Ability", - "generate": "Text Generation", - "chat": "Conversation", - "vision": "Vision", - "reasoning": "Reasoning", - "tools": "Tool Use", - "audio": "Audio Processing", - "omni": "Multimodal (Omni)", - "hybrid": "Hybrid Capability", - "text2image": "Text to Image", - "image2image": "Image to Image", - "inpainting": "Image Inpainting", - "ocr": "Optical Character Recognition (OCR)", - "audio2text": "Audio to Text", - "text2audio": "Text to Audio", - "text2audio_zero_shot": "Text to Audio (Zero-Shot)", - "text2audio_voice_cloning": "Text to Audio (Voice Cloning)", - "text2audio_emotion_control": "Text to Audio (Emotion Control)", - "text2video": "Text to Video", - "image2video": "Image to Video", - "firstlastframe2video": "First & Last Frame to Video", - "status": "Status", - "cached": "Cached", - "manageCachedModels": "Manage Cached Models", - "manageVirtualEnvironments": "Manage Virtual Environments", - "favorite": "Favorite", - "unfavorite": "Unfavorite", - "search": "Search for model name and description", - "searchModelType": "Search for {{modelType}} model name", - "searchInstruction": "Type {{hotkey}} to search", - "clickToLaunchModel": "Click with mouse to launch the model", - "dimensions": "dimensions", - "maxTokens": "max tokens", - "edit": "Edit", - "delete": "Delete", - "contextLength": "context length", - "chatModel": "chat model", - "generateModel": "generate model", - "otherModel": "other model", - "confirmDeleteCustomModel": "Are you sure to delete this custom model? This behavior is irreversible.", - "modelName": "Model Name", - "envPath": "Environment Path", - "realPath": "Real Path", - "copyEnvPath": "Copy environment path", - "viewPackages": "View Packages", - "installedPackages": "Installed Packages", - "packageName": "Package Name", - "version": "Version", - "location": "Location", - "packagesCount": "Packages Count", - "size": "Size", - "pythonVersion": "Python Version", - "createdAt": "Created At", - "noVirtualEnvironmentsForNow": "No virtual environments for now!", - "noPackagesInstalled": "No packages installed", - "lastConfig": "Last Config", - "configCache": "Config Cache", - "newCache": "New Cache", - "noConfigCache": "No config cache for now!", - "loadCache": "Use", - "deleteCache": "Delete Cache", - "lastUpdated": "Last Updated", - "createdBy": "Created By", - "defaultConfig": "Default Config", - "confirmDeleteConfigCache": "Delete this cached configuration? This action is irreversible.", - "invalidConfigCache": "The model engine required by this cached configuration is unavailable.", - "commandLineParsing": "Command Line Argument Parsing", - "copyToCommandLine": "Copy as Command Line Command", - "modelEngine": "Model Engine", - "modelFormat": "Model Format", - "modelSize": "Model Size", - "quantization": "Quantization", - "multimodelProjector": "Multimodel Projector", - "nGPU": "GPU Count per Replica", - "nGPUPerWorker": "GPU Count per Worker", - "nGpuLayers": "N GPU Layers", - "replica": "Replica", - "optionalConfigurations": "Optional Configurations", - "modelUID.optional": "(Optional) Model UID, model name by default", - "requestLimits.optional": "(Optional) Request Limits, the number of request limits for this model, default is None", - "workerIp.optional": "(Optional) Worker Ip, select one or more worker nodes in a distributed scenario", - "workerIp": "Worker Ip, specify the worker ip where the model is located in a distributed scenario", - "loadingWorkerNodes": "Loading worker nodes...", - "workerNodesLoadFailed": "Failed to load worker nodes.", - "noWorkerNodesAvailable": "No worker nodes are currently available.", - "noAvailableGpuWorkers": "No GPU-capable worker nodes are available for the current device selection.", - "workerNodesUnavailableForValidation": "Worker node data is unavailable. Please wait for the worker list to load or clear the worker selection.", - "invalidWorkerSelection": "Selected worker nodes are invalid for the current device selection.", - "gpuIdxNotAllowedForCpu": "GPU Idx must be empty when the device is CPU.", - "gpuIdxMustMatchReplica": "The number of GPU indexes must be a multiple of replica.", - "fixFieldErrorsBeforeLaunch": "Please fix the highlighted field errors before deployment.", - "workerCount.optional": "(Optional) Worker Count", - "GPUIdx.optional": "(Optional) GPU Idx, Specify the GPU index where the model is located", - "GPUIdx": "GPU Idx, Specify the GPU index where the model is located", - "downloadHub.optional": "(Optional) Download_hub", - "modelPath.optional": "(Optional) Model Path, For PyTorch, provide the model directory. For GGML/GGUF, provide the model file path.", - "GGUFQuantization.optional": "(Optional) GGUF quantization format, quantizing the Transformer part.", - "GGUFModelPath.optional": "(Optional) GGUF model path, should be a file ending with .gguf.", - "lightningVersions.optional": "(Optional) Lightning Versions", - "lightningModelPath.optional": "(Optional) Lightning Model Path", - "enableThinking": "Enable Thinking", - "parsingReasoningContent": "Parsing Reasoning Content", - "CPUOffload": "CPU Offload", - "CPUOffload.tip": "Unload the model to the CPU. Recommend to enable this when resources are limited or when using the GGUF option.", - "loraConfig": "Lora Config", - "loraModelConfig": "Lora Model Config", - "virtualEnvConfig": "Virtual Environments Config", - "modelVirtualEnv": "Model Virtual Environments", - "virtualEnvPackage": "Virtual Environment Packages", - "envVariable": "Environment Variables", - "envVariableConfig": "Environment Variable Config", - "additionalQuantizationParametersForInferenceEngine": "Additional quantization parameters passed to the inference engine", - "additionalParametersForInferenceEngine": "Additional parameters passed to the inference engine", - "enterIntegerGreaterThanZero": "Please enter an integer greater than 0.", - "enterCommaSeparatedNumbers": "Please enter numeric data separated by commas, for example: 0,1,2", - "device": "Device", - "loraLoadKwargsForImageModel": "Lora Load Kwargs for Image Model", - "loraFuseKwargsForImageModel": "Lora Fuse Kwargs for Image Model", - "launch": "Launch", - "launchCompletedWithAutostart": "Model deployment completed and added to autostart", - "autostartSaveFailed": "Model launched, but failed to save autostart config", - "saveAutostart": "Autostart after successful launch", - "goBack": "Go Back", - "copyJson": "Copy Json", - "cancel": "Cancel", - "confirm": "Confirm", - "placeholderTip": "Please enter", - "fillCompleteParametersBeforeAdding": "Please fill in the complete parameters before adding!", - "model_format": "model_format", - "model_size_in_billions": "model_size_in_billions", - "quantizations": "quantizations", - "real_path": "real_path", - "path": "path", - "ipAddress": "IP Address", - "operation": "operation", - "copyRealPath": "Copy real_path", - "copyPath": "Copy path", - "noCacheForNow": "No cache for now!", - "confirmDeleteCacheFiles": "Confirm deletion of cache files? This action is irreversible.", - "confirmDeleteVirtualEnv": "Confirm deletion of virtual environment? This action is irreversible.", - "commandLineTip": "Please confirm whether the model names are consistent.", - "featured": "featured", - "all": "all", - "cancelledSuccessfully": "Cancelled Successfully!", - "mustBeUnique": "{{key}} must be unique", - "update": "Update", - "launchProgress": "Launch Progress", - "initializing": "Initializing...", - "moreDetails": "More Details" - }, - "modelReplicaDetails": { - "title": "Model Replica Details", - "modelUid": "Model UID", - "replicaId": "Replica ID", - "workerAddress": "Worker Address", - "status": "Status", - "createdTime": "Created Time", - "actions": "Actions", - "noReplicaInfo": "No replica information available", - "errors": "Errors", - "replica": "Replica", - "remove": "Remove", - "removeConfirm": "Remove replica {{replicaId}} from model {{modelUid}}?", - "close": "Close" - }, - "runningModels": { - "name": "Name", - "address": "Address", - "gpuIndexes": "GPU Indexes", - "size": "Size", - "quantization": "Quantization", - "replica": "Replica", - "actions": "Actions", - "noRunningModels": "No Running Models", - "noRunningModelsMatches": "No Running Models Matches", - "copy": "Copy", - "copied": "Copied!", - "copyFailed": "Copy failed", - "viewDetails": "View Details", - "autostartEnabled": "Autostart configured", - "removeAutostartSuccess": "Removed autostart for {{modelUid}}", - "removeAutostartFailed": "Failed to remove autostart", - "terminateModel": "Terminate model", - "terminateInProgress": "Terminating…", - "terminateConfirmTitle": "Terminate this model?", - "terminateConfirmBody": "This model has {{replica}} replica(s). Termination can take several minutes when the cluster is busy or when multiple replicas exist; total time is bounded by the slowest worker. Do not click terminate repeatedly.", - "terminateConfirmOk": "Terminate", - "terminateErrorHint": "The request failed or the model may already be removed. Refresh the running models list to confirm." - }, - "registerModel": { - "modelName": "Model Name", - "modelDescription": "Model Description (Optional)", - "contextLength": "Context Length", - "dimensions": "Dimensions", - "maxTokens": "Max Tokens", - "modelPath": "Model Path", - "modelLanguages": "Model Languages", - "languages": "Languages", - "multilingual": "Multilingual", - "modelAbilities": "Model Abilities", - "modelFamily": "Model Family", - "chatTemplate": "Chat Template", - "test": "test", - "testResult": "test result", - "noTestResults": "No test results...", - "stopTokenIds": "Stop Token Ids", - "stop": "Stop", - "reasoningStartTag": "Reasoning Start Tag", - "reasoningEndTag": "Reasoning End Tag", - "toolParser": "Tool Parser", - "launcher": "Launcher", - "launcherArguments": "Launcher Arguments (Optional)", - "edit": "Edit", - "cancel": "Cancel", - "registerModel": "Register Model", - "messagesExample": "Messages Example", - "JSONFormat": "JSON Format", - "modelSpecs": "Model Specs", - "modelSizeBillions": "Model Size in Billions", - "quantization": "Quantization", - "quantizationOptional": "Quantization (Optional)", - "delete": "Delete", - "controlnet": "Controlnet", - "packages": "Packages in Virtual Env", - "more": "more", - "modelFormat": "Model Format", - "enterNumberGreaterThanZero": "Please enter a number greater than 0.", - "carefulQuantizationForModelRegistration": "For GPTQ/AWQ/FP8/MLX models, please be careful to fill in the quantization corresponding to the model you want to register.", - "quantizationCannotBeEmpty": "Quantization cannot be left empty.", - "enterInteger": "Please enter an integer.", - "enterIntegerGreaterThanZero": "Please enter an integer greater than 0.", - "showCustomJsonConfig": "Show custom json config used by api", - "packUp": "Pack up", - "unfold": "Unfold", - "copyAll": "Copy all", - "alphanumericWithHyphensUnderscores": "Alphanumeric characters with properly placed hyphens and underscores. Must not match any built-in model names.", - "chooseBuiltInOrCustomModel": "You can choose from the built-in models or input your own.", - "chooseOnlyBuiltInModel": "You can only choose from the built-in models.", - "provideModelDirectoryPath": "Provide the model directory path.", - "provideModelLauncher": "Provide the model launcher.", - "jsonArgumentsForLauncher": "A JSON-formatted dictionary representing the arguments passed to the Launcher.", - "provideModelDirectoryOrFilePath": "For PyTorch, provide the model directory. For GGUF, provide the model file path.", - "ensureChatTemplatePassesTest": "Please make sure this chat_template passes the test by clicking the TEST button on the right. Please note that this test may not cover all cases and will only be used for the most basic case.", - "testFailurePreventsChatWorking": "Please note that failure to pass test may prevent chats from working properly.", - "stopControlForChatModels": "int type, used to control the stopping of chat models", - "stopControlStringForChatModels": "string type, used to control the stopping of chat models", - "enterJsonFormattedDictionary": "Please enter the JSON-formatted dictionary.", - "autoFill": "Auto Fill", - "fillInModelPathFirst": "Please fill in modelPath first", - "fillInModelFamilyFirst": "Please select model family first" - }, - "clusterInfo": { - "supervisor": "Supervisor", - "workers": "Workers", - "workerDetails": "Worker Details", - "count": "Count", - "cpuInfo": "CPU Info", - "usage": "Usage:", - "total": "Total", - "cpuMemoryInfo": "CPU Memory Info", - "version": "Version", - "release": "Release:", - "commit": "Commit:", - "gpuInfo": "GPU Info", - "gpuMemoryInfo": "GPU Memory Info", - "address": "Address", - "item": "Item", - "value": "Value", - "nodeType": "Node Type", - "cpuUsage": "CPU Usage", - "cpuTotal": "CPU Total", - "memUsage": "Mem Usage", - "memTotal": "Mem Total", - "gpuCount": "GPU Count", - "gpuLoad": "GPU Load", - "gpuMemUsage": "GPU Mem Usage", - "gpuMemTotal": "GPU Mem Total", - "worker": "Worker" - }, - "components": { - "suggestsCommonParameters": "Suggests common parameters; others allowed.", - "warning": "Warning", - "ok": "OK", - "cancel": "Cancel" - }, - "monitoring": { - "notConfigured": "Monitoring not configured.", - "time": { - "5m": "Last 5 minutes", - "15m": "Last 15 minutes", - "30m": "Last 30 minutes", - "1h": "Last 1 hour", - "3h": "Last 3 hours", - "6h": "Last 6 hours", - "12h": "Last 12 hours", - "24h": "Last 24 hours", - "7d": "Last 7 days", - "2d": "Last 2 days" - }, - "refresh": { - "off": "Off", - "10s": "10s", - "30s": "30s", - "1m": "1m", - "5m": "5m" - }, - "absoluteRange": "Absolute time range", - "from": "From", - "to": "To", - "applyTimeRange": "Apply time range", - "manualRefresh": "Refresh dashboard", - "tab": { - "overview": "Overview", - "modelLoad": "Model Load", - "llmSlo": "LLM SLO", - "gpu": "GPU", - "host": "Host", - "security": "Security" - }, - "config": { - "title": "Monitor Configuration", - "grafanaUrl": "Grafana URL", - "datasource": "Datasource Name", - "alertDatasource": "Alert Datasource Name", - "alertDatasourceHint": "Leave empty to use datasource", - "clusterName": "Cluster Name", - "dashboardUid": "Dashboard UIDs", - "dashboardOverview": "Overview", - "dashboardModelLoad": "Model Load", - "dashboardLlmSlo": "LLM SLO", - "dashboardGpu": "GPU Resources", - "dashboardHost": "Host Resources", - "dashboardSecurity": "Security Audit", - "save": "Save", - "saving": "Saving...", - "cancel": "Cancel", - "reset": "Reset to Default", - "openConfig": "Open Configuration", - "sourceDb": "Database", - "sourceEnv": "Environment", - "sourceDefault": "Default", - "healthCheckFailed": "Grafana health check failed", - "saved": "Configuration saved", - "saveFailed": "Failed to save configuration", - "loadFailed": "Failed to load configuration", - "resetDone": "Configuration reset to defaults", - "checking": "Checking..." - }, - "configHint": "Click the settings button above or the button below to configure Grafana." - }, - "logs": { - "notConfigured": "Log query not configured. Please set XINFERENCE_ES_URL environment variable.", - "searchPlaceholder": "Search logs...", - "allNodes": "All Nodes", - "logLevel": "Log Level", - "nodeType": "Node Type", - "time": "Time", - "level": "Level", - "node": "Node", - "message": "Message", - "fullMessage": "Full Message", - "noLogs": "No logs found", - "refresh": "Refresh", - "totalHits": "Total: {{count}}", - "prevPage": "Previous", - "nextPage": "Next", - "detail": { - "module": "Module", - "pid": "PID", - "request_id": "Request ID", - "address": "Address", - "log_type": "Log Type", - "rtf_avg": "RTF Average", - "time_speech": "Speech Time", - "time_escape": "Process Time", - "tableTab": "Table", - "jsonTab": "JSON", - "action": "Action", - "field": "Field", - "value": "Value", - "filterFor": "Filter for value", - "filterOut": "Filter out value", - "copyJson": "Copy JSON", - "copied": "Copied!", - "viewContext": "View surrounding documents", - "contextTitle": "Surrounding documents", - "loadNewer": "Load", - "loadOlder": "Load", - "newerDocs": "newer documents", - "olderDocs": "older documents", - "anchorRow": "Current document", - "contextError": "This feature requires a newer backend version.", - "contextFetchError": "Failed to load surrounding documents." - } - }, - "userManagement": { - "title": "User Management", - "createUser": "Create User", - "id": "ID", - "username": "Username", - "source": "Source", - "status": "Status", - "permissions": "Permissions", - "actions": "Actions", - "active": "Active", - "disabled": "Disabled", - "dialogTitle": "Create User", - "usernameLabel": "Username", - "passwordLabel": "Password", - "permissionsLabel": "Permissions (comma-separated)", - "permissionsHelperText": "e.g. models:list, models:read, keys:create", - "cancel": "Cancel", - "create": "Create", - "confirmDelete": "Delete user", - "selectAll": "Select All", - "editPermissions": "Edit Permissions", - "editPermissionsTitle": "Edit Permissions", - "save": "Save", - "changePassword": "Change Password", - "changePasswordTitle": "Change Password", - "newPassword": "New Password", - "confirmPassword": "Confirm Password", - "passwordMismatch": "Passwords do not match", - "passwordTooShort": "Password must be at least 8 characters", - "changePasswordSuccess": "Password changed successfully" - }, - "permissions": { - "admin": "Administrator", - "models_list": "List Models", - "models_read": "Read Models", - "models_write": "Write Models", - "keys_create": "Create API Keys", - "keys_manage": "Manage API Keys", - "users_manage": "Manage Users", - "cache_list": "List Cache", - "cache_delete": "Delete Cache", - "virtualenv_list": "List Virtualenv", - "virtualenv_delete": "Delete Virtualenv", - "models_register": "Register / Unregister Models", - "logs_list": "View Logs", - "monitor_view": "View Monitoring" - }, - "apikeyManagement": { - "title": "API Key Management", - "createKey": "Create Key", - "id": "ID", - "name": "Name", - "prefix": "Prefix", - "status": "Status", - "expires": "Expires", - "modelPermissions": "Model Permissions", - "actions": "Actions", - "active": "Active", - "disabled": "Disabled", - "revealTooltip": "Reveal key", - "disableTooltip": "Disable", - "enableTooltip": "Enable", - "deleteTooltip": "Delete", - "keyCreatedTitle": "Key Created", - "createKeyTitle": "Create API Key", - "saveKeyWarning": "Save this key now. You won't be able to see it again.", - "nameLabel": "Name (optional)", - "ownerLabel": "Owner", - "ownerHelperText": "Leave empty to assign to current user", - "owner": "Owner", - "expiresLabel": "Expiration date (optional)", - "expiresHelperText": "Leave empty for no expiration", - "permissionType": "Permission type", - "allModels": "All models", - "byModelType": "By model type", - "byModelId": "By model ID", - "permissionValues": "Permission values (comma-separated)", - "modelTypeHelper": "e.g. LLM, embedding, rerank", - "modelIdHelper": "e.g. qwen2-72b, bge-m3", - "close": "Close", - "cancel": "Cancel", - "create": "Create", - "save": "Save", - "revealTitle": "API Key", - "confirmDelete": "Delete API key", - "copy": "Copy", - "copied": "Copied to clipboard", - "editPermTooltip": "Edit permissions", - "editPermTitle": "Edit Model Permissions —", - "editKeyTitle": "Edit API Key —", - "mixedMode": "By type + By instance (mixed)", - "modelInstances": "Model instances", - "permissionsSaved": "Permissions saved", - "bans": "Bans", - "description": "Description", - "descriptionLabel": "Description (optional)", - "bannedIpsForKey": "Banned IPs for Key #{{keyId}}", - "noActiveBans": "No active bans", - "remaining": "Remaining: {{seconds}}s", - "unban": "Unban", - "viewBans": "View", - "failedLoadBans": "Failed to load bans", - "failedUnban": "Failed to unban" - }, - "securitySettings": { - "title": "Security Settings", - "rateLimitConfig": "Rate Limit Configuration", - "ipLayer": "IP Layer", - "keyLayer": "Key Layer (Default)", - "maxFailures": "Max Failures", - "windowSeconds": "Window (seconds)", - "banSeconds": "Ban Duration (seconds)", - "saveConfig": "Save Configuration", - "bannedIps": "Banned IPs", - "bannedIpsDesc": "IPs automatically banned after exceeding max failures with non-existent keys or invalid tokens within the time window. All requests from the banned IP are rejected during the ban period (duration configured in IP layer)", - "noBannedIps": "No banned IPs", - "bannedKeys": "Banned (IP, Key) Pairs", - "bannedKeysDesc": "IP + Key pairs automatically banned after exceeding max failures with expired or disabled keys within the time window. Only this specific IP + Key combination is rejected; other keys from the same IP are unaffected (duration configured in Key layer)", - "noBannedKeys": "No banned key pairs", - "ip": "IP", - "keyId": "Key ID", - "remaining": "Remaining (s)", - "action": "Action", - "unbanAll": "Unban All" - }, - "auditLog": { - "title": "Audit Center", - "time": "Time", - "user": "User", - "apiKey": "API Key", - "model": "Model", - "type": "Type", - "status": "Status", - "clientIp": "Client IP", - "modelId": "Model ID", - "modelName": "Model Name", - "endpoint": "Endpoint", - "latency": "Latency (ms)", - "timeFrom": "From", - "timeTo": "To", - "search": "Search", - "noData": "No audit records", - "custom": "Custom", - "totalRecords": "{{count}} records", - "prevPage": "Prev", - "nextPage": "Next", - "tableTab": "Table", - "jsonTab": "JSON", - "detailField": "Field", - "detailValue": "Value", - "copyJson": "Copy JSON", - "copied": "Copied!", - "modelType": "Model Type", - "category": "Category", - "category_inference": "Inference", - "category_admin": "Admin", - "category_auth": "Auth" - }, - "login": { - "or": "OR", - "sso": "LOGIN WITH SSO" - } -} diff --git a/xinference/ui/web/ui/src/locales/ja.json b/xinference/ui/web/ui/src/locales/ja.json deleted file mode 100644 index 1fb4a69fca..0000000000 --- a/xinference/ui/web/ui/src/locales/ja.json +++ /dev/null @@ -1,587 +0,0 @@ -{ - "menu": { - "launchModel": "モデル起動", - "runningModels": "実行中のモデル", - "registerModel": "モデル登録", - "clusterInfo": "クラスター情報", - "monitoring": "モニタリング", - "logs": "ログセンター", - "xagent": "XagentでAIエージェントを構築", - "contactUs": "お問い合わせ", - "documentation": "ドキュメント", - "website": "公式サイト", - "expand": "展開", - "collapse": "折りたたむ", - "logout": "ログアウト", - "userManagement": "ユーザー管理", - "apikeyManagement": "API Key 管理", - "securitySettings": "セキュリティ設定", - "auditLog": "監査センター" - }, - "model": { - "languageModels": "言語モデル", - "embeddingModels": "埋め込みモデル", - "rerankModels": "再ランクモデル", - "imageModels": "画像モデル", - "audioModels": "音声モデル", - "videoModels": "動画モデル", - "customModels": "カスタムモデル", - "flexibleModels": "フレキシブルモデル" - }, - "launchModel": { - "modelAbility": "モデル機能", - "generate": "テキスト生成", - "chat": "会話", - "vision": "視覚", - "reasoning": "推論", - "tools": "ツール使用", - "audio": "音声処理", - "omni": "マルチモーダル (Omni)", - "hybrid": "ハイブリッド機能", - "text2image": "テキストから画像", - "image2image": "画像から画像", - "inpainting": "画像修復", - "ocr": "光学文字認識 (OCR)", - "audio2text": "音声からテキスト", - "text2audio": "テキストから音声", - "text2audio_zero_shot": "テキストから音声 (ゼロショット)", - "text2audio_voice_cloning": "テキストから音声 (声のクローン)", - "text2audio_emotion_control": "テキストから音声(感情制御)", - "text2video": "テキストから動画", - "image2video": "画像から動画", - "firstlastframe2video": "最初と最後のフレームから動画", - "status": "ステータス", - "cached": "キャッシュ済み", - "manageCachedModels": "キャッシュモデル管理", - "manageVirtualEnvironments": "仮想環境を管理", - "favorite": "お気に入り", - "unfavorite": "お気に入り解除", - "search": "モデル名と説明を検索", - "searchModelType": "{{modelType}}モデル名を検索", - "searchInstruction": "{{hotkey}}で検索", - "clickToLaunchModel": "マウスクリックでモデルを起動", - "dimensions": "次元", - "maxTokens": "最大トークン数", - "edit": "編集", - "delete": "削除", - "contextLength": "コンテキスト長", - "chatModel": "チャットモデル", - "generateModel": "生成モデル", - "otherModel": "その他モデル", - "confirmDeleteCustomModel": "このカスタムモデルを削除しますか?この操作は元に戻せません。", - "modelName": "모델 이름", - "envPath": "환경 경로", - "realPath": "실제 경로", - "copyEnvPath": "환경 경로 복사", - "viewPackages": "패키지 목록 보기", - "installedPackages": "설치된 패키지", - "packageName": "패키지 이름", - "version": "버전", - "location": "위치", - "packagesCount": "패키지 수", - "size": "크기", - "pythonVersion": "Python 버전", - "createdAt": "생성 시간", - "noVirtualEnvironmentsForNow": "현재 가상환경이 없습니다!", - "noPackagesInstalled": "설치된 패키지가 없습니다", - "lastConfig": "最終設定", - "configCache": "設定キャッシュ", - "newCache": "新規キャッシュ", - "noConfigCache": "設定キャッシュはありません。", - "loadCache": "使用する", - "deleteCache": "キャッシュを削除", - "lastUpdated": "最終更新", - "createdBy": "作成者", - "defaultConfig": "デフォルト設定", - "confirmDeleteConfigCache": "この設定キャッシュを削除しますか?この操作は元に戻せません。", - "invalidConfigCache": "この設定キャッシュに必要なモデルエンジンは現在利用できません。", - "commandLineParsing": "コマンドライン引数解析", - "copyToCommandLine": "コマンドラインコマンドとしてコピー", - "modelEngine": "モデルエンジン", - "modelFormat": "モデルフォーマット", - "modelSize": "モデルサイズ", - "quantization": "量子化", - "multimodelProjector": "マルチモデルプロジェクター", - "nGPU": "レプリカあたりのGPU数", - "nGPUPerWorker": "ワーカーあたりのGPU数", - "nGpuLayers": "GPUレイヤー数", - "replica": "レプリカ", - "optionalConfigurations": "オプション設定", - "modelUID.optional": "(オプション) モデルUID、デフォルトはモデル名", - "requestLimits.optional": "(オプション) リクエスト制限、このモデルのリクエスト制限数、デフォルトは無制限", - "workerIp.optional": "(任意)ワーカー IP。分散構成では 1 つ以上のワーカーノードを選択できます", - "workerIp": "ワーカーIP、分散シナリオでモデルが配置されているワーカーIPを指定", - "loadingWorkerNodes": "ワーカーノードを読み込み中...", - "workerNodesLoadFailed": "ワーカーノードの読み込みに失敗しました。", - "noWorkerNodesAvailable": "現在利用可能なワーカーノードはありません。", - "noAvailableGpuWorkers": "現在のデバイス選択で利用可能な GPU 対応ワーカーノードはありません。", - "workerNodesUnavailableForValidation": "ワーカーノードの情報を利用できません。ワーカー一覧の読み込み完了を待つか、ワーカーの選択を解除してください。", - "invalidWorkerSelection": "選択されたワーカーノードは現在のデバイス選択では無効です。", - "gpuIdxNotAllowedForCpu": "デバイスが CPU の場合、GPU インデックスは空である必要があります。", - "gpuIdxMustMatchReplica": "GPU インデックスの数はレプリカ数の倍数である必要があります。", - "fixFieldErrorsBeforeLaunch": "デプロイ前にハイライトされた入力エラーを修正してください。", - "workerCount.optional": "(オプション) ワーカー数", - "GPUIdx.optional": "(オプション) GPUインデックス、モデルが配置されているGPUインデックスを指定", - "GPUIdx": "GPUインデックス、モデルが配置されているGPUインデックスを指定", - "downloadHub.optional": "(オプション) ダウンロードハブ", - "modelPath.optional": "(オプション) モデルパス、PyTorchの場合はモデルディレクトリ、GGML/GGUFの場合はモデルファイルパスを指定", - "GGUFQuantization.optional": "(オプション) GGUF量子化フォーマット、Transformer部分を量子化", - "GGUFModelPath.optional": "(オプション) GGUFモデルパス、.ggufで終わるファイルを指定", - "lightningVersions.optional": "(オプション) 軽量化バージョン", - "lightningModelPath.optional": "(オプション) 軽量化LoRAモデルパス", - "enableThinking": "思考を有効化", - "parsingReasoningContent": "推論内容の解析", - "CPUOffload": "CPUオフロード", - "CPUOffload.tip": "モデルをCPUにアンロードします。リソースが限られている場合やGGUFオプションを使用する場合に推奨されます。", - "loraConfig": "Lora設定", - "loraModelConfig": "Loraモデル設定", - "virtualEnvConfig": "仮想環境の設定", - "modelVirtualEnv": "モデルの仮想環境", - "virtualEnvPackage": "仮想環境パッケージ", - "envVariable": "環境変数", - "envVariableConfig": "環境変数の設定", - "additionalQuantizationParametersForInferenceEngine": "推論エンジンに渡される追加の量子化パラメータ", - "additionalParametersForInferenceEngine": "推論エンジンに渡される追加のパラメータ", - "enterIntegerGreaterThanZero": "0より大きい整数を入力してください。", - "enterCommaSeparatedNumbers": "カンマ区切りの数値を入力してください。例: 0,1,2", - "device": "デバイス", - "loraLoadKwargsForImageModel": "画像モデルのLora読み込み引数", - "loraFuseKwargsForImageModel": "画像モデルのLora融合引数", - "launch": "起動", - "launchCompletedWithAutostart": "モデルのデプロイが完了し、自動起動に追加されました", - "autostartSaveFailed": "モデルは起動しましたが、自動起動設定の保存に失敗しました", - "saveAutostart": "起動成功後に自動起動へ追加", - "goBack": "戻る", - "copyJson": "Jsonをコピー", - "cancel": "キャンセル", - "confirm": "確認", - "placeholderTip": "入力してください", - "fillCompleteParametersBeforeAdding": "追加前に完全なパラメータを入力してください!", - "model_format": "モデルフォーマット", - "model_size_in_billions": "モデルサイズ(億単位)", - "quantizations": "量子化", - "real_path": "実際のパス", - "path": "パス", - "ipAddress": "IPアドレス", - "operation": "操作", - "copyRealPath": "実際のパスをコピー", - "copyPath": "パスをコピー", - "noCacheForNow": "現在キャッシュはありません!", - "confirmDeleteCacheFiles": "キャッシュファイルを削除しますか?この操作は元に戻せません。", - "confirmDeleteVirtualEnv": "仮想環境を削除しますか?この操作は元に戻せません。", - "commandLineTip": "モデル名が一致しているか確認してください。", - "featured": "おすすめとお気に入り", - "all": "すべて", - "cancelledSuccessfully": "正常にキャンセルされました!", - "mustBeUnique": "{{key}} は一意でなければなりません", - "update": "更新", - "launchProgress": "起動状況", - "initializing": "初期化中...", - "moreDetails": "詳細を見る" - }, - "modelReplicaDetails": { - "title": "モデルレプリカの詳細", - "modelUid": "モデル UID", - "replicaId": "レプリカ ID", - "workerAddress": "ワーカーアドレス", - "status": "ステータス", - "createdTime": "作成日時", - "actions": "操作", - "noReplicaInfo": "レプリカ情報はありません", - "errors": "エラー", - "replica": "レプリカ", - "remove": "削除", - "removeConfirm": "モデル {{modelUid}} のレプリカ {{replicaId}} を削除しますか?", - "close": "閉じる" - }, - "runningModels": { - "name": "名前", - "address": "アドレス", - "gpuIndexes": "GPUインデックス", - "size": "サイズ", - "quantization": "量子化", - "replica": "レプリカ", - "actions": "操作", - "noRunningModels": "実行中のモデルはありません", - "noRunningModelsMatches": "一致する実行中のモデルはありません", - "copy": "コピー", - "copied": "コピーしました!", - "copyFailed": "コピーに失敗しました", - "viewDetails": "詳細を表示", - "autostartEnabled": "自動起動が設定されています", - "removeAutostartSuccess": "{{modelUid}} の自動起動を削除しました", - "removeAutostartFailed": "自動起動の削除に失敗しました", - "terminateModel": "モデルを終了", - "terminateInProgress": "終了処理中…", - "terminateConfirmTitle": "このモデルを終了しますか?", - "terminateConfirmBody": "このモデルには {{replica}} 個のレプリカがあります。クラスターが混雑している場合やレプリカが多い場合、終了に数分かかることがあります。所要時間は最も遅いワーカーに依存します。終了を繰り返しクリックしないでください。", - "terminateConfirmOk": "終了", - "terminateErrorHint": "リクエストが失敗したか、モデルが既に削除されている可能性があります。実行中のモデル一覧を更新して確認してください。" - }, - "registerModel": { - "modelName": "モデル名", - "modelDescription": "モデル説明(オプション)", - "contextLength": "コンテキスト長", - "dimensions": "次元", - "maxTokens": "最大トークン数", - "modelPath": "モデルパス", - "modelLanguages": "モデル言語", - "languages": "言語", - "multilingual": "多言語", - "modelAbilities": "モデル機能", - "modelFamily": "モデルファミリー", - "chatTemplate": "チャットテンプレート", - "test": "テスト", - "testResult": "テスト結果", - "noTestResults": "テスト結果がありません...", - "stopTokenIds": "停止トークンID", - "stop": "停止", - "reasoningStartTag": "推論開始タグ", - "reasoningEndTag": "推論終了タグ", - "toolParser": "ツールパーサー", - "launcher": "ランチャー", - "launcherArguments": "ランチャー引数(オプション)", - "edit": "編集", - "cancel": "キャンセル", - "registerModel": "モデル登録", - "messagesExample": "メッセージ例", - "JSONFormat": "JSONフォーマット", - "modelSpecs": "モデル仕様", - "modelSizeBillions": "モデルサイズ(億単位)", - "quantization": "量子化", - "quantizationOptional": "量子化(オプション)", - "delete": "削除", - "controlnet": "Controlnet", - "packages": "仮想環境パッケージ", - "more": "詳細", - "modelFormat": "モデルフォーマット", - "enterNumberGreaterThanZero": "0より大きい数値を入力してください。", - "carefulQuantizationForModelRegistration": "GPTQ/AWQ/FP8/MLXモデルの場合、登録するモデルに対応する量子化を慎重に入力してください。", - "quantizationCannotBeEmpty": "量子化は空にできません。", - "enterInteger": "整数を入力してください。", - "enterIntegerGreaterThanZero": "0より大きい整数を入力してください。", - "showCustomJsonConfig": "APIで使用されるカスタムjson設定を表示", - "packUp": "折りたたむ", - "unfold": "展開", - "copyAll": "すべてコピー", - "alphanumericWithHyphensUnderscores": "ハイフンとアンダースコアを適切に配置した英数字。組み込みモデル名と一致してはいけません。", - "chooseBuiltInOrCustomModel": "組み込みモデルから選択するか、独自のモデルを入力できます。", - "chooseOnlyBuiltInModel": "組み込みモデルのみから選択できます。", - "provideModelDirectoryPath": "モデルディレクトリパスを指定してください。", - "provideModelLauncher": "モデルランチャーを指定してください。", - "jsonArgumentsForLauncher": "ランチャーに渡される引数を表すJSON形式の辞書。", - "provideModelDirectoryOrFilePath": "PyTorchの場合はモデルディレクトリ、GGUFの場合はモデルファイルパスを指定してください。", - "ensureChatTemplatePassesTest": "右側のTESTボタンをクリックして、このchat_templateがテストに合格することを確認してください。このテストはすべてのケースをカバーするわけではなく、最も基本的なケースにのみ使用されます。", - "testFailurePreventsChatWorking": "テストに合格しないと、チャットが正常に動作しない可能性があることに注意してください。", - "stopControlForChatModels": "int型、チャットモデルの停止を制御するために使用", - "stopControlStringForChatModels": "string型、チャットモデルの停止を制御するために使用", - "enterJsonFormattedDictionary": "JSON形式の辞書を入力してください。", - "autoFill": "自動入力", - "fillInModelPathFirst": "まずモデルパスを入力してください", - "fillInModelFamilyFirst": "まずモデルファミリーを選択してください" - }, - "clusterInfo": { - "supervisor": "スーパーバイザー", - "workers": "ワーカー", - "workerDetails": "ワーカー詳細", - "count": "数", - "cpuInfo": "CPU情報", - "usage": "使用率:", - "total": "合計", - "cpuMemoryInfo": "CPUメモリ情報", - "version": "バージョン", - "release": "リリース:", - "commit": "コミット:", - "gpuInfo": "GPU情報", - "gpuMemoryInfo": "GPUメモリ情報", - "address": "アドレス", - "item": "項目", - "value": "値", - "nodeType": "ノードタイプ", - "cpuUsage": "CPU使用率", - "cpuTotal": "CPU合計", - "memUsage": "メモリ使用量", - "memTotal": "メモリ合計", - "gpuCount": "GPU数", - "gpuLoad": "GPU負荷", - "gpuMemUsage": "GPUメモリ使用量", - "gpuMemTotal": "GPUメモリ合計", - "worker": "ワーカー" - }, - "components": { - "suggestsCommonParameters": "一般的なパラメータを提案します。他のパラメータも使用可能です。", - "warning": "警告", - "ok": "確認", - "cancel": "キャンセル" - }, - "monitoring": { - "notConfigured": "モニタリングが設定されていません。", - "time": { - "5m": "過去 5 分", - "15m": "過去 15 分", - "30m": "過去 30 分", - "1h": "過去 1 時間", - "3h": "過去 3 時間", - "6h": "過去 6 時間", - "12h": "過去 12 時間", - "24h": "過去 24 時間", - "7d": "過去 7 日間", - "2d": "過去2日間" - }, - "refresh": { - "off": "オフ", - "10s": "10秒", - "30s": "30秒", - "1m": "1分", - "5m": "5分" - }, - "absoluteRange": "絶対時間範囲", - "from": "開始", - "to": "終了", - "applyTimeRange": "時間範囲を適用", - "manualRefresh": "ダッシュボードを更新", - "tab": { - "overview": "概要", - "modelLoad": "モデル負荷", - "llmSlo": "LLM SLO", - "gpu": "GPU", - "host": "ホスト", - "security": "セキュリティ" - }, - "config": { - "title": "監視設定", - "grafanaUrl": "Grafana URL", - "datasource": "データソース名", - "alertDatasource": "アラートデータソース名", - "alertDatasourceHint": "空欄の場合はメインデータソースを使用", - "clusterName": "クラスター名", - "dashboardUid": "ダッシュボード UID", - "dashboardOverview": "クラスター概要", - "dashboardModelLoad": "モデル負荷", - "dashboardLlmSlo": "LLM SLO", - "dashboardGpu": "GPU リソース", - "dashboardHost": "ホストリソース", - "dashboardSecurity": "セキュリティ監査", - "save": "保存", - "saving": "保存中...", - "cancel": "キャンセル", - "reset": "デフォルトに戻す", - "openConfig": "設定を開く", - "sourceDb": "データベース", - "sourceEnv": "環境変数", - "sourceDefault": "デフォルト", - "healthCheckFailed": "Grafana 接続チェック失敗", - "saved": "設定を保存しました", - "saveFailed": "設定の保存に失敗しました", - "loadFailed": "設定の読み込みに失敗しました", - "resetDone": "設定をデフォルトに戻しました", - "checking": "チェック中..." - }, - "configHint": "上の設定ボタンまたは下のボタンをクリックして Grafana を設定してください。" - }, - "logs": { - "notConfigured": "ログクエリが設定されていません。XINFERENCE_ES_URL 環境変数を設定してください。", - "searchPlaceholder": "ログを検索...", - "allNodes": "全ノード", - "logLevel": "ログレベル", - "nodeType": "ノードタイプ", - "time": "時刻", - "level": "レベル", - "node": "ノード", - "message": "メッセージ", - "fullMessage": "完全なメッセージ", - "noLogs": "ログが見つかりません", - "refresh": "更新", - "totalHits": "合計: {{count}} 件", - "prevPage": "前へ", - "nextPage": "次へ", - "detail": { - "module": "モジュール", - "pid": "PID", - "request_id": "リクエストID", - "address": "アドレス", - "log_type": "ログタイプ", - "rtf_avg": "RTF平均", - "time_speech": "音声時間", - "time_escape": "処理時間", - "tableTab": "テーブル", - "jsonTab": "JSON", - "action": "操作", - "field": "フィールド", - "value": "値", - "filterFor": "この値でフィルター", - "filterOut": "この値を除外", - "copyJson": "JSONをコピー", - "copied": "コピーしました!", - "viewContext": "周辺ドキュメントを表示", - "contextTitle": "周辺ドキュメント", - "loadNewer": "読み込む", - "loadOlder": "読み込む", - "newerDocs": "件の新しいドキュメント", - "olderDocs": "件の古いドキュメント", - "anchorRow": "現在のドキュメント", - "contextError": "この機能にはバックエンドの更新が必要です。", - "contextFetchError": "周辺ドキュメントの読み込みに失敗しました。" - } - }, - "userManagement": { - "title": "ユーザー管理", - "createUser": "ユーザー作成", - "id": "ID", - "username": "ユーザー名", - "source": "ソース", - "status": "状態", - "permissions": "権限", - "actions": "操作", - "active": "有効", - "disabled": "無効", - "dialogTitle": "ユーザー作成", - "usernameLabel": "ユーザー名", - "passwordLabel": "パスワード", - "permissionsLabel": "権限(カンマ区切り)", - "permissionsHelperText": "例: models:list, models:read, keys:create", - "cancel": "キャンセル", - "create": "作成", - "confirmDelete": "ユーザーを削除しますか", - "selectAll": "全選択", - "editPermissions": "権限編集", - "editPermissionsTitle": "権限編集", - "save": "保存", - "changePassword": "パスワード変更", - "changePasswordTitle": "パスワード変更", - "newPassword": "新しいパスワード", - "confirmPassword": "パスワード確認", - "passwordMismatch": "パスワードが一致しません", - "passwordTooShort": "パスワードは8文字以上である必要があります", - "changePasswordSuccess": "パスワードが正常に変更されました" - }, - "permissions": { - "admin": "管理者", - "models_list": "モデル一覧表示", - "models_read": "モデル情報読取", - "models_write": "モデル起動/停止", - "keys_create": "API Key 作成", - "keys_manage": "API Key 管理", - "users_manage": "ユーザー管理", - "cache_list": "キャッシュ表示", - "cache_delete": "キャッシュ削除", - "virtualenv_list": "仮想環境表示", - "virtualenv_delete": "仮想環境削除", - "models_register": "モデル登録/解除", - "logs_list": "ログ表示", - "monitor_view": "モニタリング表示" - }, - "apikeyManagement": { - "title": "API Key 管理", - "createKey": "Key 作成", - "id": "ID", - "name": "名前", - "prefix": "プレフィックス", - "status": "状態", - "expires": "有効期限", - "modelPermissions": "モデル権限", - "actions": "操作", - "active": "有効", - "disabled": "無効", - "revealTooltip": "キーを表示", - "disableTooltip": "無効化", - "enableTooltip": "有効化", - "deleteTooltip": "削除", - "keyCreatedTitle": "Key 作成完了", - "createKeyTitle": "API Key 作成", - "saveKeyWarning": "このキーを今すぐ保存してください。後で再表示することはできません。", - "nameLabel": "名前(任意)", - "ownerLabel": "所有者", - "ownerHelperText": "空にすると現在のユーザーに割り当て", - "owner": "所有者", - "expiresLabel": "有効期限(任意)", - "expiresHelperText": "空にすると無期限", - "permissionType": "権限タイプ", - "allModels": "全モデル", - "byModelType": "モデルタイプ別", - "byModelId": "モデルID別", - "permissionValues": "権限値(カンマ区切り)", - "modelTypeHelper": "例: LLM, embedding, rerank", - "modelIdHelper": "例: qwen2-72b, bge-m3", - "close": "閉じる", - "cancel": "キャンセル", - "create": "作成", - "save": "保存", - "revealTitle": "API Key", - "confirmDelete": "API Key を削除しますか", - "copy": "コピー", - "copied": "クリップボードにコピーしました", - "editPermTooltip": "権限編集", - "editPermTitle": "モデル権限編集 —", - "editKeyTitle": "API Key 編集 —", - "mixedMode": "タイプ別 + インスタンス別(混合)", - "bans": "禁止数", - "description": "説明", - "descriptionLabel": "申請理由(任意)", - "bannedIpsForKey": "Key #{{keyId}} の禁止 IP", - "noActiveBans": "禁止中のIPはありません", - "remaining": "残り: {{seconds}}秒", - "unban": "解除", - "viewBans": "表示", - "failedLoadBans": "禁止情報の読み込みに失敗しました", - "failedUnban": "解除に失敗しました" - }, - "securitySettings": { - "title": "セキュリティ設定", - "rateLimitConfig": "レート制限設定", - "ipLayer": "IP 層", - "keyLayer": "Key 層(デフォルト)", - "maxFailures": "最大失敗回数", - "windowSeconds": "ウィンドウ(秒)", - "banSeconds": "禁止期間(秒)", - "saveConfig": "設定を保存", - "bannedIps": "禁止 IP", - "bannedIpsDesc": "存在しないキーや無効なトークンでの失敗が時間窓口内に最大回数を超えた IP を自動的に禁止。禁止期間中、該当 IP からのすべてのリクエストが拒否されます(禁止期間は IP 層の設定に従う)", - "noBannedIps": "禁止 IP なし", - "bannedKeys": "禁止 (IP, Key) ペア", - "bannedKeysDesc": "期限切れや無効化されたキーでの失敗が時間窓口内に最大回数を超えた IP+Key ペアを自動的に禁止。該当の IP+Key 組み合わせのみ拒否され、同じ IP から他のキーを使用する場合は影響なし(禁止期間は Key 層の設定に従う)", - "noBannedKeys": "禁止記録なし", - "ip": "IP", - "keyId": "Key ID", - "remaining": "残り時間(秒)", - "action": "操作", - "unbanAll": "全解除" - }, - "auditLog": { - "title": "監査センター", - "time": "時刻", - "user": "ユーザー", - "apiKey": "API Key", - "model": "モデル", - "type": "タイプ", - "status": "ステータス", - "clientIp": "クライアントIP", - "modelId": "モデルID", - "modelName": "モデル名", - "endpoint": "エンドポイント", - "latency": "レイテンシ (ms)", - "timeFrom": "開始", - "timeTo": "終了", - "search": "検索", - "noData": "監査記録なし", - "custom": "カスタム", - "totalRecords": "全 {{count}} 件", - "prevPage": "前へ", - "nextPage": "次へ", - "tableTab": "テーブル", - "jsonTab": "JSON", - "detailField": "フィールド", - "detailValue": "値", - "copyJson": "JSONコピー", - "copied": "コピー済", - "modelType": "モデルタイプ", - "category": "カテゴリ", - "category_inference": "推論", - "category_admin": "管理", - "category_auth": "認証" - }, - "login": { - "or": "または", - "sso": "SSO ログイン" - } -} diff --git a/xinference/ui/web/ui/src/locales/ko.json b/xinference/ui/web/ui/src/locales/ko.json deleted file mode 100644 index 79896eb825..0000000000 --- a/xinference/ui/web/ui/src/locales/ko.json +++ /dev/null @@ -1,587 +0,0 @@ -{ - "menu": { - "launchModel": "모델 실행", - "runningModels": "실행 중인 모델", - "registerModel": "모델 등록", - "clusterInfo": "클러스터 정보", - "monitoring": "모니터링", - "logs": "로그 센터", - "xagent": "Xagent로 AI 에이전트 구축", - "contactUs": "문의하기", - "documentation": "문서", - "website": "공식 웹사이트", - "expand": "펼치기", - "collapse": "접기", - "logout": "로그아웃", - "userManagement": "사용자 관리", - "apikeyManagement": "API Key 관리", - "securitySettings": "보안 설정", - "auditLog": "감사 센터" - }, - "model": { - "languageModels": "언어 모델", - "embeddingModels": "임베딩 모델", - "rerankModels": "재순위 모델", - "imageModels": "이미지 모델", - "audioModels": "오디오 모델", - "videoModels": "비디오 모델", - "customModels": "커스텀 모델", - "flexibleModels": "유연한 모델" - }, - "launchModel": { - "modelAbility": "모델 기능", - "generate": "텍스트 생성", - "chat": "대화", - "vision": "비전", - "reasoning": "추론", - "tools": "도구 사용", - "audio": "오디오 처리", - "omni": "멀티모달 (Omni)", - "hybrid": "하이브리드 기능", - "text2image": "텍스트에서 이미지", - "image2image": "이미지에서 이미지", - "inpainting": "이미지 인페인팅", - "ocr": "광학 문자 인식 (OCR)", - "audio2text": "오디오에서 텍스트", - "text2audio": "텍스트에서 오디오", - "text2audio_zero_shot": "텍스트에서 오디오 (제로 샷)", - "text2audio_voice_cloning": "텍스트에서 오디오 (음성 클로닝)", - "text2audio_emotion_control": "텍스트에서 오디오(감정 제어)", - "text2video": "텍스트에서 비디오", - "image2video": "이미지에서 비디오", - "firstlastframe2video": "첫 번째와 마지막 프레임에서 비디오", - "status": "상태", - "cached": "캐시됨", - "manageCachedModels": "캐시 모델 관리", - "manageVirtualEnvironments": "가상 환경 관리", - "favorite": "즐겨찾기", - "unfavorite": "즐겨찾기 해제", - "search": "모델 이름 및 설명 검색", - "searchModelType": "{{modelType}} 모델 이름 검색", - "searchInstruction": "{{hotkey}}로 검색", - "clickToLaunchModel": "마우스 클릭으로 모델 실행", - "dimensions": "차원", - "maxTokens": "최대 토큰 수", - "edit": "편집", - "delete": "삭제", - "contextLength": "컨텍스트 길이", - "chatModel": "채팅 모델", - "generateModel": "생성 모델", - "otherModel": "기타 모델", - "confirmDeleteCustomModel": "이 커스텀 모델을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", - "modelName": "모델 이름", - "envPath": "환경 경로", - "realPath": "실제 경로", - "copyEnvPath": "환경 경로 복사", - "viewPackages": "패키지 목록 보기", - "installedPackages": "설치된 패키지", - "packageName": "패키지 이름", - "version": "버전", - "location": "위치", - "packagesCount": "패키지 수", - "size": "크기", - "pythonVersion": "Python 버전", - "createdAt": "생성 시간", - "noVirtualEnvironmentsForNow": "현재 가상환경이 없습니다!", - "noPackagesInstalled": "설치된 패키지가 없습니다", - "lastConfig": "마지막 설정", - "configCache": "구성 캐시", - "newCache": "새 캐시", - "noConfigCache": "현재 구성 캐시가 없습니다!", - "loadCache": "사용하기", - "deleteCache": "캐시 삭제", - "lastUpdated": "마지막 업데이트", - "createdBy": "작성자", - "defaultConfig": "기본 구성", - "confirmDeleteConfigCache": "이 구성 캐시를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", - "invalidConfigCache": "이 구성 캐시에 필요한 모델 엔진을 현재 사용할 수 없습니다.", - "commandLineParsing": "명령줄 인수 파싱", - "copyToCommandLine": "명령줄 명령으로 복사", - "modelEngine": "모델 엔진", - "modelFormat": "모델 형식", - "modelSize": "모델 크기", - "quantization": "양자화", - "multimodelProjector": "멀티모델 프로젝터", - "nGPU": "레플리카당 GPU 수", - "nGPUPerWorker": "워커당 GPU 수", - "nGpuLayers": "GPU 레이어 수", - "replica": "레플리카", - "optionalConfigurations": "선택적 구성", - "modelUID.optional": "(선택) 모델 UID, 기본값은 모델 이름", - "requestLimits.optional": "(선택) 요청 제한, 이 모델의 요청 제한 수, 기본값은 없음", - "workerIp.optional": "(선택 사항) 워커 IP, 분산 환경에서는 하나 이상의 워커 노드를 선택할 수 있습니다", - "workerIp": "워커 IP, 분산 시나리오에서 모델이 위치한 워커 IP 지정", - "loadingWorkerNodes": "워커 노드를 불러오는 중...", - "workerNodesLoadFailed": "워커 노드를 불러오지 못했습니다.", - "noWorkerNodesAvailable": "현재 사용 가능한 워커 노드가 없습니다.", - "noAvailableGpuWorkers": "현재 선택한 디바이스에서 사용할 수 있는 GPU 지원 워커 노드가 없습니다.", - "workerNodesUnavailableForValidation": "워커 노드 정보를 사용할 수 없습니다. 워커 목록이 로드될 때까지 기다리거나 워커 선택을 해제해 주세요.", - "invalidWorkerSelection": "선택한 워커 노드는 현재 디바이스 선택에 사용할 수 없습니다.", - "gpuIdxNotAllowedForCpu": "디바이스가 CPU인 경우 GPU 인덱스는 비워 두어야 합니다.", - "gpuIdxMustMatchReplica": "GPU 인덱스 개수는 레플리카 수의 배수여야 합니다.", - "fixFieldErrorsBeforeLaunch": "배포 전에 강조 표시된 입력 오류를 수정해 주세요.", - "workerCount.optional": "(선택) 워커 수", - "GPUIdx.optional": "(선택) GPU 인덱스, 모델이 위치한 GPU 인덱스 지정", - "GPUIdx": "GPU 인덱스, 모델이 위치한 GPU 인덱스 지정", - "downloadHub.optional": "(선택) 다운로드 허브", - "modelPath.optional": "(선택) 모델 경로, PyTorch의 경우 모델 디렉토리, GGML/GGUF의 경우 모델 파일 경로 지정", - "GGUFQuantization.optional": "(선택) GGUF 양자화 형식, Transformer 부분 양자화", - "GGUFModelPath.optional": "(선택) GGUF 모델 경로, .gguf로 끝나는 파일 지정", - "lightningVersions.optional": "(선택) 경량화 버전", - "lightningModelPath.optional": "(선택) 경량화 lora 모델 경로", - "enableThinking": "사고 활성화", - "parsingReasoningContent": "추론 내용 파싱", - "CPUOffload": "CPU 오프로드", - "CPUOffload.tip": "모델을 CPU로 언로드합니다. 리소스가 제한된 경우 또는 GGUF 옵션을 사용할 때 권장됩니다.", - "loraConfig": "Lora 설정", - "loraModelConfig": "Lora 모델 설정", - "virtualEnvConfig": "가상 환경 설정", - "modelVirtualEnv": "모델 가상 환경", - "virtualEnvPackage": "가상 환경 패키지", - "envVariable": "환경 변수", - "envVariableConfig": "환경 변수 설정", - "additionalQuantizationParametersForInferenceEngine": "추론 엔진에 전달되는 추가 양자화 매개변수", - "additionalParametersForInferenceEngine": "추론 엔진에 전달되는 추가 매개변수", - "enterIntegerGreaterThanZero": "0보다 큰 정수를 입력하세요.", - "enterCommaSeparatedNumbers": "쉼표로 구분된 숫자를 입력하세요. 예: 0,1,2", - "device": "장치", - "loraLoadKwargsForImageModel": "이미지 모델의 Lora 로드 인수", - "loraFuseKwargsForImageModel": "이미지 모델의 Lora 퓨즈 인수", - "launch": "실행", - "launchCompletedWithAutostart": "모델 배포가 완료되고 자동 시작에 추가되었습니다", - "autostartSaveFailed": "모델이 시작되었지만 자동 시작 구성을 저장하지 못했습니다", - "saveAutostart": "시작 성공 후 자동 시작으로 설정", - "goBack": "뒤로 가기", - "copyJson": "Json 복사", - "cancel": "취소", - "confirm": "확인", - "placeholderTip": "입력하세요", - "fillCompleteParametersBeforeAdding": "추가하기 전에 완전한 매개변수를 입력하세요!", - "model_format": "모델 형식", - "model_size_in_billions": "모델 크기(억 단위)", - "quantizations": "양자화", - "real_path": "실제 경로", - "path": "경로", - "ipAddress": "IP 주소", - "operation": "작업", - "copyRealPath": "실제 경로 복사", - "copyPath": "경로 복사", - "noCacheForNow": "현재 캐시가 없습니다!", - "confirmDeleteCacheFiles": "캐시 파일을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", - "confirmDeleteVirtualEnv": "가상 환경을 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", - "commandLineTip": "모델 이름이 일치하는지 확인하세요.", - "featured": "추천 및 즐겨찾기", - "all": "모두", - "cancelledSuccessfully": "성공적으로 취소되었습니다!", - "mustBeUnique": "{{key}} 는 고유해야 합니다", - "update": "업데이트", - "launchProgress": "시작 진행 상황", - "initializing": "초기화 중...", - "moreDetails": "자세히 보기" - }, - "modelReplicaDetails": { - "title": "모델 복제본 세부 정보", - "modelUid": "모델 UID", - "replicaId": "복제본 ID", - "workerAddress": "워커 주소", - "status": "상태", - "createdTime": "생성 시간", - "actions": "작업", - "noReplicaInfo": "복제본 정보를 사용할 수 없습니다", - "errors": "오류", - "replica": "복제본", - "remove": "제거", - "removeConfirm": "모델 {{modelUid}} 의 복제본 {{replicaId}} 을(를) 제거하시겠습니까?", - "close": "닫기" - }, - "runningModels": { - "name": "이름", - "address": "주소", - "gpuIndexes": "GPU 인덱스", - "size": "크기", - "quantization": "양자화", - "replica": "레플리카", - "actions": "작업", - "noRunningModels": "실행 중인 모델이 없습니다", - "noRunningModelsMatches": "일치하는 실행 중인 모델이 없습니다", - "copy": "복사", - "copied": "복사되었습니다!", - "copyFailed": "복사 실패", - "viewDetails": "상세 보기", - "autostartEnabled": "자동 시작이 설정됨", - "removeAutostartSuccess": "{{modelUid}}의 자동 시작을 제거했습니다", - "removeAutostartFailed": "자동 시작 제거에 실패했습니다", - "terminateModel": "모델 종료", - "terminateInProgress": "종료 중…", - "terminateConfirmTitle": "이 모델을 종료하시겠습니까?", - "terminateConfirmBody": "이 모델에는 {{replica}}개의 레플리카가 있습니다. 클러스터가 혼잡하거나 레플리카가 많을 경우 종료에 몇 분이 걸릴 수 있으며, 총 소요 시간은 가장 느린 워커에 의해 결정됩니다. 종료를 반복 클릭하지 마십시오.", - "terminateConfirmOk": "종료", - "terminateErrorHint": "요청이 실패했거나 모델이 이미 삭제되었을 수 있습니다. 실행 중인 모델 목록을 새로고침하여 확인하세요." - }, - "registerModel": { - "modelName": "모델 이름", - "modelDescription": "모델 설명 (선택)", - "contextLength": "컨텍스트 길이", - "dimensions": "차원", - "maxTokens": "최대 토큰 수", - "modelPath": "모델 경로", - "modelLanguages": "모델 언어", - "languages": "언어", - "multilingual": "다국어", - "modelAbilities": "모델 기능", - "modelFamily": "모델 패밀리", - "chatTemplate": "채팅 템플릿", - "test": "테스트", - "testResult": "테스트 결과", - "noTestResults": "테스트 결과가 없습니다...", - "stopTokenIds": "중지 토큰 ID", - "stop": "중지", - "reasoningStartTag": "추론 시작 태그", - "reasoningEndTag": "추론 종료 태그", - "toolParser": "도구 파서", - "launcher": "런처", - "launcherArguments": "런처 인수 (선택)", - "edit": "편집", - "cancel": "취소", - "registerModel": "모델 등록", - "messagesExample": "메시지 예시", - "JSONFormat": "JSON 형식", - "modelSpecs": "모델 사양", - "modelSizeBillions": "모델 크기(억 단위)", - "quantization": "양자화", - "quantizationOptional": "양자화 (선택)", - "delete": "삭제", - "controlnet": "Controlnet", - "packages": "가상환경 패키지", - "more": "더보기", - "modelFormat": "모델 형식", - "enterNumberGreaterThanZero": "0보다 큰 숫자를 입력하세요.", - "carefulQuantizationForModelRegistration": "GPTQ/AWQ/FP8/MLX 모델의 경우, 등록하려는 모델에 해당하는 양자화를 신중하게 입력하세요.", - "quantizationCannotBeEmpty": "양자화는 비워둘 수 없습니다.", - "enterInteger": "정수를 입력하세요.", - "enterIntegerGreaterThanZero": "0보다 큰 정수를 입력하세요.", - "showCustomJsonConfig": "API에서 사용하는 사용자 정의 json 설정 표시", - "packUp": "접기", - "unfold": "펼치기", - "copyAll": "모두 복사", - "alphanumericWithHyphensUnderscores": "하이픈과 언더스코어가 적절히 배치된 영숫자. 내장 모델 이름과 일치하지 않아야 합니다.", - "chooseBuiltInOrCustomModel": "내장 모델에서 선택하거나 자신의 모델을 입력할 수 있습니다.", - "chooseOnlyBuiltInModel": "내장 모델만 선택할 수 있습니다.", - "provideModelDirectoryPath": "모델 디렉토리 경로를 제공하세요.", - "provideModelLauncher": "모델 런처를 제공하세요.", - "jsonArgumentsForLauncher": "런처에 전달되는 인수를 나타내는 JSON 형식의 사전.", - "provideModelDirectoryOrFilePath": "PyTorch의 경우 모델 디렉토리, GGUF의 경우 모델 파일 경로를 제공하세요.", - "ensureChatTemplatePassesTest": "오른쪽의 TEST 버튼을 클릭하여 이 chat_template이 테스트를 통과하는지 확인하세요. 이 테스트는 모든 경우를 다루지 않으며 가장 기본적인 경우에만 사용됩니다.", - "testFailurePreventsChatWorking": "테스트를 통과하지 못하면 채팅이 제대로 작동하지 않을 수 있습니다.", - "stopControlForChatModels": "int 유형, 채팅 모델의 중지를 제어하는 데 사용", - "stopControlStringForChatModels": "string 유형, 채팅 모델의 중지를 제어하는 데 사용", - "enterJsonFormattedDictionary": "JSON 형식의 사전을 입력하세요.", - "autoFill": "자동 채우기", - "fillInModelPathFirst": "먼저 모델 경로를 입력하세요", - "fillInModelFamilyFirst": "먼저 모델 패밀리를 선택하세요" - }, - "clusterInfo": { - "supervisor": "슈퍼바이저", - "workers": "워커", - "workerDetails": "워커 세부 정보", - "count": "수", - "cpuInfo": "CPU 정보", - "usage": "사용률:", - "total": "총계", - "cpuMemoryInfo": "CPU 메모리 정보", - "version": "버전", - "release": "릴리스:", - "commit": "커밋:", - "gpuInfo": "GPU 정보", - "gpuMemoryInfo": "GPU 메모리 정보", - "address": "주소", - "item": "항목", - "value": "값", - "nodeType": "노드 유형", - "cpuUsage": "CPU 사용률", - "cpuTotal": "CPU 총계", - "memUsage": "메모리 용량", - "memTotal": "메모리 총계", - "gpuCount": "GPU 수", - "gpuLoad": "GPU 로드", - "gpuMemUsage": "GPU 메모리 사용량", - "gpuMemTotal": "GPU 메모리 총계", - "worker": "워커" - }, - "components": { - "suggestsCommonParameters": "일반적인 매개변수를 제안합니다. 다른 매개변수도 사용 가능합니다.", - "warning": "경고", - "ok": "확인", - "cancel": "취소" - }, - "monitoring": { - "notConfigured": "모니터링이 구성되지 않았습니다.", - "time": { - "5m": "최근 5분", - "15m": "최근 15분", - "30m": "최근 30분", - "1h": "최근 1시간", - "3h": "최근 3시간", - "6h": "최근 6시간", - "12h": "최근 12시간", - "24h": "최근 24시간", - "7d": "최근 7일", - "2d": "최근 2일" - }, - "refresh": { - "off": "끄기", - "10s": "10초", - "30s": "30초", - "1m": "1분", - "5m": "5분" - }, - "absoluteRange": "절대 시간 범위", - "from": "시작", - "to": "종료", - "applyTimeRange": "시간 범위 적용", - "manualRefresh": "대시보드 새로고침", - "tab": { - "overview": "개요", - "modelLoad": "모델 부하", - "llmSlo": "LLM SLO", - "gpu": "GPU", - "host": "호스트", - "security": "보안" - }, - "config": { - "title": "모니터링 설정", - "grafanaUrl": "Grafana URL", - "datasource": "데이터소스 이름", - "alertDatasource": "알림 데이터소스 이름", - "alertDatasourceHint": "비워두면 메인 데이터소스 사용", - "clusterName": "클러스터 이름", - "dashboardUid": "대시보드 UID", - "dashboardOverview": "클러스터 개요", - "dashboardModelLoad": "모델 부하", - "dashboardLlmSlo": "LLM SLO", - "dashboardGpu": "GPU 리소스", - "dashboardHost": "호스트 리소스", - "dashboardSecurity": "보안 감사", - "save": "저장", - "saving": "저장 중...", - "cancel": "취소", - "reset": "기본값으로 초기화", - "openConfig": "설정 열기", - "sourceDb": "데이터베이스", - "sourceEnv": "환경변수", - "sourceDefault": "기본값", - "healthCheckFailed": "Grafana 연결 확인 실패", - "saved": "설정이 저장되었습니다", - "saveFailed": "설정 저장 실패", - "loadFailed": "설정 로드 실패", - "resetDone": "설정이 기본값으로 초기화되었습니다", - "checking": "확인 중..." - }, - "configHint": "위의 설정 버튼 또는 아래 버튼을 클릭하여 Grafana를 설정하세요." - }, - "logs": { - "notConfigured": "로그 조회가 구성되지 않았습니다. XINFERENCE_ES_URL 환경 변수를 설정하세요.", - "searchPlaceholder": "로그 검색...", - "allNodes": "전체 노드", - "logLevel": "로그 레벨", - "nodeType": "노드 유형", - "time": "시간", - "level": "레벨", - "node": "노드", - "message": "메시지", - "fullMessage": "전체 메시지", - "noLogs": "로그를 찾을 수 없습니다", - "refresh": "새로고침", - "totalHits": "총 {{count}} 건", - "prevPage": "이전", - "nextPage": "다음", - "detail": { - "module": "모듈", - "pid": "PID", - "request_id": "요청 ID", - "address": "주소", - "log_type": "로그 유형", - "rtf_avg": "RTF 평균", - "time_speech": "음성 시간", - "time_escape": "처리 시간", - "tableTab": "테이블", - "jsonTab": "JSON", - "action": "작업", - "field": "필드", - "value": "값", - "filterFor": "이 값으로 필터", - "filterOut": "이 값 제외", - "copyJson": "JSON 복사", - "copied": "복사됨!", - "viewContext": "주변 문서 보기", - "contextTitle": "주변 문서", - "loadNewer": "불러오기", - "loadOlder": "불러오기", - "newerDocs": "최신 문서", - "olderDocs": "이전 문서", - "anchorRow": "현재 문서", - "contextError": "이 기능을 사용하려면 백엔드를 업데이트해야 합니다.", - "contextFetchError": "주변 문서를 불러오지 못했습니다." - } - }, - "userManagement": { - "title": "사용자 관리", - "createUser": "사용자 생성", - "id": "ID", - "username": "사용자 이름", - "source": "출처", - "status": "상태", - "permissions": "권한", - "actions": "작업", - "active": "활성", - "disabled": "비활성", - "dialogTitle": "사용자 생성", - "usernameLabel": "사용자 이름", - "passwordLabel": "비밀번호", - "permissionsLabel": "권한 (쉼표 구분)", - "permissionsHelperText": "예: models:list, models:read, keys:create", - "cancel": "취소", - "create": "생성", - "confirmDelete": "사용자를 삭제하시겠습니까", - "selectAll": "전체 선택", - "editPermissions": "권한 편집", - "editPermissionsTitle": "권한 편집", - "save": "저장", - "changePassword": "비밀번호 변경", - "changePasswordTitle": "비밀번호 변경", - "newPassword": "새 비밀번호", - "confirmPassword": "비밀번호 확인", - "passwordMismatch": "비밀번호가 일치하지 않습니다", - "passwordTooShort": "비밀번호는 최소 8자 이상이어야 합니다", - "changePasswordSuccess": "비밀번호가 성공적으로 변경되었습니다" - }, - "permissions": { - "admin": "관리자", - "models_list": "모델 목록 보기", - "models_read": "모델 정보 읽기", - "models_write": "모델 시작/중지", - "keys_create": "API Key 생성", - "keys_manage": "API Key 관리", - "users_manage": "사용자 관리", - "cache_list": "캐시 보기", - "cache_delete": "캐시 삭제", - "virtualenv_list": "가상환경 보기", - "virtualenv_delete": "가상환경 삭제", - "models_register": "모델 등록/해제", - "logs_list": "로그 보기", - "monitor_view": "모니터링 보기" - }, - "apikeyManagement": { - "title": "API Key 관리", - "createKey": "Key 생성", - "id": "ID", - "name": "이름", - "prefix": "접두사", - "status": "상태", - "expires": "만료일", - "modelPermissions": "모델 권한", - "actions": "작업", - "active": "활성", - "disabled": "비활성", - "revealTooltip": "키 보기", - "disableTooltip": "비활성화", - "enableTooltip": "활성화", - "deleteTooltip": "삭제", - "keyCreatedTitle": "Key 생성 완료", - "createKeyTitle": "API Key 생성", - "saveKeyWarning": "이 키를 지금 저장하세요. 나중에 다시 볼 수 없습니다.", - "nameLabel": "이름 (선택)", - "ownerLabel": "소유자", - "ownerHelperText": "비워두면 현재 사용자에게 할당", - "owner": "소유자", - "expiresLabel": "만료일 (선택)", - "expiresHelperText": "비워두면 만료 없음", - "permissionType": "권한 유형", - "allModels": "전체 모델", - "byModelType": "모델 유형별", - "byModelId": "모델 ID별", - "permissionValues": "권한 값 (쉼표 구분)", - "modelTypeHelper": "예: LLM, embedding, rerank", - "modelIdHelper": "예: qwen2-72b, bge-m3", - "close": "닫기", - "cancel": "취소", - "create": "생성", - "save": "저장", - "revealTitle": "API Key", - "confirmDelete": "API Key를 삭제하시겠습니까", - "copy": "복사", - "copied": "클립보드에 복사됨", - "editPermTooltip": "권한 편집", - "editPermTitle": "모델 권한 편집 —", - "editKeyTitle": "API Key 편집 —", - "mixedMode": "유형별 + 인스턴스별 (혼합)", - "bans": "차단 수", - "description": "설명", - "descriptionLabel": "신청 사유 (선택)", - "bannedIpsForKey": "Key #{{keyId}}의 차단된 IP", - "noActiveBans": "활성 차단 없음", - "remaining": "남은 시간: {{seconds}}초", - "unban": "차단 해제", - "viewBans": "보기", - "failedLoadBans": "차단 정보 로드 실패", - "failedUnban": "차단 해제 실패" - }, - "securitySettings": { - "title": "보안 설정", - "rateLimitConfig": "속도 제한 설정", - "ipLayer": "IP 계층", - "keyLayer": "Key 계층 (기본값)", - "maxFailures": "최대 실패 횟수", - "windowSeconds": "시간 창 (초)", - "banSeconds": "차단 기간 (초)", - "saveConfig": "설정 저장", - "bannedIps": "차단된 IP", - "bannedIpsDesc": "존재하지 않는 키 또는 유효하지 않은 토큰으로 시간 창 내 최대 실패 횟수를 초과한 IP를 자동 차단. 차단 기간 동안 해당 IP의 모든 요청이 거부됩니다 (차단 기간은 IP 계층 설정에 따름)", - "noBannedIps": "차단된 IP 없음", - "bannedKeys": "차단된 (IP, Key) 쌍", - "bannedKeysDesc": "만료되거나 비활성화된 키로 시간 창 내 최대 실패 횟수를 초과한 IP+Key 쌍을 자동 차단. 해당 IP+Key 조합만 거부되며, 같은 IP에서 다른 키 사용은 영향 없음 (차단 기간은 Key 계층 설정에 따름)", - "noBannedKeys": "차단 기록 없음", - "ip": "IP", - "keyId": "Key ID", - "remaining": "남은 시간 (초)", - "action": "작업", - "unbanAll": "전체 해제" - }, - "auditLog": { - "title": "감사 센터", - "time": "시간", - "user": "사용자", - "apiKey": "API Key", - "model": "모델", - "type": "유형", - "status": "상태", - "clientIp": "클라이언트 IP", - "modelId": "모델 ID", - "modelName": "모델명", - "endpoint": "엔드포인트", - "latency": "지연시간 (ms)", - "timeFrom": "시작", - "timeTo": "종료", - "search": "검색", - "noData": "감사 기록 없음", - "custom": "사용자 정의", - "totalRecords": "총 {{count}} 건", - "prevPage": "이전", - "nextPage": "다음", - "tableTab": "테이블", - "jsonTab": "JSON", - "detailField": "필드", - "detailValue": "값", - "copyJson": "JSON 복사", - "copied": "복사됨", - "modelType": "모델 유형", - "category": "분류", - "category_inference": "추론", - "category_admin": "관리", - "category_auth": "인증" - }, - "login": { - "or": "또는", - "sso": "SSO 로그인" - } -} diff --git a/xinference/ui/web/ui/src/locales/zh.json b/xinference/ui/web/ui/src/locales/zh.json deleted file mode 100644 index 998fb9017a..0000000000 --- a/xinference/ui/web/ui/src/locales/zh.json +++ /dev/null @@ -1,596 +0,0 @@ -{ - "menu": { - "launchModel": "启动模型", - "runningModels": "运行模型", - "registerModel": "注册模型", - "clusterInfo": "集群信息", - "monitoring": "监控中心", - "logs": "日志中心", - "xagent": "使用 Xagent 构建 AI 智能体", - "contactUs": "联系我们", - "documentation": "文档", - "website": "官网", - "expand": "展开", - "collapse": "折叠", - "userManagement": "用户管理", - "apikeyManagement": "API Key 管理", - "securitySettings": "安全设置", - "auditLog": "审计中心", - "logout": "退出登录" - }, - "auth": { - "permissionError": "权限错误", - "authenticationError": "认证错误", - "noPermission": "您没有执行此操作的权限!", - "invalidCredentials": "凭证无效!请重新登录。", - "confirmed": "确认" - }, - "model": { - "languageModels": "语言模型", - "embeddingModels": "嵌入模型", - "rerankModels": "重排序模型", - "imageModels": "图像模型", - "audioModels": "音频模型", - "videoModels": "视频模型", - "customModels": "自定义模型", - "flexibleModels": "灵活模型" - }, - "launchModel": { - "modelAbility": "模型能力", - "generate": "文本生成", - "chat": "对话", - "vision": "图像识别", - "reasoning": "推理能力", - "tools": "工具使用能力", - "audio": "音频处理", - "omni": "全模态", - "hybrid": "混合能力", - "text2image": "文生图", - "image2image": "图生图", - "inpainting": "图像修复", - "ocr": "光学字符识别", - "audio2text": "语音转文本", - "text2audio": "文本转语音", - "text2audio_zero_shot": "文本转语音(零样本)", - "text2audio_voice_cloning": "文本转语音(声音克隆)", - "text2audio_emotion_control": "文本转语音(情感控制)", - "text2video": "文生视频", - "image2video": "图生视频", - "firstlastframe2video": "首尾帧生视频", - "status": "状态", - "cached": "已缓存", - "manageCachedModels": "管理缓存模型", - "manageVirtualEnvironments": "管理虚拟环境", - "favorite": "收藏", - "unfavorite": "取消收藏", - "search": "搜索模型名称和描述", - "searchModelType": "搜索 {{modelType}} 相关的模型名称", - "searchInstruction": "输入 {{hotkey}} 进行搜索", - "clickToLaunchModel": "点击鼠标以启动模型", - "dimensions": "维度", - "maxTokens": "最大 token 数", - "edit": "编辑", - "delete": "删除", - "contextLength": "上下文长度", - "chatModel": "聊天模型", - "generateModel": "生成模型", - "otherModel": "其他模型", - "confirmDeleteCustomModel": "您确定要删除这个自定义模型吗?此操作无法恢复。", - "modelName": "模型名称", - "envPath": "环境路径", - "realPath": "真实路径", - "copyEnvPath": "复制环境路径", - "viewPackages": "查看包列表", - "installedPackages": "已安装的包", - "packageName": "包名称", - "version": "版本", - "location": "位置", - "packagesCount": "包数量", - "size": "大小", - "pythonVersion": "Python 版本", - "createdAt": "创建时间", - "noVirtualEnvironmentsForNow": "当前没有虚拟环境!", - "noPackagesInstalled": "未安装任何包", - "lastConfig": "最后配置", - "configCache": "配置缓存", - "newCache": "新建缓存", - "noConfigCache": "当前没有配置缓存!", - "loadCache": "使用", - "deleteCache": "删除缓存", - "lastUpdated": "最后更新", - "createdBy": "创建者", - "defaultConfig": "默认配置", - "confirmDeleteConfigCache": "确认删除这条配置缓存吗?此操作无法恢复。", - "invalidConfigCache": "这条配置缓存对应的模型引擎当前不可用。", - "commandLineParsing": "解析命令行参数", - "copyToCommandLine": "复制为命令行指令", - "modelEngine": "模型引擎", - "modelFormat": "模型格式", - "modelSize": "模型大小", - "quantization": "量化", - "multimodelProjector": "多模态投影器", - "nGPU": "GPU 数量 (每个副本)", - "nGPUPerWorker": "每个 Worker 上的 GPU 数量", - "nGpuLayers": "GPU 层数", - "replica": "副本", - "optionalConfigurations": "可选配置", - "modelUID.optional": "(可选) 模型 UID,默认是模型名称", - "requestLimits.optional": "(可选) 请求限制,模型的请求限制数,默认值为无", - "workerIp.optional": "(可选) 工作节点 IP,在分布式场景中选择一个或多个工作节点 IP", - "workerIp": "工作节点 IP,在分布式场景中指定模型所在的工作节点 IP", - "loadingWorkerNodes": "正在加载工作节点...", - "workerNodesLoadFailed": "工作节点加载失败。", - "noWorkerNodesAvailable": "当前没有可用的工作节点。", - "noAvailableGpuWorkers": "当前设备设置下没有可用的 GPU 工作节点。", - "workerNodesUnavailableForValidation": "暂时无法校验工作节点,请等待工作节点列表加载完成或清空当前选择。", - "invalidWorkerSelection": "当前选择的工作节点与设备设置不匹配。", - "gpuIdxNotAllowedForCpu": "设备为 CPU 时不允许填写 GPU 索引。", - "gpuIdxMustMatchReplica": "GPU 索引数量必须是副本数的整数倍。", - "fixFieldErrorsBeforeLaunch": "请先修正表单中的错误后再部署。", - "workerCount.optional": "(可选) Worker 数量", - "GPUIdx.optional": "(可选) GPU 索引,指定模型所在的 GPU 索引", - "GPUIdx": "GPU 索引,指定模型所在的 GPU 索引", - "downloadHub.optional": "(可选) 下载中心", - "modelPath.optional": "(可选) 模型路径,对于 PyTorch,提供模型目录;对于 GGML/GGUF,提供模型文件路径。", - "GGUFQuantization.optional": "(可选) GGUF量化格式,对Transformer部分进行量化。", - "GGUFModelPath.optional": "(可选) GGUF模型路径,应为以 .gguf 结尾的文件。", - "lightningVersions.optional": "(可选) 蒸馏版本", - "lightningModelPath.optional": "(可选) 蒸馏lora路径", - "enableThinking": "开启思考模式", - "parsingReasoningContent": "解析推理内容", - "CPUOffload": "CPU卸载", - "CPUOffload.tip": "将模型卸载到CPU。当资源有限或使用GGUF选项时,建议启用此功能。", - "loraConfig": "Lora 配置", - "loraModelConfig": "Lora 模型配置", - "virtualEnvConfig": "虚拟空间配置", - "modelVirtualEnv": "模型虚拟空间", - "virtualEnvPackage": "虚拟空间安装包", - "envVariable": "环境变量", - "envVariableConfig": "环境变量配置", - "additionalQuantizationParametersForInferenceEngine": "传递给推理引擎的量化参数", - "additionalParametersForInferenceEngine": "传递给推理引擎的附加参数", - "enterIntegerGreaterThanZero": "请输入大于 0 的整数。", - "enterCommaSeparatedNumbers": "请输入以逗号分隔的数字数据,例如:0,1,2", - "device": "设备", - "loraLoadKwargsForImageModel": "图像模型的 Lora 加载参数", - "loraFuseKwargsForImageModel": "图像模型的 Lora 融合参数", - "launch": "启动", - "launchCompletedWithAutostart": "模型部署完成,并已设为开机自启", - "autostartSaveFailed": "模型已启动,但保存开机自启配置失败", - "saveAutostart": "启动成功后设为开机自启", - "goBack": "返回", - "copyJson": "复制 JSON", - "cancel": "取消", - "confirm": "确定", - "placeholderTip": "请输入", - "fillCompleteParametersBeforeAdding": "请在添加之前填写完整的参数!", - "model_format": "模型格式", - "model_size_in_billions": "模型大小(以十亿为单位)", - "quantizations": "量化方式", - "real_path": "真实路径", - "path": "路径", - "ipAddress": "IP 地址", - "operation": "操作", - "copyRealPath": "复制真实路径", - "copyPath": "复制路径", - "noCacheForNow": "当前没有缓存!", - "confirmDeleteCacheFiles": "确认删除缓存文件吗?此操作无法恢复。", - "confirmDeleteVirtualEnv": "确认删除虚拟环境吗?此操作无法恢复。", - "commandLineTip": "请确定模型名称是否一致。", - "featured": "推荐和收藏", - "all": "全部", - "cancelledSuccessfully": "取消成功!", - "mustBeUnique": "{{key}} 必须唯一", - "update": "更新", - "launchProgress": "启动进度", - "initializing": "初始化中...", - "moreDetails": "更多详情" - }, - "modelReplicaDetails": { - "title": "模型副本详情", - "modelUid": "模型 UID", - "replicaId": "副本 ID", - "workerAddress": "工作节点地址", - "status": "状态", - "createdTime": "创建时间", - "actions": "操作", - "noReplicaInfo": "暂无副本信息", - "errors": "错误", - "replica": "副本", - "remove": "移除", - "removeConfirm": "确认移除模型 {{modelUid}} 的副本 {{replicaId}} 吗?", - "close": "关闭" - }, - "runningModels": { - "name": "名称", - "address": "地址", - "gpuIndexes": "GPU 索引", - "size": "大小", - "quantization": "量化", - "replica": "副本", - "actions": "操作", - "noRunningModels": "没有运行中的模型", - "noRunningModelsMatches": "没有匹配的运行模型", - "copy": "复制", - "copied": "已复制!", - "copyFailed": "复制失败", - "viewDetails": "查看详情", - "autostartEnabled": "已配置开机自启", - "removeAutostartSuccess": "已移除 {{modelUid}} 的开机自启", - "removeAutostartFailed": "移除开机自启失败", - "terminateModel": "终止模型", - "terminateInProgress": "正在终止…", - "terminateConfirmTitle": "确定要终止该模型?", - "terminateConfirmBody": "当前模型共有 {{replica}} 个副本。集群繁忙或副本较多时,终止操作可能需要数分钟;总耗时取决于最慢的 Worker 节点。请勿重复点击终止。", - "terminateConfirmOk": "终止", - "terminateErrorHint": "请求失败或模型可能已删除,请刷新运行中模型列表确认。" - }, - "registerModel": { - "modelName": "模型名称", - "modelDescription": "模型描述(可选)", - "contextLength": "上下文长度", - "dimensions": "维度", - "maxTokens": "最大 token 数", - "modelPath": "模型路径", - "modelLanguages": "模型语言", - "languages": "语言", - "multilingual": "多语言", - "modelAbilities": "模型能力", - "modelFamily": "模型系列", - "chatTemplate": "聊天模板", - "test": "测试", - "testResult": "测试结果", - "noTestResults": "没有测试结果...", - "stopTokenIds": "停止token ID", - "stop": "停止", - "reasoningStartTag": "推理开始标签", - "reasoningEndTag": "推理结束标签", - "toolParser": "工具解析器", - "launcher": "启动器", - "launcherArguments": "启动器参数(可选)", - "edit": "编辑", - "cancel": "取消", - "registerModel": "注册模型", - "messagesExample": "消息示例", - "JSONFormat": "JSON 格式", - "modelSpecs": "模型规格", - "modelSizeBillions": "模型大小(以十亿为单位)", - "quantization": "量化", - "quantizationOptional": "量化(可选)", - "delete": "删除", - "controlnet": "控制网", - "packages": "虚拟环境安装包", - "more": "更多", - "modelFormat": "模型格式", - "enterNumberGreaterThanZero": "请输入大于 0 的数字。", - "carefulQuantizationForModelRegistration": "对于 GPTQ/AWQ/FP8/MLX 模型,请小心填写与您要注册的模型对应的量化方式。", - "quantizationCannotBeEmpty": "量化方式不能为空。", - "enterInteger": "请输入一个整数。", - "enterIntegerGreaterThanZero": "请输入大于 0 的整数。", - "showCustomJsonConfig": "显示由 API 使用的自定义 JSON 配置", - "packUp": "收起", - "unfold": "展开", - "copyAll": "复制全部", - "alphanumericWithHyphensUnderscores": "字母数字字符,连字符和下划线应正确放置。不能与任何内置模型名称匹配。", - "chooseBuiltInOrCustomModel": "您可以选择内置模型或输入自定义模型。", - "chooseOnlyBuiltInModel": "您只能从内置模型中选择。", - "provideModelDirectoryPath": "提供模型目录路径。", - "provideModelLauncher": "提供模型启动器。", - "jsonArgumentsForLauncher": "一个 JSON 格式的字典,表示传递给启动器的参数。", - "provideModelDirectoryOrFilePath": "对于 PyTorch,提供模型目录。对于 GGUF,提供模型文件路径。", - "ensureChatTemplatePassesTest": "请确保通过点击右侧的测试按钮,使此聊天模板通过测试。请注意,此测试可能无法涵盖所有情况,只会用于最基本的情况。", - "testFailurePreventsChatWorking": "请注意,未通过测试可能会导致聊天无法正常工作。", - "stopControlForChatModels": "整数类型,用于控制聊天模型的停止。", - "stopControlStringForChatModels": "字符串类型,用于控制聊天模型的停止。", - "enterJsonFormattedDictionary": "请输入 JSON 格式的字典。", - "autoFill": "自动填充", - "fillInModelPathFirst": "请先填写模型路径", - "fillInModelFamilyFirst": "请先选择模型系列" - }, - "clusterInfo": { - "supervisor": "主管", - "workers": "工作节点", - "workerDetails": "工作节点详情", - "count": "数量", - "cpuInfo": "CPU 信息", - "usage": "使用率:", - "total": "总计", - "cpuMemoryInfo": "CPU 内存信息", - "version": "版本", - "release": "发布:", - "commit": "提交:", - "gpuInfo": "GPU 信息", - "gpuMemoryInfo": "GPU 内存信息", - "address": "地址", - "item": "项", - "value": "值", - "nodeType": "节点类型", - "cpuUsage": "CPU 使用率", - "cpuTotal": "CPU 总数", - "memUsage": "内存用量", - "memTotal": "内存总量", - "gpuCount": "GPU 数量", - "gpuLoad": "GPU 负载", - "gpuMemUsage": "GPU 内存用量", - "gpuMemTotal": "GPU 内存总量", - "worker": "工作节点" - }, - "components": { - "suggestsCommonParameters": "提示常用参数,也允许输入其他参数", - "warning": "警告", - "ok": "确定", - "cancel": "取消" - }, - "monitoring": { - "notConfigured": "监控未配置。", - "time": { - "5m": "最近 5 分钟", - "15m": "最近 15 分钟", - "30m": "最近 30 分钟", - "1h": "最近 1 小时", - "3h": "最近 3 小时", - "6h": "最近 6 小时", - "12h": "最近 12 小时", - "24h": "最近 24 小时", - "7d": "最近 7 天", - "2d": "最近 2 天" - }, - "refresh": { - "off": "关闭", - "10s": "10秒", - "30s": "30秒", - "1m": "1分钟", - "5m": "5分钟" - }, - "absoluteRange": "绝对时间范围", - "from": "开始", - "to": "结束", - "applyTimeRange": "应用时间范围", - "manualRefresh": "刷新仪表板", - "tab": { - "overview": "概览", - "modelLoad": "模型负载", - "llmSlo": "LLM SLO", - "gpu": "GPU", - "host": "主机", - "security": "安全" - }, - "config": { - "title": "监控配置", - "grafanaUrl": "Grafana URL", - "datasource": "数据源名称", - "alertDatasource": "告警数据源名称", - "alertDatasourceHint": "留空则使用主数据源", - "clusterName": "集群名称", - "dashboardUid": "看板 UID", - "dashboardOverview": "集群概览", - "dashboardModelLoad": "模型负载", - "dashboardLlmSlo": "LLM SLO", - "dashboardGpu": "GPU 资源", - "dashboardHost": "主机资源", - "dashboardSecurity": "安全审计", - "save": "保存", - "saving": "保存中...", - "cancel": "取消", - "reset": "恢复默认", - "openConfig": "打开配置", - "sourceDb": "数据库", - "sourceEnv": "环境变量", - "sourceDefault": "默认值", - "healthCheckFailed": "Grafana 连通性检测失败", - "saved": "配置已保存", - "saveFailed": "保存配置失败", - "loadFailed": "加载配置失败", - "resetDone": "配置已恢复为默认值", - "checking": "检测中..." - }, - "configHint": "点击上方设置按钮或下方按钮配置 Grafana。" - }, - "logs": { - "notConfigured": "日志查询未配置,请设置 XINFERENCE_ES_URL 环境变量。", - "searchPlaceholder": "搜索日志...", - "allNodes": "全部节点", - "logLevel": "日志级别", - "nodeType": "节点类型", - "time": "时间", - "level": "级别", - "node": "节点", - "message": "消息", - "fullMessage": "完整消息", - "noLogs": "未找到日志", - "refresh": "刷新", - "totalHits": "共 {{count}} 条", - "prevPage": "上一页", - "nextPage": "下一页", - "detail": { - "module": "模块", - "pid": "进程 ID", - "request_id": "请求 ID", - "address": "地址", - "log_type": "日志类型", - "rtf_avg": "RTF 均值", - "time_speech": "语音时长", - "time_escape": "处理耗时", - "tableTab": "表格", - "jsonTab": "JSON", - "action": "操作", - "field": "字段", - "value": "值", - "filterFor": "筛选该值", - "filterOut": "排除该值", - "copyJson": "复制 JSON", - "copied": "已复制!", - "viewContext": "查看周围文档", - "contextTitle": "周围文档", - "loadNewer": "加载", - "loadOlder": "加载", - "newerDocs": "newer documents", - "olderDocs": "older documents", - "anchorRow": "当前文档", - "contextError": "该功能需要更新后端版本。", - "contextFetchError": "加载周围文档失败。" - } - }, - "userManagement": { - "title": "用户管理", - "createUser": "创建用户", - "id": "ID", - "username": "用户名", - "source": "来源", - "status": "状态", - "permissions": "权限", - "actions": "操作", - "active": "启用", - "disabled": "禁用", - "dialogTitle": "创建用户", - "usernameLabel": "用户名", - "passwordLabel": "密码", - "permissionsLabel": "权限(逗号分隔)", - "permissionsHelperText": "如: models:list, models:read, keys:create", - "cancel": "取消", - "create": "创建", - "confirmDelete": "确定删除用户", - "selectAll": "全选", - "editPermissions": "编辑权限", - "editPermissionsTitle": "编辑权限", - "save": "保存", - "changePassword": "修改密码", - "changePasswordTitle": "修改密码", - "newPassword": "新密码", - "confirmPassword": "确认密码", - "passwordMismatch": "两次输入的密码不一致", - "passwordTooShort": "密码至少需要8个字符", - "changePasswordSuccess": "密码修改成功" - }, - "permissions": { - "admin": "管理员", - "models_list": "查看模型列表", - "models_read": "读取模型信息", - "models_write": "启动/停止模型", - "keys_create": "创建 API Key", - "keys_manage": "管理 API Key", - "users_manage": "管理用户", - "cache_list": "查看缓存", - "cache_delete": "删除缓存", - "virtualenv_list": "查看虚拟环境", - "virtualenv_delete": "删除虚拟环境", - "models_register": "注册/注销模型", - "logs_list": "查看日志", - "monitor_view": "查看监控" - }, - "apikeyManagement": { - "title": "API Key 管理", - "createKey": "创建 Key", - "id": "ID", - "name": "名称", - "prefix": "前缀", - "status": "状态", - "expires": "过期时间", - "modelPermissions": "模型权限", - "actions": "操作", - "active": "启用", - "disabled": "禁用", - "revealTooltip": "查看密钥", - "disableTooltip": "禁用", - "enableTooltip": "启用", - "deleteTooltip": "删除", - "keyCreatedTitle": "Key 已创建", - "createKeyTitle": "创建 API Key", - "saveKeyWarning": "请立即保存此密钥,之后将无法再次查看。", - "nameLabel": "名称(可选)", - "ownerLabel": "所属用户", - "ownerHelperText": "不选择则归属当前用户", - "owner": "所属用户", - "expiresLabel": "过期日期(可选)", - "expiresHelperText": "不选择表示永不过期", - "permissionType": "权限类型", - "allModels": "所有模型", - "byModelType": "按模型类型", - "byModelId": "按模型 ID", - "permissionValues": "权限值(逗号分隔)", - "modelTypeHelper": "如: LLM, embedding, rerank", - "modelIdHelper": "如: qwen2-72b, bge-m3", - "close": "关闭", - "cancel": "取消", - "create": "创建", - "save": "保存", - "revealTitle": "API Key", - "confirmDelete": "确定删除 API Key", - "copy": "复制", - "copied": "已复制到剪贴板", - "editPermTooltip": "编辑权限", - "editPermTitle": "编辑模型权限 —", - "editKeyTitle": "编辑 API Key —", - "mixedMode": "按类型 + 按实例(混合)", - "modelInstances": "模型实例", - "permissionsSaved": "权限已保存", - "bans": "封禁数", - "description": "申请理由", - "descriptionLabel": "申请理由(可选)", - "bannedIpsForKey": "Key #{{keyId}} 的封禁 IP", - "noActiveBans": "暂无封禁", - "remaining": "剩余: {{seconds}}秒", - "unban": "解封", - "viewBans": "查看", - "failedLoadBans": "加载封禁信息失败", - "failedUnban": "解封失败" - }, - "securitySettings": { - "title": "安全设置", - "rateLimitConfig": "频率限制配置", - "ipLayer": "IP 层", - "keyLayer": "Key 层(默认)", - "maxFailures": "最大失败次数", - "windowSeconds": "时间窗口(秒)", - "banSeconds": "封禁时长(秒)", - "saveConfig": "保存配置", - "bannedIps": "已封禁 IP", - "bannedIpsDesc": "同一 IP 使用不存在的 Key 或无效 Token 请求,在时间窗口内超过最大失败次数后自动封禁。封禁期间该 IP 的所有请求均被拒绝(封禁时长由 IP 层配置决定)", - "noBannedIps": "无封禁 IP", - "bannedKeys": "已封禁 (IP, Key) 对", - "bannedKeysDesc": "同一 IP 使用已过期或已禁用的 Key 请求,在时间窗口内超过最大失败次数后自动封禁。封禁期间仅该 IP + Key 组合被拒绝,使用其他 Key 不受影响(封禁时长由 Key 层配置决定)", - "noBannedKeys": "无封禁记录", - "ip": "IP", - "keyId": "Key ID", - "remaining": "剩余时间(秒)", - "action": "操作", - "unbanAll": "全部解禁" - }, - "auditLog": { - "title": "审计中心", - "time": "时间", - "user": "用户", - "apiKey": "API Key", - "model": "模型", - "type": "类型", - "status": "状态", - "clientIp": "客户端IP", - "modelId": "模型ID", - "modelName": "模型名称", - "endpoint": "端点", - "latency": "耗时 (ms)", - "timeFrom": "开始时间", - "timeTo": "结束时间", - "search": "查询", - "noData": "无审计记录", - "custom": "自定义", - "totalRecords": "共 {{count}} 条", - "prevPage": "上一页", - "nextPage": "下一页", - "tableTab": "表格", - "jsonTab": "JSON", - "detailField": "字段", - "detailValue": "值", - "copyJson": "复制 JSON", - "copied": "已复制", - "modelType": "模型类型", - "category": "分类", - "category_inference": "模型推理", - "category_admin": "管理操作", - "category_auth": "认证" - }, - "login": { - "or": "或", - "sso": "SSO 登录" - } -} diff --git a/xinference/ui/web/ui/src/media/icon.png b/xinference/ui/web/ui/src/media/icon.png deleted file mode 100644 index 059f5f63e43493acaee731b9be0d333261335938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23192 zcmeFZ2{@E(|1dl=rVNTfl8~{J-Po5g_Od2r$-a}_*w-N>vXphm61Oc`DlJGTTa0~6 z))qrUR7ke^PTgD2^WM+*|9|iMz29-X$MM}Aadlni?_7TScHY;{8E7A+K1mIMK#rb0 zqj4Srfo>f9MH~iiddKGy!7nK8ytW#orl0Kt_{SF~v$M|n`jFG$83Cb$GC(K}hJZg1 z=t;<-pU)78J(TsY=gUxmKgPho7zqgY3E>2P{h*RRpO1m(jH_-C_#dzp;P=6!@WGEi zf2%rr+dHAoxqAD1<6OOcP?EBuQYZm^I|nzfgExW@h@`lrjDk2?K@yD;ms60GRFIa0 zK;UWczt)&7g8seNBG{knK{tvh{(e4K`Oldo&?pIM1u&VEG~|3lj4}8`<#Way2Z4xk zAN+*|m#PFpAoQ2rE|~e7>FX&tczcT49c)xI*wg1=CWun70(kUv^0z|;dwO``6oQqx zevVK8&j+u?xKKZb_`54}ndzTHseAi5p=3nGMa8)=)F>26$6$%3QAg z{yqv~VnIPcqCsd;Z$B3?33+*WF>y&TNl6hfLIfA$eUd-t(Qv{!___J` zyLo$|4(7G9_YUw^=Hfb7=&%2N-=|Zs+utjB;r=)lIH1_U7cmJ@aj|~_b9DG?dp-ev z9zQqd=pg3g;pFM$<&Oh!68{JXkfg8w7wEsN7i{PAb2(4Xe}u&OYX*Wd{DG5ygv4D4 z@o^G6?}YOX@N;m|3-#hV%FK3;E@w;JiP@$k@sEU*G=u!NcvRIQZE4;hYY5MVaeQ zX8B8g{t}M^n4dhSfb(|t53=)fQgs0gh54@(l#!O2-x-a$^%?$6nO0sqfy*f|{N6O4nOlbyelHVA^yKgI(u0Ow79grortUiAefXi zT3p25(Lq8)!d^;7+CfIrNnHLf{Qo~89nLQB|0f)+L(JAh^W5?KX#X$MCc2`M=dDG5mj5j!U-@IxBJBvN)x z60(v~lCttnQhy%km&yLeg?<+}tphc2;4}Q!&KYo=fJ3g}{lAKg|2WOxd;DF_4_5ny zEB^Gb{=3@#-@yNAc7WXfIfDLvhF`${p8YT6|Bc{ZysfRfoJUzaG>!odb#;yB$dSe>Gi)u0S*Uz{nJojB>n*T_1(XZH~V`T4En%b{<+An zZ~q;_{2w8HeftXpIHiKVx1*bLhz4+a|8mp+K{Nf^$bXwd{ioCXFLV5ZtA8-ZFC+hH z4sX8;-rgSnjUeQ&x&DCox5@NDO2X03-|k)2oB`CAwK3@!nloG@r5v448~ z2h{IM@0aYvPlo*cEy#Ufr~%LZnMc7;Cj>HXLm*hlSq;?-!O)NSVRcqx5pxr-O`jT} zEMEp%zAX|mzj+j~?h~h{^a>g~<5qTbi#qLk$Rtw5exlD&l0f_|{e#{Qw{)48{wJ@5 zaP#QgP-HRee8_X;o-rIV;{8=7d z6!F!edTwofYAbThTRHPB1r&jWz>s(d90mFRAOBl;VBjjU+G+gS!`_l37*Y9hbV_u2 zvq7|ELzgnp=11Ltj6EyBWpqqyqfnrSxOrgdILXX6B}$QMDPE!8du^OO-}H{+gS(Bz zin{&v)(#mvhC1K7%Fkkj9z@J!D$YKPT6?5|r#c`3A9IJ{Gqoo;$¬?x-{=XdYp?v)xmt$|C(ReZo4T zF)F%8Gh#oJ?niD^nH@bGl|~H}B6VdpXbP@>xDZY|V+fxaK+M`oKDb5-Qn_;FA~GQ# z%SpOaHRZ4+&G!T8Z&TtnDzh^hag;Vt6=e-umR;LBr=FLGT>oT$y=a#mt*GqCZTxzV zmSJ2KbsQ#xmeqQ4^+y-V;(I~3=4$HiOLmwboi*V!y)*7xzIa(v|`0JgkQOd}42}T$afyauHhFxlq z>yYBHISqKT3P){?40E9PA~)GO?vMitDGbilSLwDvpk!?iiRWHgw~h4?n0hxOyskE2 z6SdGkhiJ3*h=suSc+MrrmrU+o9}qC%Tq-$Nwap?#K3d(cIqFUeA5%x2gKhiOT#BHU zpp(KY6SW4z@SpeVnF1!`zD6W8uHAT!L44C}O>Dpv?4K5D-Db*`ysJ9cTV!U+a{rkm zA=K(qB{S>|eO=$mof{EZ4<}zF&7h8RFI_qJ<=d&;Ib~YfGSyb@12mbxd(h`AcZwxm zu#_G3hymQYFpHuc_Hy59^}#OQrI+hpDaT}5(4~Fp zc-zBpCC)TDd@qr?ovkTDsxW~{j>+G%{;qI$`DvJp@qqt3Sk|@bMDYbRlrU@?BKMN$ zR8sC~XP)w~1nF~nNsG07Ga1IS;gZO-fZQD9zP67%k&0(pCoT=>3ObVB-9AEcD~IXE zuacU(cVDi=i{=GI4(TV4!k~z68bv4i3K@TrOHO%tth; z+^ZPBNvdbkXui~wK?_}kQ%htgs=RyZcX}fc60>?y?zBu9a#JWMyz*_Xz$qBg2a96H zm0|=ha*}9+cdZWr4vp=3G?3VsKOA3?t)KM;HJ^dCAU@o_HIi6Kw16QRAK$JVtz-2s z6LloK(qS={gP-Oe^m5iF3OTUZw;@6kjD*^po91J!_>LQiLHRVXt(?)1az==&X`v@B zaxU4mS276EZ|c;Y7XW~1-u1bI<@=|E z7n+S#`PFSsvu#?5X++FiRE&Ip5vpK;Aq>m)N0X9#0RU_peUqWwIbhsyhv z0w&&9iUq)`E8Pm2X#q+sG`qxGO!NU zz#XDHjp{Kb?j@txp=*q?@0;p@PSxapXha2=GHr_>gk!ZYIMXWRKLU_irx$m_-+1F_ zPX%3#`smDHS=JJjl=cI|=}x8fCH0T(s^u}O?cAp;bMfqVAJ7}soZ|H;=|zhqKO#gT%EiKvgzu#^HQhYAmFEY(vlj^7iOGBu2ajG zU#d4&bvb95QEQIdP%J*>9bD25xW<=bBW*>DZj?_>7pw1BpM9xXciJ#(+tvhm(8*eoR(}dvF!aj}}W7JQTn` ze__zgZ|zj9S-%W(r}*N7&C9~{9jU%RFWvH@fqTw_DYi=Rcph6cZmb*AOYNf`^X}_CpvyMyRhQ!H5Uv4LlA-KJ*4~QEaJKrM3p0%)$pheR%6DQoUl{W`b6vktj{@cJ)~V}6cO+J z*jTlkPI-^nnTJkel=V`6Qbnpp>QxvD@S5y>v4qONbuJ9DA`X8rtU2pMn30>rxs(vH zbu0z94i7#j8l~^3 zJV4p8WFNbGIdO-SZ==^{9)A5QFafMR)A2c7j3Z`Bs)G*K9CIS2wv4q$UtG72F_|J- z%JO*`2PPlFAU|CP%FZ0iAl3C%#mn+)1^=DgbIm2lHrC-Z9s_>21`?-|@PCLp^P2_wY*CL}8Q5`4x_ zZImM1f-P^_^2v)^1EQWOZTyz`eMF}TDMGFmI_!C^s$fm;n%LqF`RViR->8kUaW(}} z1rCT~@I0qi8rK{=rnrn)6i#sZ~k4_(Byx2uGtRnF#FD(a>tkjDzKd8)%n1yVRMm9+myBxJ? zBDa*kE!pHhyxcp`{iUY%(QH%NOk3bpAZ@z3yUhU!4FMxGs*mIAHTIb_W`^fSGVvzN zJs}#+LTmS)$W?iu?jt1N-nbCpfQ?INRK0o zYBKHU58YTXoL5_%w&iG_R`{4%WN{_8II@rak2Mk$BFI)ReeOHL zG|N&dvX96Vzdi73XKYN-yWttLRE^TKMui+)DNXcs5qTz~{HEUKA}#(uil>xsUBR-z zk(-hNT9@LDwsM54oFJC6#n#k~(#MR}j*Is9@!M)DkB~U{O!W)7*LscDYkiMIOH!f8 zPQ%xK6Q;*)vu_m95kgc)EmR*L<|1q6e0wYljffVW`@~Q@n};;*;k4C^=pcVskYrqx zF00RcA@%C~CHrT0(&n!ExCj|gXw7Wnd1L$eC5}rH()%=yZ7^KvIF1I505stuXTb`25eXGl+(IS;w~{NwR1Ij^dX)x#UzI8?c3XP0Z;V z96;jzYV=!a&2lwIr67W1MhP{&a%DXvk+?R?8wb2|q=W!ICsOg}F#3k{c0jC|= z^Ah}I9s?SudNNMH^ zdd|G^snLK{>+L)4jOxZ-GBz?HE>BB)UU+=vxc{=h@o4#EspqIHDtS?+?wj7p=$fhC zacqO}iGAxJ9xbpWJNQr)uW3D=p zAMSq*`?97U0J+q+#;-fFJ4H0EO~EnoGTWchDcrU{Y=meGxFdfqMK8h^zl|xx-xVky zP4ZZhETrnXh^*^d+g94tYvx>-s>}#i;zu^-SUep95b>lS-DpD<*iGpOY)#7(zsscN ztF)`3_ve}|ue8d+zmT>rS{P)TsApYcr~K`TivvKF;Az#zv`ob{53@+30oRnfC}HbB z;9XQUw>9Ky60uc=5g}QGLY?&{PtLdRSfJH?6i1bP4HF_rNk&@yOXF=>6)inWTODsm zVX6SbEhxgyCCSYg>K`VmK-OmlHAxSeUx%*Usfd@bW1vw zWD2J}oV>ar{7lt%26C)eG=lu)Dhq3)KM1KC)J6%zSvz^>ntvpOZe9-?pWluoDStfm zNo|8AwC%Pad1ct-)BKzP%w!bp`Q6TMY(rl1@Vm->MLCLSKg6-({-rIyVA=~h@9n)< zc!0c^Ys{RVA1TD*H03p#Rd{Ps3;{CO_fslT2mD?#Fd%WgC_#XB3nQ21i@Gs}-Y`iU zvt@OU=GQ;<#kmB9q=AeV58MT>B{Xa*%Y&oKme&vMd6|Fua28)}8dm&9jR3z}QER3g zk-JB~U6ug^!RfjF8KTG|9)JOZvY(9KdYCXC=-5FfJor^Tpw4!Vr1v@5r|NJnrdT5B z`svT;5v$+5q;3qDbtX%-STKa|AmuoW*3_@+meRW(%}~6UJC~|^drho*{uqtUIihDy z`f-06h|%L?--K0LWv=uOmp_B^il*up@sa~o0yH8ta<_{mZuFyVsLy_h@q!MOKO1#_ z9>9q$RH%(+geB}Oo9tIZ6A`w!$9axIC(=((|OUDSEIT~=YJ|08CPzFTRNN6k7l zy*k>D|E0az(R+B(7W8=YX%l0TsqSqJws%676h zJ1pw`|67LxqRlV8eSh;ZZ!ifmdOi5f((Bd#=icLTkXJ+sU zb658@vm73qgnhPoXE>_mPgTGmj;u(;?+tzPC$lyl>suLEeYR?G(UfJaw>%>RbR62 zc`Q9&+M*S|mBWoH_Nw2J=v%{`k-HO*z(k6kSvx=3ObGQ?ClBWeQN- zv62i3nJ^1?hQ|)6*he*xiF>gjS9@N^nKN)^qV;jD{1bfv(w*jOW~g`eOOIOz+9iYtYS3?-7w>0ME8JnDNeN}>MsH?TJ$kx3*rwewu`Vi# zwbg?K7Tvll5R~Xh?kW`!(^URx)Ip$ye)UBz27`H#!q7dcnC4TQ-nu=!7nuV#cEqKJ zcaUtnb$--bs%+Yfduic|M|Nk%BN=MiP)6G#OK%xV!5jG0;*^~16Z0lUh|q1lDPAtJ z=P|YozQJRgl^<-^RnCuo`XA12su zF!Z)-u~^jJx(rm?OD}QW_3vj8lNHnaBez z_%KD#^HLsV{m_;Kq~_+Jq(IHdyZNQZi$zUSdZM!ZXWLj1-HCoW&E2A&PpK|40;h<- zmpa~C$13o&(*j2xftxgD&!=9SwH7lBm@ZZ?0($%z5bq#2hvl<lZt}*n&z~=EBNw zf>|CxcB5U{qyD_P+JcdNQ|cN7@S8*iB-f2Um_8QKD2+-a zvPp=sdum4`LMd;O4b6-SZ{2d*h@Ux2>j?N2F@*+{7t`C(ADfSGs0> zK-gb@ZgwGsZOu4l377dmHx`)4LEba@FQQ<)BI~`!-M3dN?U+*~h zt%OobLNe}yN-pw7r8a}^zzo2fMa}g{&Dfdm z67pXtB{*1S%;>n59Nw`0u*;q6ayb!3wNcr1$}VcpUEfU+cS~<3F~oUvU+O_qs!+^o zL5Oy;X4!$6eo!PzeiF_2lCiG12EERByzuPzixq5G_o8VQ?rV)JxmovybQUDY7ojn; zN!Q=4_v!8Da$j-@tWwvQk@z8g$Kf+U{Oz%4nQ;|#(mVMg=iKR(Vywduq$94*KtvfebF@bfZ-@2i06?T640!DIYQ{9hJ&zJp_o!r z%uy@*BQ>TNree{sqfa^G18j_FCARpS5sk99bI|S1@O|961y!fyU*BBkU!BpkaU$z~A zIiAwXm*zq?wlJ`$yG>(nEknB33lgqcW>(OI&;Sqa)7#-1%EhjsD~U{-OjYHECVc79 zE9A3;kk6>5vTY`Dkbn>NH+z9?pyj!>#DlL0l6<3g2>yO+XhdjSkHhrn`u={Z=ahvi z(=qwO&~5G{Lj-)>dv=@CVM9cRV0hJ5OlDlow#jk%N7#?m>Zl94A1_ct5u-ZzBOn&P zV(O*cQfrA;?iKaCg4X@ifAsCTFvSAHbtO@CECRIzZ9WX}Do;%GgC6Q@uGBYj(a8(@ zGKz@Kr9v%9Q`){FzZ|{FoArL5)p7Qdt}tVs9SjkQZ}S$#yoe-2~X1f!!38bZL1s(m(GeT}7VBgT$Qj z*|UfsYo8Ec_CX5C%&ZP~Mv|G-%YqTXY7o^e9%M@WRb09a$clW(0h{$mw4~I@pX<({oQL;LY2B@3fH^J+wosUi&PhnG-zU1byH<-D z5Dq=t;sME=viePU`ys?PHT;p8>@%Z|S2u1vtMlt4+I=;y6@=Jbn7TFmD3p{B9QPlw zc9JG)C}lwHP>HoqPY9LX@)~8c(eaEpxQweOZEvSac~XUna!@We0^7qb3j$HLBHZBSO|T782)DUH#sFgGqORn!6NK5w&G3B?sn6X|p3nA6|vvO$H& zq@~1*=vp?QdAA$Z*;FC007mTKathvM^D#(J2MoM@n=Q{pCcKOcBEZPZ$?jt1y_98?`xlWAXdq^2ZT2P>X#CDm3ouYe5}HGS(F_ z)@Fb$374Fm=`f8GG-2W}*fp>gV-$3!!RAOtiD5HGX?rcpLmL@fi0sHDLlm9Q-0yPr zX#$Zux1XHMoOL$KD?`D5Jl8#yEpm0}$6}oR323wiAl9|RktZJ07@6wyu6YFvi4XXB z@4@TObDZmB%ly8vHdJ^j>gne}8-T5rd!Kvm18;tS3zWY)SRGb|+X#eU-P~D@txka> z(O7$so^OX?QkoKWwf4!RS{^*v%?sQ31dhBC4D(C@B!($yoksNl`&VUi|VMe0NXe1I0oD_B9tPHRI0})1Iny3%C^djzcMbO<~gD8 znHNQ|whYCm)H2BTh6MIYg7iG)9m|!+9iR`@Q2H?QT(5TlEby-%XLo+PyBtw_B%`V7 z`WFFiT9_nuHL!%0BlQLAQ#@7<-aYu@T4r|E&B`#Atk=mmh4;Np4Lk{H!uy2R$!!n> z58ycE8(7m1e1yJNRx zKIbU===9)uJ~#>S$#fm~c{+T9Yy#yUjKv7<2^~(!?^cGH?dR*{f8PuBfZ5@mIOYdB z!sDSc4W=sh%WmEmJO)E{1EzV3$Yc~a+%r^eEq}RC=o`@px1v;dv|R=fYXDKDQ;vy# zm0Cf`P(j^CydL>O8}sGced?+rR|JnfMAcAX&nsU{1LS198g|d;8Ie_!~8e1-lNKGhRz->rIQ%cew9;FXhTyn1+bd6|h z;0SrY@%kvBm&O?YD_+6*v2(nXSiWD6tm@>fTUl!V z!lC5*(fwUU+XE!Nl?^JnA%C1LM61X(lHYhsSbTx-BGGr@-fujJx(%T<{2T~!%MEAN zo)U@xp6b$5YE>k5 z^a^4mP3z>iKgZ1zkJXDffNJMpuL;ovX-^4quQf}&L<#+1BHz|f_vd5qMu6QW`!~PU z!gC|YWZ;{T=9y@8M6#oIs~C>dYlogq^s>sn_HGE`!r+(FB40 z3oHE5E?=#GWLSkCHrhgCD9oKkuL+Byk%C?^tys93nKMdn`n?eJc;RPh$t#naIPJNB z=ZuEo8?S7GaLjPjU@C+qR7JsZy#VhSDO=Vid2d$xPE+(i)nax)%X4$E4)7Cp>e`>o zDZ(hfdhOz>`zn#~c{7jW*^B_LL6ZDh zfK7);RXvtRR5cV{dSW362(0t@eDFn3ubX99_q;f!+Q7un4uwHt8_9=O2^Itko!l6AOA z5vqs$hoq1j_~&tzP#`rFi1TE=M|qR<>lM~cYj|$SwR2!$2EH^Y`)PAIDM^gJID-RD5_O_@W683SlH{S!V6&MH%x3oxpkflFaToL^ZL+rqV?6x$+mecLia< z(1wvlpCn*)i7KMyldu5#yb~=w9G(OBdoNwT(NW$AxFA3q^?7Fg z?TwLC(d#s4i^HqKjwIp`d3TO8xEkn>By6h*8%3qB>^&>tXA9%J%o02O@I~b;kxy%KAo{CJ6lLE)Qk3Y_mQ(efx^E>vxEND%@#}sCd%HYh z^b80Rw7vs)4`U+-gJ}o%(rtHscOm{jUo^WF0SL4wS5z+RC%OXAT`roTpp*nTfD;>F)lKqbdc8p!q@(e=C%!&uZjk_DgCX z+28uPF8**5pN=XB4r7TaAk*OI3;_Qbh?iSj19i$y5BrIF|2gP#hP0o%B>Lx z+#-7`y|N>*;rxzdyAmO7E8s$8n^M?3YvDKRxx6O`C?Z1*j{#Yg^9i6H*5Fa^ht@!) zxh(di<*%Q{w$cMnhJNW))jj(Hw@tfk-bja)XK&|<;2U$NUNvnFP&Vi7f(EkB;K1)b zzjOQ9Ob{WzP7Gmx4Zr@~n^8x3==ZJ4gRT0t`tV{7bV-YWM$@yvnM?f~Yx$e2>U zXM*0ns0HHh-#Ab8iIl9~V4`%C#%$)nG_Bb3(<lcg@wk2O-CIxvvGD2osy$bV-sg8={E z^MLDAj(L;3ApbaWB+90?ba??&+GnG*p1l0yK2R^9h3YgnzQ{CQrY6QBf+Y2zi)noL z>C24mq3<&mYl78S>KF(-o)2F{mn_^&iCo{X$Nbi1Qy|y4l6o~feu@(keG?pvmm<0P ziM>?QH_gHjk2aC6!jDJuKkh-p^0U=JXd`|Y3XeDvd{5#xi&9+m+}@{;fRTG``Hv@G}G{PkI$zLkWKcHdK7 z568pTRg~(&rc%2EueyM zP*_*rF)hq&L!QJ>Cgfi71oUct2UfFJGyv^g;zy{iP0SJx+h zd)O#1J|Z!}9{o{=5au+J$v<=Ptp3lPy-)SRR5G~I;zzPy>iXdB9Qo9w0-aR;2pt>T zTAgazy!JiFj|qmX$OATbhQ6XQQiwz_;gE@k`bfvM?p|Jp`sgS>;gHzEn4CaBb%EpE zwuRz=ly5A&Rahr7UjKm=WerH}A*$~NdGC_2TR27_qX(YKYxVhYyb?Nl!IF0usGP@3 zFDj2p(D9p?QAdY>GcL9z?E4rHrR`6J)oFh$23U{YnxGYT2~8cR z%sdl9Y@shK5yC(biM7%%GPf)BKgn8VvbPpB)VTsW#Wrp?xvbWA2IK|J-nq_&4$@Js z??J8)a>X|zmw@BCrp0>`Cj)qxo66bA3q{JjU22Pv<7>UNniAb~r{9@$$xRYx+NyrH zE5+FbVwrH`g)_pR7aKpzr2C5Bg0Ow@ZHL~g0^5j-@ReeTFB5xL?%!HwJh0B7oAaP8 z%wjfkV*Dh;rDN}Pk5EYrit2rD!zGEiD>;-b*z56FI$$8TAdGK6SP~z8uXvS`bM*vP zR;Cwp!$gt@P0{)yNT0JHhUWc9y?oh;l--MZ;>l#9KE%nGCUWj$jax!Uw`zMJVuKHC zC{JJ9^lr{nvPrw`xHBE!Wv`=SJxap%k+SxyS&9!;TY00YvNMfLw?R%R@>`&r+J4%~ z1Dx@8sj>YL&}t{Uld>Q7Ncq$im2aS#*q0Bbb1>(QM4!_}GaXAkP z8*m#J5Fo2zwlgOG#qTt6mzX@u!#Y2E$>3TB11q#$=~2R4I`|Hw?K#URjJ0*&?>eIS zNGgZcONiWu#D=gR1=WV%?2snF!@3CEr`lYfmkXdxWv5rHgwX6*=gaiiiZwvCZ^icz zlQ*jF7?5#6wNqBwL}lvu^0N0yol+ak2@U1Y=fa2!XYhPm)NiuP>zQzh(tRfa90&{N zO_bojUE9ZeCbjK{xjCou-vPcv8;~!${yUEp54hGw^sxBA(?xm1XBXWNOb2Z0myM5POh#S-qaYi6~2fz?vmwePHwcLRExM|SA^oxdZEwuHtJ zjW(anZ1rb}HKR;gAC{Rd=V{=t;pCZty<4f%VWhMC1$*xH{kzC7f#-(hu%pdM=$KWj zGr5N!=1xvZ_lQLC=W#^VldTK=F#3Y-tQ8ChRj8w@svrZS6Ru zS%}vX*d?}j_+|-1Y<zkWYN7AA6+({zcQ_azU=MXXwZ3iSKd5#&4S)Uq7?Mkl6>gm^sZ{ z?wIzf=UTWY6J~ynTS!}Iz0UDP&~6$*JN|f(S6B=^Cef(pB%ry98Yu zo~E*gl|JHypvzfn?oD1!VUdBH%$z|ACupnFh(PH%O~)2xtNOM|di<1JDT`U9dG6_~ z6QJo?tEzUi+5M92O4r6`hx-Dr)&iP3EK-oYZ$sctm(SMdm?szy{xT zT<|iM&d1mf9^OYx!mi9c*z6jh9+^Ic-vf0!@*NN^y?RSsf z8-w0q@PFeqr7A*0By>=WEI}M+dN@G+cX%hof~Dw#w8-yHEnDT)-)HSIKuFZP&PgTM%by zQFVCyGu^`pYu8nYG>`9A7#j5L-QBz4rxD3vV|HuN25}ube|~a`%c3FBnS-!{*mzHW zP|&0)xO}YvG!68|(1b^0^FYu847~I11s=)=Af;RdN*_^LJEK30V)rR-Jc(o7M5cX6 zyQE*Ulj-6@7rA*xnJ?BtC94WFf7`EC&LEI!7pHHPi(az4N9^^24Ss1Cfk7X6o zgAT2JPl5h*F}N104(Ja~V~!NI1BkCP2_dY9D4P+Wd3O!rSr8%?bXb1wa-@pB+kV+} z)OXZ?4;?%di85Y;mQA?9o0$oiMf!D&&yx(sx}?q}qKDyGK%~XKHRF+Tov58DP%X9g zEr{Y2hXEepEaF^JZ@vHc5s2~S9U;?cE9V=U8*aG=3$j=Q5S=og||yKDpTWb zUd^=EY`}Pf0v=^bvm+YEGQYvOt?56)@Yqk@=pex4E>QgXab`!O7?I@yb7LOtQlI5Tms=gz6f!v*3}vs9GdJig|W=QAU(k4#<$+cUJUK~yJeQm0Pi)O-d_xn~3JThk6H@!+=!DJJg+k}Wy8N9ThhE#s9 zc$%T;i4p|*$lB@%m8y-N#lzY8B7h zwVw}^jz;s@L#l;afj|43LoUeOGHew+$!#A=M=?(_X8HK)ptfkypB5qKTpF9CB@|bF zP)Y%+X!m zi97CvXMH!qzQh!`kaVm#?VpL{2c0s!$~8DG{gKlI&zku9oGfU1=`{x&7nhvZ#Mn*Q zQ*EY*n;)bLY98Ltk{jR?S&GZ)ZDj*Z=xKceH zKg)AASI3j^%JES17!fpRd{{pIl=49G@d*uHD?Dg#ipsqr5wZ^Zjkzvn6KhVUc0E)B z)56VT8(BFvBHoe~MV))^l(M`Nw#~kE20t0wi{x7$?ZS7L9E#S>G@5)rDoyEppcs55 z$D`62H$v<&jPB#GIiXqX6qiz@};e=aE%}t&42c83Ky9-M*o4p zWUx>_X0zgu^1y+IzXyAjOA1Sxpg_J7EvckmhhoPfdT(E8`X1UbN<7O@`_8_%Az(^< zUzHK`a=ao{Y6~q@I|rKgUyR^dnxK7G#a%Q;TiT~gMAy>#PVz1mKMUP)+~(fT$w;oq zJ}OuJr8uwrRB2J|L6AEvwUzWmec<(q+diIlrFv$-QnI-TxgLEZ1Xto2X(KO<v^&Hq2g`t$A4yw!&Ab8mHUSYC9MaL2 zqYkeIc|o@#q2Vqy55=ib5u=t!Iax_?Wnpq4+%a}m$rbcl-XWxymM$EXxO_!6-tJ5S z{L4|RS^0pOXK6uhNm_#-vgojk1d;A%&*vmE6^b;54zyCQGTfJPyW#MeW#Uswm7%v} zqn+CEO#!$v2gJoOh`n8@k>lQdw)^&=+X$q%oai^p*`~@d@(-OF_V!v%e}lgu8BKY4_qT_Mc@(_ZzY8ydfN~4E>#mP1NBEd>KR5-bt|7OHC=EH9CWch zJ&K|c0%EM({b}3TA1TxW`iFn!euSFMi^HqEZ*-orK_uiXcN%2jHhE8NP7NIoC`}RH zY5pDz_ln*sJ{4Q^SaLn}Wp5qtCuZ2X5H~&tWOF{nSoE#ANE(8h9XocBqU2|*<*UtL zAWn#cj%;TX+5^LOnHgJzK_80!=7t{&&sMJgq}6!Qj+U1hYK~IS7ORwnjg_zF7l9a*gtU1%Dit+rHYfZt8wWx= zSLZDe$v3YKYFo{x*M^O@t#H+yA7Qp+YO4pq=QX89NMaL zz0T2wm`n^`9;+mzBRA7ZmXbeO>$$CK4T4-4$Bj?n&-0LW2{v$W1;}&MDxtx~j%xCx zhVuKR5SOrz#j9~ei+wA7$tIW&Rte(WG_XJw+)Lt`2C*5TeL)LFHi~=T<#L&6^Yx)- zBo5pQ4bYC++2;YbRlYVnqmTe~76~)Z@$9#`AqZL=ICCHFp3AG4IK32tZW_w_ZD5b| zS{)CyX224gkLYG-F;OgBD4S)VBn%&S%E*@wsFWmWhLk^hcUPxX=?iGb^v{$TYF| zBX}TzX=a+vWqMbqy{^A@m{3R{N>BTq!G0I;kh?2d+tW~#PH3X_P22P|?U~ju3`x6} z^xRd5Jgl~nbH9rIOEeaBaC7N(pW^obzLLq8M2Zl_%i<$40X?JjP3F*=!{076;6XcJ zY2UkH>EMY2mlR)qa1&*Guv{{CW<<7);(-Ta`CgC;p@FikHTD*^YI}bwK|xFdaWD#j zt-Hqu8?Gk+i6n&R?^QnHkEQ?>U+m6ki^z|e$#p(aZ0kX|PpNulHkMT5Mt6h2|AQ}> z=HU9o2gyU=HmvuRSi8;ZepeMi*|A%!Tkk7+uK8mgZc#1<9|cd;1NAsD8M9FyY}&1%$w zt}&QS{a6g#^n0cOQ`F*4+p1*UmlNtq?o2Je16o&1Uu2#S1H?S&MLu`XHyhUOYL2)@ z_ec5SiobB(e#!=+oN*1V)W=+CL}I>Mn$okH z-B#f=HrzZ~G2snww*Ede?iF?WL;Mc4{VC4`-@BC1yh0%7A*ufX zW62tpXdFTDX(};vcCUXa$olYAkkr3gXIw!oVaVC@O%9YXHkzh;l{QuJz5}m7nera} zd8{f#LhQ^ZF?jC5+15cR+M0?IfKjHUS3H*y873BJRQUSI!Qv_&eBJe#ei9Z867Qdg z!Nuu#DZ!Ik4}$#OfFv1gdnw52l<~@Nr-#vL1O!6aeDMDQU^N2m4b5s#1drv5o#Zwi z$#E%AtN-lF23muY!O%$ZyL0a+Bf&l*{hy3yV`pOpfF;On7UL6DE7C7&E^NH1pZE=1 z&u21b&zobS;`( z3MU#+uy3%eUTL)l2(sr2x6yz|*uZ0JkrlC6jNwd$@_9M;7E?93@Bddj=l%|L7RT{s z`pRXDaT~NM<64`tavPRmMhxpxT9@o%Vuy7dQX-d;L1tovtrZf3hZJ%vW!%EZ)?&wH zANOm;gm}cT4B9h(+`nP}gY%s4=bZ03=lyzpEM+$SA)B%34OcRL-R$39(*W+C(;2yn zky487wTVzL(ieDutj5ts0rwzJwq$1OJblo9i(4d@uaZJb@|%4(H2&oNq9cwJFC@{q*_eEEd~VP zxh3L$;&*M^9%ZMyxx=18+43-&EZ{aZ@ebu;5U$93>-yhDpATwoDnoV{GXpaG8=v3; z=e+63dQ=q=!aZlWdWY?&b?{7qXF2nu24siHya+@f|BYC2U3DEe0Z?B_uTpYQmUm(? zP8P!2bMG+Y?{vhrn3RT6>RN z_oVL-1fWlLnq*cV>K=MN%L>OrW*Sb*1KF#|ydrAOhXU{_R}f7x9Mk&VEujKwfj-ZQ z0E1BGQ>1dw~Rm=-W+}7Ng^Z6#6WuGQ?hH zqwY?OYeDOuEB<{FS4kp3zjr!HYbe*>Y0-OQt_b=99D7t75}axR@MppYA2G-V6Ba)_ z9}f0CMRqNc2-r#<8OCVLxYVu%2sm%W!mQshDr9Su%bdM(QNotGl;+R01N-to>tEFS zLPaUFA?1!Dqz#u&oL@T}8I|`jqS-v);HE(-u0<+TVUX+JQ z;!1WD`US<`WcYLq;B)5GxIIJsVNQk3+!x6(2{3sCHO?(Rgv(jwDqX{~oEaZ|XhJU2 zt@*fJZgtj^CjZr9A~Y%TQDU*iA~O=n0 zx~Dn=qnSBl2X=L;;!flwiE9e`0l+^!RpLyb0~cxd2|&H;IFH>QJMr@Ir<-(^sC+QT zjOFcf8iHdov26#nhrqZW&S40j64E?E29hyN7nknQYSd&@*}D=Lr;C8s%GL;;09cg~lK>-f zsgikdZYdr>P$5R58%zd7VFHjPAv$;5d!8MT(B9^lHq`> zWU2E=UG^MLY~*jbv1oZF4POV1^{z7GQFF)f+!k@UUsfDX=|XVn03omJyAf+{`;wY{ zSOsi9BrB0~TWXR@fRBmL^tNfUFWe!YF&{){U{6j;u-#6^yl=#&VCJWi;pai7Rsb9y z>^Gz25Z-`Xe+R;lH(7UE!DW|Xi7U!jsz?t#ru;%{l8d~TD{_kwVTujfE-}YGMIr}{ zcb8W##@!lwM9{0MtZ68K}ai|fFFVS zT6VJPr`}DOM=qzAjMh0{2$27(K)N9ydDd?!c5j-;dfva3U-)%(SCF>8URb}7y4uAr zeYX?|+!6`p)CGkH)9(f2!W8o1ZO2{2|Gi { - const [authority, setAuthority] = useState(true) - - const navigate = useNavigate() - const { endPoint } = useContext(ApiContext) - - useEffect(() => { - fetch(endPoint + '/v1/cluster/auth', { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }).then((res) => { - if (res.ok) { - res.json().then((data) => { - setAuthority(data.auth) - sessionStorage.setItem('auth', String(data.auth)) // sessionStorage only can set string value - }) - } - }) - }, []) - - useEffect(() => { - if (!authority) navigate('/launch_model/llm') - }, [authority]) - - return -} - -const routes = [ - { - path: '/', - element: , - children: [ - { - path: '/', - element: , - }, - { - path: 'launch_model/:Modeltype/:subType?', - element: , - }, - { - path: 'running_models/:runningModelType', - element: , - }, - { - path: 'register_model/:registerModelType/:model_name?', - element: , - }, - { - path: 'cluster_info', - element: ( - - - - ), - }, - { - path: 'monitoring', - element: ( - - - - ), - }, - { - path: 'logs', - element: ( - - - - ), - }, - { - path: 'user_management', - element: ( - - - - ), - }, - { - path: 'apikey_management', - element: ( - - - - ), - }, - { - path: 'security_settings', - element: ( - - - - ), - }, - { - path: 'audit_log', - element: ( - - - - ), - }, - ], - }, - { - path: '/login', - element: , - }, - { - path: '/change_password', - element: , - }, - { - path: '*', - element: , - }, -] -const WraperRoutes = () => { - let element = useRoutes(routes) - return element -} - -// `PermissionGate` redirects to `/` when the current session lacks the -// required scope. `admin` is a wildcard (passes any gate). Routes that -// are A-class (launch / running / register model) are intentionally NOT -// wrapped — they remain visible to all authenticated users and rely on -// backend 403 as the only enforcement, matching the menu-visibility -// contract in MenuSide.js. -function PermissionGate({ requiredScope, alternateScope, children }) { - const { scopes } = parseTokenFromSession() || {} - const ok = - !requiredScope || - hasPermission(scopes, requiredScope) || - (alternateScope && hasPermission(scopes, alternateScope)) - return ok ? children : -} - -export default WraperRoutes diff --git a/xinference/ui/web/ui/src/scenes/_layout/index.js b/xinference/ui/web/ui/src/scenes/_layout/index.js deleted file mode 100644 index 47f0bb9122..0000000000 --- a/xinference/ui/web/ui/src/scenes/_layout/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { Box } from '@mui/material' -import React from 'react' -import { Outlet } from 'react-router-dom' - -import MenuSide from '../../components/MenuSide' - -const Layout = () => { - return ( - - - - - - - ) -} - -export default Layout diff --git a/xinference/ui/web/ui/src/scenes/apikey_management/index.js b/xinference/ui/web/ui/src/scenes/apikey_management/index.js deleted file mode 100644 index 04f4a6ad47..0000000000 --- a/xinference/ui/web/ui/src/scenes/apikey_management/index.js +++ /dev/null @@ -1,907 +0,0 @@ -import BlockIcon from '@mui/icons-material/Block' -import CheckCircleIcon from '@mui/icons-material/CheckCircle' -import ContentCopyIcon from '@mui/icons-material/ContentCopy' -import DeleteIcon from '@mui/icons-material/Delete' -import EditIcon from '@mui/icons-material/Edit' -import VisibilityIcon from '@mui/icons-material/Visibility' -import { - Alert, - Autocomplete, - Box, - Checkbox, - Chip, - FormControlLabel, - FormGroup, - IconButton, - InputAdornment, - Snackbar, - Tooltip, -} from '@mui/material' -import Button from '@mui/material/Button' -import Dialog from '@mui/material/Dialog' -import DialogActions from '@mui/material/DialogActions' -import DialogContent from '@mui/material/DialogContent' -import DialogTitle from '@mui/material/DialogTitle' -import TextField from '@mui/material/TextField' -import Typography from '@mui/material/Typography' -import { DataGrid } from '@mui/x-data-grid' -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' -import { DatePicker } from '@mui/x-date-pickers/DatePicker' -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider' -import dayjs from 'dayjs' -import * as React from 'react' -import { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import fetchWrapper from '../../components/fetchWrapper' -import Title from '../../components/Title' - -const MODEL_TYPES = ['LLM', 'embedding', 'rerank', 'image', 'audio', 'video'] - -function ApiKeyManagement() { - const { t } = useTranslation() - const [keys, setKeys] = useState([]) - const [createOpen, setCreateOpen] = useState(false) - const [revealOpen, setRevealOpen] = useState(false) - const [revealedKey, setRevealedKey] = useState('') - const [newKeyName, setNewKeyName] = useState('') - const [newKeyDescription, setNewKeyDescription] = useState('') - const [newKeyExpires, setNewKeyExpires] = useState(null) - const [newKeyPermType, setNewKeyPermType] = useState('all') - const [selectedModelTypes, setSelectedModelTypes] = useState([]) - const [selectedModelIds, setSelectedModelIds] = useState([]) - const [availableModels, setAvailableModels] = useState([]) - const [createdKey, setCreatedKey] = useState(null) - const [snackError, setSnackError] = useState('') - const [snackSuccess, setSnackSuccess] = useState('') - const [users, setUsers] = useState([]) - const [selectedOwner, setSelectedOwner] = useState(null) - const [isAdmin, setIsAdmin] = useState(false) - const [editOpen, setEditOpen] = useState(false) - const [editingKey, setEditingKey] = useState(null) - const [editPermType, setEditPermType] = useState('all') - const [editName, setEditName] = useState('') - const [editDescription, setEditDescription] = useState('') - const [editModelTypes, setEditModelTypes] = useState([]) - const [editModelIds, setEditModelIds] = useState([]) - const [bansDialogOpen, setBansDialogOpen] = useState(false) - const [bansDialogKeyId, setBansDialogKeyId] = useState(null) - const [bansData, setBansData] = useState([]) - - const loadKeys = async () => { - try { - const data = await fetchWrapper.get('/v1/admin/keys') - setKeys(data) - } catch (e) { - console.error(e) - } - } - - const handleShowBans = async (keyId) => { - try { - const data = await fetchWrapper.get(`/v1/admin/keys/${keyId}/banned`) - setBansData(Array.isArray(data) ? data : []) - setBansDialogKeyId(keyId) - setBansDialogOpen(true) - } catch (e) { - setSnackError(t('apikeyManagement.failedLoadBans')) - } - } - - const handleUnbanFromDialog = async (ip) => { - try { - await fetchWrapper.post(`/v1/admin/keys/${bansDialogKeyId}/unban`, { ip }) - const data = await fetchWrapper.get( - `/v1/admin/keys/${bansDialogKeyId}/banned` - ) - setBansData(Array.isArray(data) ? data : []) - } catch (e) { - setSnackError(t('apikeyManagement.failedUnban')) - } - } - - useEffect(() => { - loadKeys() - fetchWrapper - .get('/v1/models') - .then((response) => { - const models = (response.data || []).map((m) => ({ - id: m.id, - label: `${m.model_name || m.id} (${m.model_type || 'unknown'}) — ${ - m.id - }`, - })) - setAvailableModels(models) - }) - .catch(() => {}) - - const token = sessionStorage.getItem('token') - if (token) { - try { - const payload = JSON.parse(atob(token.split('.')[1])) - const scopes = payload.scopes || [] - if (scopes.includes('admin')) { - setIsAdmin(true) - fetchWrapper - .get('/v1/admin/users') - .then((data) => setUsers(data)) - .catch(() => {}) - } - } catch (_) { - /* token parse failed, not admin */ - } - } - }, []) - - const handleCreate = async () => { - try { - const model_permissions = [] - if (newKeyPermType === 'all') { - model_permissions.push({ - permission_type: 'all', - permission_value: null, - }) - } else if (newKeyPermType === 'model_type') { - selectedModelTypes.forEach((v) => { - model_permissions.push({ - permission_type: 'model_type', - permission_value: v, - }) - }) - } else if (newKeyPermType === 'model_id') { - selectedModelIds.forEach((v) => { - model_permissions.push({ - permission_type: 'model_id', - permission_value: v.id || v, - }) - }) - } - const result = await fetchWrapper.post('/v1/admin/keys', { - name: newKeyName || undefined, - description: newKeyDescription || undefined, - owner: selectedOwner ? selectedOwner.id : undefined, - expires_at: newKeyExpires - ? newKeyExpires.endOf('day').format('YYYY-MM-DDTHH:mm:ss') - : undefined, - model_permissions, - }) - setCreatedKey(result.key) - setNewKeyName('') - setNewKeyDescription('') - setNewKeyExpires(null) - setNewKeyPermType('all') - setSelectedModelTypes([]) - setSelectedModelIds([]) - setSelectedOwner(null) - loadKeys() - } catch (e) { - setSnackError(e.message || String(e)) - } - } - - const handleReveal = async (keyId) => { - try { - const data = await fetchWrapper.get(`/v1/admin/keys/${keyId}/reveal`) - setRevealedKey(data.key) - setRevealOpen(true) - } catch (e) { - setSnackError(e.message || String(e)) - } - } - - const handleToggleEnabled = async (key) => { - try { - await fetchWrapper.put(`/v1/admin/keys/${key.id}`, { - enabled: !key.enabled, - }) - loadKeys() - } catch (e) { - setSnackError(e.message || String(e)) - } - } - - const handleDelete = async (key) => { - if ( - !window.confirm( - `${t('apikeyManagement.confirmDelete')} "${ - key.name || key.key_prefix - }"?` - ) - ) - return - try { - await fetchWrapper.delete(`/v1/admin/keys/${key.id}`) - loadKeys() - } catch (e) { - setSnackError(e.message || String(e)) - } - } - - const handleEditPermissions = (key) => { - const perms = key.model_permissions || [] - if (perms.some((p) => p.permission_type === 'all')) { - setEditPermType('all') - setEditModelTypes([]) - setEditModelIds([]) - } else { - const types = perms - .filter((p) => p.permission_type === 'model_type') - .map((p) => p.permission_value) - const ids = perms - .filter((p) => p.permission_type === 'model_id') - .map((p) => p.permission_value) - if (types.length > 0 && ids.length > 0) { - setEditPermType('mixed') - } else if (ids.length > 0) { - setEditPermType('model_id') - } else { - setEditPermType('model_type') - } - setEditModelTypes(types) - setEditModelIds(ids) - } - setEditName(key.name || '') - setEditDescription(key.description || '') - setEditingKey(key) - setEditOpen(true) - } - - const handleSavePermissions = async () => { - if (!editingKey) return - try { - const model_permissions = [] - if (editPermType === 'all') { - model_permissions.push({ - permission_type: 'all', - permission_value: null, - }) - } else if (editPermType === 'model_type') { - editModelTypes.forEach((v) => { - model_permissions.push({ - permission_type: 'model_type', - permission_value: v, - }) - }) - } else if (editPermType === 'model_id') { - editModelIds.forEach((v) => { - model_permissions.push({ - permission_type: 'model_id', - permission_value: v.id || v, - }) - }) - } else { - editModelTypes.forEach((v) => { - model_permissions.push({ - permission_type: 'model_type', - permission_value: v, - }) - }) - editModelIds.forEach((v) => { - model_permissions.push({ - permission_type: 'model_id', - permission_value: v.id || v, - }) - }) - } - await fetchWrapper.put(`/v1/admin/keys/${editingKey.id}`, { - name: editName === '' ? null : editName, - description: editDescription === '' ? null : editDescription, - model_permissions, - }) - setEditOpen(false) - setEditingKey(null) - setSnackSuccess(t('apikeyManagement.permissionsSaved')) - loadKeys() - } catch (e) { - setSnackError(e.message || String(e)) - } - } - - const columns = [ - { field: 'id', headerName: t('apikeyManagement.id'), width: 60 }, - { - field: 'name', - headerName: t('apikeyManagement.name'), - flex: 1, - minWidth: 120, - }, - { - field: 'description', - headerName: t('apikeyManagement.description'), - flex: 1, - minWidth: 120, - }, - { - field: 'user_id', - headerName: t('apikeyManagement.owner'), - flex: 0.8, - minWidth: 100, - renderCell: (params) => { - // Prefer backend-provided owner_username (works for non-admin - // callers who can't GET /v1/admin/users). Fall back to local - // users[] lookup (still populated for admin), then to "#". - const row = params.row || {} - if (row.owner_username) return row.owner_username - const user = users.find((u) => u.id === params.value) - return user ? user.username : `#${params.value}` - }, - }, - { - field: 'key_prefix', - headerName: t('apikeyManagement.prefix'), - width: 100, - }, - { - field: 'enabled', - headerName: t('apikeyManagement.status'), - width: 80, - renderCell: (params) => - params.value ? ( - - ) : ( - - ), - }, - { - field: 'expires_at', - headerName: t('apikeyManagement.expires'), - flex: 1, - minWidth: 140, - }, - { - field: 'model_permissions', - headerName: t('apikeyManagement.modelPermissions'), - flex: 1.5, - minWidth: 180, - renderCell: (params) => ( - - {(params.value || []).map((mp, i) => ( - - ))} - - ), - }, - ...(isAdmin - ? [ - { - field: 'bans', - headerName: t('apikeyManagement.bans'), - width: 70, - renderCell: (params) => ( - handleShowBans(params.row.id)} - sx={{ cursor: 'pointer' }} - /> - ), - }, - ] - : []), - { - field: 'actions', - headerName: t('apikeyManagement.actions'), - width: 170, - renderCell: (params) => ( - - - handleReveal(params.row.id)} - > - - - - - handleEditPermissions(params.row)} - > - - - - - handleToggleEnabled(params.row)} - > - {params.row.enabled ? : } - - - - handleDelete(params.row)}> - - - - - ), - }, - ] - - return ( - - - <Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: 2 }}> - <Button variant="contained" onClick={() => setCreateOpen(true)}> - {t('apikeyManagement.createKey')} - </Button> - </Box> - <DataGrid - rows={keys} - columns={columns} - autoHeight - pageSizeOptions={[10, 25, 50]} - initialState={{ pagination: { paginationModel: { pageSize: 10 } } }} - getRowHeight={() => 'auto'} - /> - - {/* Create Key Dialog */} - <Dialog - open={createOpen} - onClose={() => { - setCreateOpen(false) - setCreatedKey(null) - }} - maxWidth="sm" - fullWidth - > - <DialogTitle> - {createdKey - ? t('apikeyManagement.keyCreatedTitle') - : t('apikeyManagement.createKeyTitle')} - </DialogTitle> - <DialogContent> - {createdKey ? ( - <Box> - <Typography variant="body2" color="warning.main" sx={{ mb: 1 }}> - {t('apikeyManagement.saveKeyWarning')} - </Typography> - <TextField - fullWidth - value={createdKey} - InputProps={{ - readOnly: true, - endAdornment: ( - <InputAdornment position="end"> - <Tooltip title={t('apikeyManagement.copy')}> - <IconButton - size="small" - onClick={() => { - navigator.clipboard.writeText(createdKey) - setSnackSuccess(t('apikeyManagement.copied')) - }} - > - <ContentCopyIcon fontSize="small" /> - </IconButton> - </Tooltip> - </InputAdornment> - ), - }} - sx={{ fontFamily: 'monospace' }} - /> - </Box> - ) : ( - <Box> - <TextField - margin="dense" - label={t('apikeyManagement.nameLabel')} - fullWidth - value={newKeyName} - onChange={(e) => setNewKeyName(e.target.value)} - /> - <TextField - margin="dense" - label={t('apikeyManagement.descriptionLabel')} - fullWidth - multiline - minRows={2} - maxRows={4} - value={newKeyDescription} - onChange={(e) => setNewKeyDescription(e.target.value)} - /> - {isAdmin && ( - <Autocomplete - options={users} - getOptionLabel={(option) => option.username} - value={selectedOwner} - onChange={(_, val) => setSelectedOwner(val)} - renderInput={(params) => ( - <TextField - {...params} - margin="dense" - label={t('apikeyManagement.ownerLabel')} - helperText={t('apikeyManagement.ownerHelperText')} - /> - )} - /> - )} - <LocalizationProvider dateAdapter={AdapterDayjs}> - <DatePicker - label={t('apikeyManagement.expiresLabel')} - value={newKeyExpires} - onChange={(val) => setNewKeyExpires(val)} - slotProps={{ - textField: { - fullWidth: true, - margin: 'dense', - helperText: t('apikeyManagement.expiresHelperText'), - }, - field: { clearable: true }, - }} - minDate={dayjs().add(1, 'day')} - /> - </LocalizationProvider> - <TextField - margin="dense" - label={t('apikeyManagement.permissionType')} - fullWidth - select - SelectProps={{ native: true }} - value={newKeyPermType} - onChange={(e) => setNewKeyPermType(e.target.value)} - > - <option value="all">{t('apikeyManagement.allModels')}</option> - <option value="model_type"> - {t('apikeyManagement.byModelType')} - </option> - <option value="model_id"> - {t('apikeyManagement.byModelId')} - </option> - </TextField> - {newKeyPermType === 'model_type' && ( - <FormGroup row sx={{ mt: 1 }}> - {MODEL_TYPES.map((type) => ( - <FormControlLabel - key={type} - control={ - <Checkbox - size="small" - checked={selectedModelTypes.includes(type)} - onChange={() => - setSelectedModelTypes((prev) => - prev.includes(type) - ? prev.filter((t) => t !== type) - : [...prev, type] - ) - } - /> - } - label={type} - /> - ))} - </FormGroup> - )} - {newKeyPermType === 'model_id' && ( - <Autocomplete - multiple - options={availableModels} - getOptionLabel={(option) => option.label || option} - isOptionEqualToValue={(option, value) => - option.id === (value.id || value) - } - value={selectedModelIds} - onChange={(_, val) => setSelectedModelIds(val)} - renderTags={(value, getTagProps) => - value.map((option, index) => ( - <Chip - size="small" - label={option.label || option} - {...getTagProps({ index })} - key={option.id || option} - /> - )) - } - renderInput={(params) => ( - <TextField - {...params} - margin="dense" - label={t('apikeyManagement.permissionValues')} - helperText={t('apikeyManagement.modelIdHelper')} - /> - )} - sx={{ mt: 1 }} - /> - )} - </Box> - )} - </DialogContent> - <DialogActions> - <Button - onClick={() => { - setCreateOpen(false) - setCreatedKey(null) - }} - > - {createdKey - ? t('apikeyManagement.close') - : t('apikeyManagement.cancel')} - </Button> - {!createdKey && ( - <Button variant="contained" onClick={handleCreate}> - {t('apikeyManagement.create')} - </Button> - )} - </DialogActions> - </Dialog> - - {/* Reveal Key Dialog */} - <Dialog - open={revealOpen} - onClose={() => setRevealOpen(false)} - maxWidth="sm" - fullWidth - > - <DialogTitle>{t('apikeyManagement.revealTitle')}</DialogTitle> - <DialogContent> - <TextField - fullWidth - value={revealedKey} - InputProps={{ - readOnly: true, - endAdornment: ( - <InputAdornment position="end"> - <Tooltip title={t('apikeyManagement.copy')}> - <IconButton - size="small" - onClick={() => { - navigator.clipboard.writeText(revealedKey) - setSnackSuccess(t('apikeyManagement.copied')) - }} - > - <ContentCopyIcon fontSize="small" /> - </IconButton> - </Tooltip> - </InputAdornment> - ), - }} - sx={{ fontFamily: 'monospace' }} - /> - </DialogContent> - <DialogActions> - <Button onClick={() => setRevealOpen(false)}> - {t('apikeyManagement.close')} - </Button> - </DialogActions> - </Dialog> - - {/* Edit Permissions Dialog */} - <Dialog - open={editOpen} - onClose={() => setEditOpen(false)} - maxWidth="sm" - fullWidth - > - <DialogTitle> - {t('apikeyManagement.editKeyTitle')}{' '} - {editingKey && (editingKey.name || editingKey.key_prefix)} - </DialogTitle> - <DialogContent> - <TextField - margin="dense" - label={t('apikeyManagement.nameLabel')} - fullWidth - value={editName} - onChange={(e) => setEditName(e.target.value)} - /> - <TextField - margin="dense" - label={t('apikeyManagement.descriptionLabel')} - fullWidth - multiline - minRows={2} - maxRows={4} - value={editDescription} - onChange={(e) => setEditDescription(e.target.value)} - /> - <TextField - margin="dense" - label={t('apikeyManagement.permissionType')} - fullWidth - select - SelectProps={{ native: true }} - value={editPermType} - onChange={(e) => { - const newType = e.target.value - if (newType === 'all') { - setEditModelTypes([]) - setEditModelIds([]) - } else if (newType === 'model_type') { - setEditModelIds([]) - } else if (newType === 'model_id') { - setEditModelTypes([]) - } - setEditPermType(newType) - }} - > - <option value="all">{t('apikeyManagement.allModels')}</option> - <option value="model_type"> - {t('apikeyManagement.byModelType')} - </option> - <option value="model_id">{t('apikeyManagement.byModelId')}</option> - <option value="mixed">{t('apikeyManagement.mixedMode')}</option> - </TextField> - {(editPermType === 'model_type' || editPermType === 'mixed') && ( - <FormGroup row sx={{ mt: 1 }}> - {MODEL_TYPES.map((type) => ( - <FormControlLabel - key={type} - control={ - <Checkbox - size="small" - checked={editModelTypes.includes(type)} - onChange={() => - setEditModelTypes((prev) => - prev.includes(type) - ? prev.filter((t) => t !== type) - : [...prev, type] - ) - } - /> - } - label={type} - /> - ))} - </FormGroup> - )} - {(editPermType === 'model_id' || editPermType === 'mixed') && ( - <Autocomplete - multiple - options={availableModels} - getOptionLabel={(option) => option.label || option} - isOptionEqualToValue={(option, value) => - option.id === (value.id || value) - } - value={editModelIds.map( - (id) => - availableModels.find((m) => m.id === id) || { id, label: id } - )} - onChange={(_, val) => setEditModelIds(val.map((v) => v.id || v))} - renderTags={(value, getTagProps) => - value.map((option, index) => ( - <Chip - size="small" - label={option.label || option} - {...getTagProps({ index })} - key={option.id || option} - /> - )) - } - renderInput={(params) => ( - <TextField - {...params} - margin="dense" - label={t('apikeyManagement.modelInstances')} - helperText={t('apikeyManagement.modelIdHelper')} - /> - )} - sx={{ mt: 1 }} - /> - )} - </DialogContent> - <DialogActions> - <Button onClick={() => setEditOpen(false)}> - {t('apikeyManagement.cancel')} - </Button> - <Button variant="contained" onClick={handleSavePermissions}> - {t('apikeyManagement.save')} - </Button> - </DialogActions> - </Dialog> - - <Snackbar - open={!!snackError} - autoHideDuration={5000} - onClose={() => setSnackError('')} - anchorOrigin={{ vertical: 'top', horizontal: 'center' }} - > - <Alert - severity="error" - onClose={() => setSnackError('')} - variant="filled" - > - {snackError} - </Alert> - </Snackbar> - <Snackbar - open={!!snackSuccess} - autoHideDuration={2000} - onClose={() => setSnackSuccess('')} - anchorOrigin={{ vertical: 'top', horizontal: 'center' }} - > - <Alert - severity="success" - onClose={() => setSnackSuccess('')} - variant="filled" - > - {snackSuccess} - </Alert> - </Snackbar> - - {/* Bans Detail Dialog */} - <Dialog - open={bansDialogOpen} - onClose={() => setBansDialogOpen(false)} - maxWidth="sm" - fullWidth - > - <DialogTitle> - {t('apikeyManagement.bannedIpsForKey', { keyId: bansDialogKeyId })} - </DialogTitle> - <DialogContent> - {bansData.length === 0 ? ( - <Typography color="text.secondary"> - {t('apikeyManagement.noActiveBans')} - </Typography> - ) : ( - <Box> - {bansData.map((ban, idx) => ( - <Box - key={idx} - display="flex" - justifyContent="space-between" - alignItems="center" - sx={{ py: 1, borderBottom: '1px solid #eee' }} - > - <Box> - <Typography variant="body2">{ban.ip}</Typography> - <Typography variant="caption" color="text.secondary"> - {t('apikeyManagement.remaining', { - seconds: ban.remaining_seconds, - })} - </Typography> - </Box> - <Button - size="small" - color="error" - onClick={() => handleUnbanFromDialog(ban.ip)} - > - {t('apikeyManagement.unban')} - </Button> - </Box> - ))} - </Box> - )} - </DialogContent> - <DialogActions> - <Button onClick={() => setBansDialogOpen(false)}> - {t('apikeyManagement.close')} - </Button> - </DialogActions> - </Dialog> - </Box> - ) -} - -export default ApiKeyManagement diff --git a/xinference/ui/web/ui/src/scenes/audit_log/index.js b/xinference/ui/web/ui/src/scenes/audit_log/index.js deleted file mode 100644 index c1550e746b..0000000000 --- a/xinference/ui/web/ui/src/scenes/audit_log/index.js +++ /dev/null @@ -1,1011 +0,0 @@ -import AccessTime from '@mui/icons-material/AccessTime' -import CalendarToday from '@mui/icons-material/CalendarToday' -import CheckIcon from '@mui/icons-material/Check' -import ContentCopyIcon from '@mui/icons-material/ContentCopy' -import ExpandMoreIcon from '@mui/icons-material/ExpandMore' -import RefreshIcon from '@mui/icons-material/Refresh' -import TagIcon from '@mui/icons-material/Tag' -import TextFieldsIcon from '@mui/icons-material/TextFields' -import { - Box, - Button, - Checkbox, - Chip, - Collapse, - Divider, - IconButton, - ListItemText, - Menu, - MenuItem, - MenuList, - Popover, - Select, - Tab, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - Tabs, - TextField, - Toolbar, - Tooltip, - Typography, -} from '@mui/material' -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' -import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker' -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider' -import React, { useCallback, useEffect, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import fetchWrapper from '../../components/fetchWrapper' -import Title from '../../components/Title' - -const FONT_SIZE = '0.813rem' -const PAGE_SIZE = 50 - -const TIME_RANGES = [ - { labelKey: 'monitoring.time.15m', from: 'now-15m', to: 'now' }, - { labelKey: 'monitoring.time.1h', from: 'now-1h', to: 'now' }, - { labelKey: 'monitoring.time.6h', from: 'now-6h', to: 'now' }, - { labelKey: 'monitoring.time.24h', from: 'now-24h', to: 'now' }, - { labelKey: 'monitoring.time.2d', from: 'now-2d', to: 'now' }, - { labelKey: 'monitoring.time.7d', from: 'now-7d', to: 'now' }, -] - -const DATE_TIME_SLOT_PROPS = { - textField: { - size: 'small', - fullWidth: true, - sx: { - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - '& .MuiInputLabel-root': { fontSize: FONT_SIZE }, - }, - }, -} - -const MODEL_TYPES = ['LLM', 'embedding', 'rerank', 'audio', 'image', 'video'] - -const CATEGORIES = ['inference', 'admin', 'auth'] - -const REFRESH_OPTIONS = [ - { labelKey: 'monitoring.refresh.off', value: 0 }, - { labelKey: 'monitoring.refresh.10s', value: 10000 }, - { labelKey: 'monitoring.refresh.30s', value: 30000 }, - { labelKey: 'monitoring.refresh.1m', value: 60000 }, - { labelKey: 'monitoring.refresh.5m', value: 300000 }, -] - -const ALL_STATUSES = [ - 'success', - 'denied', - 'error', - 'login_failed', - 'model_not_found', - 'no_credentials', - 'invalid_token', - 'invalid_key', - 'key_expired', - 'key_disabled', - 'ip_banned', - 'key_banned', - 'user_disabled', - 'insufficient_scope', -] - -const STATUS_COLORS = { - success: 'success.main', - denied: 'error.main', - error: 'error.main', - login_failed: 'error.main', - ip_banned: 'error.main', - key_banned: 'error.main', - user_disabled: 'error.main', - insufficient_scope: 'warning.main', - model_not_found: 'warning.main', - no_credentials: 'warning.main', - invalid_token: 'warning.main', - invalid_key: 'warning.main', - key_expired: 'warning.main', - key_disabled: 'warning.main', -} - -const DETAIL_FIELDS = [ - '@timestamp', - 'event_type', - 'category', - 'auth_type', - 'user', - 'api_key_name', - 'api_key_prefix', - 'model_id', - 'model_name', - 'model_type', - 'endpoint', - 'status', - 'latency_ms', - 'client_ip', - 'node', - 'address', -] - -const NUMBER_FIELDS = new Set(['latency_ms']) -const TIME_FIELDS = new Set(['@timestamp']) - -function FieldTypeIcon({ fieldKey }) { - if (TIME_FIELDS.has(fieldKey)) - return <CalendarToday sx={{ fontSize: 14, color: 'text.disabled' }} /> - if (NUMBER_FIELDS.has(fieldKey)) - return <TagIcon sx={{ fontSize: 14, color: 'text.disabled' }} /> - return <TextFieldsIcon sx={{ fontSize: 14, color: 'text.disabled' }} /> -} - -function HighlightText({ text, keywords }) { - if (!text) return '' - const validKeywords = ( - Array.isArray(keywords) ? keywords : [keywords] - ).filter((k) => k && typeof k === 'string' && k.trim()) - if (!validKeywords.length) return text - const escaped = validKeywords - .sort((a, b) => b.length - a.length) - .map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) - .join('|') - const parts = String(text).split(new RegExp(`(${escaped})`, 'gi')) - const lowerSet = new Set(validKeywords.map((k) => k.toLowerCase())) - return parts.map((part, i) => - lowerSet.has(part.toLowerCase()) ? ( - <mark key={i} style={{ background: '#ffe082', padding: 0 }}> - {part} - </mark> - ) : ( - part - ) - ) -} - -function copyToClipboard(text) { - if (navigator.clipboard) return navigator.clipboard.writeText(text) - const ta = document.createElement('textarea') - ta.value = text - document.body.appendChild(ta) - ta.select() - document.execCommand('copy') - document.body.removeChild(ta) - return Promise.resolve() -} - -function formatFieldValue(value) { - if (value === null || value === undefined) return '-' - if (typeof value === 'object') return JSON.stringify(value) - return String(value) -} - -function buildJsonObj(hit) { - const obj = {} - DETAIL_FIELDS.forEach((k) => { - if (hit[k] !== undefined) obj[k] = hit[k] - }) - return obj -} - -function DetailPanel({ hit, t }) { - const [tab, setTab] = useState(0) - const [copied, setCopied] = useState(false) - const copyTimerRef = useRef(null) - - useEffect(() => { - return () => { - if (copyTimerRef.current) clearTimeout(copyTimerRef.current) - } - }, []) - - const handleCopyJson = () => { - copyToClipboard(JSON.stringify(buildJsonObj(hit), null, 2)).then(() => { - setCopied(true) - copyTimerRef.current = setTimeout(() => setCopied(false), 1500) - }) - } - - const fields = DETAIL_FIELDS.filter( - (k) => hit[k] !== undefined && hit[k] !== '' - ) - - return ( - <Box sx={{ px: 2, pb: 2 }}> - <Tabs - value={tab} - onChange={(_, v) => setTab(v)} - sx={{ - 'minHeight': 32, - '& .MuiTab-root': { - minHeight: 32, - fontSize: FONT_SIZE, - textTransform: 'none', - py: 0.5, - }, - }} - > - <Tab label={t('auditLog.tableTab')} /> - <Tab label={t('auditLog.jsonTab')} /> - </Tabs> - - {tab === 0 ? ( - <Table size="small" sx={{ mt: 1 }}> - <TableHead> - <TableRow> - <TableCell - sx={{ fontSize: FONT_SIZE, width: 200, fontWeight: 600 }} - > - {t('auditLog.detailField')} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE, fontWeight: 600 }}> - {t('auditLog.detailValue')} - </TableCell> - </TableRow> - </TableHead> - <TableBody> - {fields.map((key) => ( - <TableRow key={key} hover> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <Box sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}> - <FieldTypeIcon fieldKey={key} /> - {key} - </Box> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - wordBreak: 'break-all', - fontFamily: 'monospace', - }} - > - {formatFieldValue(hit[key])} - </TableCell> - </TableRow> - ))} - </TableBody> - </Table> - ) : ( - <Box - sx={{ - mt: 1, - p: 1.5, - bgcolor: 'action.hover', - borderRadius: 1, - overflow: 'auto', - maxHeight: 400, - position: 'relative', - }} - > - <Tooltip - title={copied ? t('auditLog.copied') : t('auditLog.copyJson')} - > - <IconButton - size="small" - onClick={handleCopyJson} - sx={{ position: 'absolute', top: 4, right: 4 }} - > - {copied ? ( - <CheckIcon sx={{ fontSize: 16 }} /> - ) : ( - <ContentCopyIcon sx={{ fontSize: 16 }} /> - )} - </IconButton> - </Tooltip> - <pre - style={{ - margin: 0, - fontSize: FONT_SIZE, - fontFamily: 'monospace', - whiteSpace: 'pre-wrap', - wordBreak: 'break-all', - }} - > - {JSON.stringify(buildJsonObj(hit), null, 2)} - </pre> - </Box> - )} - </Box> - ) -} - -function AuditLog() { - const { t } = useTranslation() - const [hits, setHits] = useState([]) - const [total, setTotal] = useState(0) - const [loading, setLoading] = useState(false) - const [error, setError] = useState('') - const [pageFrom, setPageFrom] = useState(0) - const [expandedRow, setExpandedRow] = useState(null) - - // Time - const [timeRange, setTimeRange] = useState({ from: 'now-1h', to: 'now' }) - const [timeRangeLabel, setTimeRangeLabel] = useState('monitoring.time.1h') - const [timeAnchor, setTimeAnchor] = useState(null) - const [customFrom, setCustomFrom] = useState(null) - const [customTo, setCustomTo] = useState(null) - const [customDisplay, setCustomDisplay] = useState('') - - // Filters - const [selectedTypes, setSelectedTypes] = useState([]) - const [selectedCategories, setSelectedCategories] = useState([]) - const [selectedStatuses, setSelectedStatuses] = useState([]) - const [filterUser, setFilterUser] = useState('') - const [filterModel, setFilterModel] = useState('') - const [filterModelName, setFilterModelName] = useState('') - const [filterKey, setFilterKey] = useState('') - const [filterClientIp, setFilterClientIp] = useState('') - - // Auto refresh - const [refreshInterval, setRefreshInterval] = useState(0) - const [refreshLabel, setRefreshLabel] = useState('monitoring.refresh.off') - const [refreshAnchor, setRefreshAnchor] = useState(null) - const refreshTimerRef = useRef(null) - - const fetchData = useCallback(async () => { - setLoading(true) - setError('') - try { - const params = new URLSearchParams({ - time_from: timeRange.from, - time_to: timeRange.to, - page_from: String(pageFrom), - size: String(PAGE_SIZE), - }) - if (filterUser) params.set('user', filterUser) - if (filterKey) params.set('api_key_name', filterKey) - if (filterModel) params.set('model_id', filterModel) - if (filterModelName) params.set('model_name', filterModelName) - if (filterClientIp) params.set('client_ip', filterClientIp) - if (selectedTypes.length) - params.set('model_type', selectedTypes.join(',')) - if (selectedCategories.length) - params.set('category', selectedCategories.join(',')) - if (selectedStatuses.length) - params.set('status', selectedStatuses.join(',')) - - const data = await fetchWrapper.get( - `/v1/audit/search?${params.toString()}` - ) - setHits(data.hits || []) - setTotal(data.total || 0) - } catch (e) { - setError(e.message || String(e)) - setHits([]) - setTotal(0) - } finally { - setLoading(false) - } - }, [ - timeRange, - pageFrom, - filterUser, - filterKey, - filterModel, - filterModelName, - filterClientIp, - selectedTypes, - selectedCategories, - selectedStatuses, - ]) - - useEffect(() => { - fetchData() - }, [pageFrom, timeRange, selectedTypes, selectedCategories, selectedStatuses]) - - // Auto refresh timer - useEffect(() => { - if (refreshTimerRef.current) { - clearInterval(refreshTimerRef.current) - refreshTimerRef.current = null - } - if (refreshInterval > 0) { - refreshTimerRef.current = setInterval(() => fetchData(), refreshInterval) - } - return () => { - if (refreshTimerRef.current) clearInterval(refreshTimerRef.current) - } - }, [refreshInterval, fetchData]) - - const handleSearch = () => { - setPageFrom(0) - setExpandedRow(null) - fetchData() - } - - const handleKeyDown = (e) => { - if (e.key === 'Enter') handleSearch() - } - - const toggleType = (type) => { - setSelectedTypes((prev) => - prev.includes(type) ? prev.filter((t2) => t2 !== type) : [...prev, type] - ) - setPageFrom(0) - } - - const toggleCategory = (cat) => { - setSelectedCategories((prev) => - prev.includes(cat) ? prev.filter((c) => c !== cat) : [...prev, cat] - ) - setPageFrom(0) - } - - const handleQuickRange = (item) => { - setTimeRange({ from: item.from, to: item.to }) - setTimeRangeLabel(item.labelKey) - setCustomDisplay('') - setTimeAnchor(null) - setPageFrom(0) - } - - const handleApplyAbsolute = () => { - if ( - customFrom && - customTo && - customFrom.isValid() && - customTo.isValid() && - customTo.isAfter(customFrom) - ) { - const fromMs = customFrom.valueOf() - const toMs = customTo.valueOf() - setTimeRange({ from: String(fromMs), to: String(toMs) }) - setTimeRangeLabel(null) - setCustomDisplay( - `${customFrom.format('YYYY-MM-DD HH:mm')} ~ ${customTo.format( - 'YYYY-MM-DD HH:mm' - )}` - ) - setTimeAnchor(null) - setPageFrom(0) - } - } - - const formatTime = (ts) => { - if (!ts) return '' - const d = new Date(ts) - return d.toLocaleString([], { - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', - hour12: false, - }) - } - - const totalPages = Math.ceil(total / PAGE_SIZE) - const currentPage = Math.floor(pageFrom / PAGE_SIZE) + 1 - const searchKeywords = [ - filterUser, - filterModel, - filterModelName, - filterKey, - filterClientIp, - ].filter(Boolean) - - return ( - <Box - sx={{ - width: '100%', - height: 'calc(100vh - 64px)', - padding: '20px 20px 0 20px', - display: 'flex', - flexDirection: 'column', - }} - > - <Title title={t('auditLog.title')} /> - - {/* Toolbar */} - <Toolbar - variant="dense" - sx={{ - minHeight: 48, - px: 2, - gap: 1, - flexWrap: 'wrap', - }} - > - {/* Status Multi-Select */} - <Select - multiple - displayEmpty - value={selectedStatuses} - onChange={(e) => setSelectedStatuses(e.target.value)} - renderValue={(selected) => - selected.length === 0 ? ( - <Typography sx={{ fontSize: FONT_SIZE, color: 'text.disabled' }}> - {t('auditLog.status')} - </Typography> - ) : ( - <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.3 }}> - {selected.map((v) => ( - <Chip - key={v} - label={v} - size="small" - onDelete={() => - setSelectedStatuses((prev) => prev.filter((s) => s !== v)) - } - onMouseDown={(e) => e.stopPropagation()} - sx={{ fontSize: '0.7rem', height: 20 }} - /> - ))} - </Box> - ) - } - size="small" - sx={{ minWidth: 160, fontSize: FONT_SIZE }} - > - {ALL_STATUSES.map((s) => ( - <MenuItem key={s} value={s} dense> - <Checkbox checked={selectedStatuses.includes(s)} size="small" /> - <ListItemText - primary={s} - primaryTypographyProps={{ fontSize: FONT_SIZE }} - /> - </MenuItem> - ))} - </Select> - - {/* Text Filters */} - <TextField - size="small" - placeholder={t('auditLog.user')} - value={filterUser} - onChange={(e) => setFilterUser(e.target.value)} - onKeyDown={handleKeyDown} - sx={{ - 'width': 100, - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - }} - /> - <TextField - size="small" - placeholder={t('auditLog.modelId')} - value={filterModel} - onChange={(e) => setFilterModel(e.target.value)} - onKeyDown={handleKeyDown} - sx={{ - 'width': 120, - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - }} - /> - <TextField - size="small" - placeholder={t('auditLog.modelName')} - value={filterModelName} - onChange={(e) => setFilterModelName(e.target.value)} - onKeyDown={handleKeyDown} - sx={{ - 'width': 120, - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - }} - /> - <TextField - size="small" - placeholder={t('auditLog.apiKey')} - value={filterKey} - onChange={(e) => setFilterKey(e.target.value)} - onKeyDown={handleKeyDown} - sx={{ - 'width': 100, - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - }} - /> - <TextField - size="small" - placeholder={t('auditLog.clientIp')} - value={filterClientIp} - onChange={(e) => setFilterClientIp(e.target.value)} - onKeyDown={handleKeyDown} - sx={{ - 'width': 120, - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - }} - /> - <Button - variant="contained" - size="small" - onClick={handleSearch} - sx={{ fontSize: FONT_SIZE, textTransform: 'none' }} - > - {t('auditLog.search')} - </Button> - - <Box sx={{ flex: 1 }} /> - - {/* Time Range */} - <Button - size="small" - color="inherit" - startIcon={<AccessTime fontSize="small" />} - onClick={(e) => setTimeAnchor(e.currentTarget)} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - > - {timeRangeLabel ? t(timeRangeLabel) : customDisplay} - </Button> - <Popover - anchorEl={timeAnchor} - open={Boolean(timeAnchor)} - onClose={() => setTimeAnchor(null)} - anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} - transformOrigin={{ vertical: 'top', horizontal: 'right' }} - > - <Box sx={{ display: 'flex', width: 480, maxHeight: 400 }}> - <Box - sx={{ - width: 240, - p: 2, - display: 'flex', - flexDirection: 'column', - gap: 1.5, - }} - > - <Typography - variant="subtitle2" - color="text.secondary" - sx={{ fontSize: FONT_SIZE }} - > - {t('auditLog.timeFrom')} / {t('auditLog.timeTo')} - </Typography> - <LocalizationProvider dateAdapter={AdapterDayjs}> - <DateTimePicker - label={t('auditLog.timeFrom')} - value={customFrom} - onChange={(v) => setCustomFrom(v)} - ampm={false} - slotProps={DATE_TIME_SLOT_PROPS} - /> - <DateTimePicker - label={t('auditLog.timeTo')} - value={customTo} - onChange={(v) => setCustomTo(v)} - ampm={false} - slotProps={DATE_TIME_SLOT_PROPS} - /> - </LocalizationProvider> - <Button - variant="contained" - size="small" - onClick={handleApplyAbsolute} - disabled={!customFrom || !customTo} - fullWidth - sx={{ fontSize: FONT_SIZE }} - > - OK - </Button> - </Box> - <Divider orientation="vertical" flexItem /> - <Box sx={{ width: 240, overflow: 'auto' }}> - <MenuList dense disablePadding> - {TIME_RANGES.map((item) => ( - <MenuItem - key={item.labelKey} - selected={item.labelKey === timeRangeLabel} - onClick={() => handleQuickRange(item)} - sx={{ fontSize: FONT_SIZE }} - > - {t(item.labelKey)} - </MenuItem> - ))} - </MenuList> - </Box> - </Box> - </Popover> - - {/* Refresh */} - <Tooltip title={t('auditLog.search')}> - <IconButton size="small" color="inherit" onClick={handleSearch}> - <RefreshIcon fontSize="small" /> - </IconButton> - </Tooltip> - - {/* Auto Refresh Interval */} - <Button - size="small" - color="inherit" - startIcon={<RefreshIcon fontSize="small" />} - onClick={(e) => setRefreshAnchor(e.currentTarget)} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - > - {t(refreshLabel)} - </Button> - <Menu - anchorEl={refreshAnchor} - open={Boolean(refreshAnchor)} - onClose={() => setRefreshAnchor(null)} - > - {REFRESH_OPTIONS.map((item) => ( - <MenuItem - key={item.labelKey} - selected={item.labelKey === refreshLabel} - onClick={() => { - setRefreshInterval(item.value) - setRefreshLabel(item.labelKey) - setRefreshAnchor(null) - }} - sx={{ fontSize: FONT_SIZE }} - > - {t(item.labelKey)} - </MenuItem> - ))} - </Menu> - </Toolbar> - - {/* Model Type Chips */} - <Box - sx={{ - display: 'flex', - alignItems: 'center', - gap: 0.5, - px: 2, - py: 0.5, - }} - > - <Typography - sx={{ fontSize: FONT_SIZE, color: 'text.secondary', mr: 0.5 }} - > - {t('auditLog.modelType')} - </Typography> - {MODEL_TYPES.map((type) => ( - <Chip - key={type} - label={type} - size="small" - variant={selectedTypes.includes(type) ? 'filled' : 'outlined'} - color={selectedTypes.includes(type) ? 'primary' : 'default'} - onClick={() => toggleType(type)} - sx={{ fontSize: FONT_SIZE }} - /> - ))} - </Box> - - {/* Category Chips */} - <Box - sx={{ - display: 'flex', - alignItems: 'center', - gap: 0.5, - px: 2, - py: 0.5, - borderBottom: 1, - borderColor: 'divider', - }} - > - <Typography - sx={{ fontSize: FONT_SIZE, color: 'text.secondary', mr: 0.5 }} - > - {t('auditLog.category')} - </Typography> - {CATEGORIES.map((cat) => ( - <Chip - key={cat} - label={t(`auditLog.category_${cat}`)} - size="small" - variant={selectedCategories.includes(cat) ? 'filled' : 'outlined'} - color={selectedCategories.includes(cat) ? 'primary' : 'default'} - onClick={() => toggleCategory(cat)} - sx={{ fontSize: FONT_SIZE }} - /> - ))} - </Box> - - {/* Error */} - {error && ( - <Typography color="error" sx={{ px: 2, py: 1, fontSize: FONT_SIZE }}> - {error} - </Typography> - )} - - {/* Table */} - <TableContainer sx={{ flex: 1, overflow: 'auto' }}> - <Table size="small" stickyHeader> - <TableHead> - <TableRow> - <TableCell sx={{ width: 32, fontSize: FONT_SIZE }} /> - <TableCell sx={{ width: 150, fontSize: FONT_SIZE }}> - {t('auditLog.time')} - </TableCell> - <TableCell sx={{ width: 120, fontSize: FONT_SIZE }}> - {t('auditLog.status')} - </TableCell> - <TableCell sx={{ width: 80, fontSize: FONT_SIZE }}> - {t('auditLog.user')} - </TableCell> - <TableCell sx={{ width: 110, fontSize: FONT_SIZE }}> - {t('auditLog.apiKey')} - </TableCell> - <TableCell sx={{ width: 160, fontSize: FONT_SIZE }}> - {t('auditLog.modelName')} - </TableCell> - <TableCell sx={{ width: 160, fontSize: FONT_SIZE }}> - {t('auditLog.modelId')} - </TableCell> - <TableCell sx={{ width: 120, fontSize: FONT_SIZE }}> - {t('auditLog.clientIp')} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - {t('auditLog.endpoint')} - </TableCell> - </TableRow> - </TableHead> - <TableBody> - {hits.map((hit, idx) => { - const isExpanded = expandedRow === idx - const statusColor = STATUS_COLORS[hit.status] || 'text.primary' - - return ( - <React.Fragment key={`${hit['@timestamp']}-${idx}`}> - <TableRow - hover - sx={{ - 'cursor': 'pointer', - '& > *': { - borderBottom: isExpanded ? 'none' : undefined, - }, - }} - onClick={() => setExpandedRow(isExpanded ? null : idx)} - > - <TableCell sx={{ fontSize: FONT_SIZE, p: 0.5 }}> - <ExpandMoreIcon - fontSize="small" - sx={{ - transform: isExpanded ? 'rotate(180deg)' : 'none', - transition: 'transform 0.2s', - }} - /> - </TableCell> - <TableCell - sx={{ fontSize: FONT_SIZE, whiteSpace: 'nowrap' }} - > - {formatTime(hit['@timestamp'])} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <Typography - component="span" - sx={{ - fontSize: FONT_SIZE, - fontWeight: 600, - color: statusColor, - }} - > - {hit.status} - </Typography> - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <HighlightText - text={hit.user || ''} - keywords={searchKeywords} - /> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - maxWidth: 0, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }} - > - <HighlightText - text={hit.api_key_name || ''} - keywords={searchKeywords} - /> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - maxWidth: 0, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }} - > - <HighlightText - text={hit.model_name || ''} - keywords={searchKeywords} - /> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - maxWidth: 0, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }} - > - <HighlightText - text={hit.model_id || ''} - keywords={searchKeywords} - /> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - whiteSpace: 'nowrap', - }} - > - <HighlightText - text={hit.client_ip || ''} - keywords={searchKeywords} - /> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - maxWidth: 0, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - color: 'text.secondary', - }} - > - {hit.endpoint || ''} - </TableCell> - </TableRow> - <TableRow> - <TableCell sx={{ p: 0 }} colSpan={9}> - <Collapse in={isExpanded} timeout="auto" unmountOnExit> - <DetailPanel hit={hit} t={t} /> - </Collapse> - </TableCell> - </TableRow> - </React.Fragment> - ) - })} - {!loading && hits.length === 0 && ( - <TableRow> - <TableCell colSpan={9} align="center" sx={{ py: 4 }}> - <Typography color="text.secondary"> - {t('auditLog.noData')} - </Typography> - </TableCell> - </TableRow> - )} - </TableBody> - </Table> - </TableContainer> - - {/* Pagination */} - <Toolbar - variant="dense" - sx={{ - minHeight: 40, - px: 2, - justifyContent: 'flex-end', - gap: 1, - borderTop: 1, - borderColor: 'divider', - }} - > - <Typography variant="body2" sx={{ fontSize: FONT_SIZE }}> - {t('auditLog.totalRecords', { count: total })} - </Typography> - <Button - size="small" - disabled={pageFrom === 0} - onClick={() => setPageFrom(Math.max(0, pageFrom - PAGE_SIZE))} - sx={{ fontSize: FONT_SIZE, textTransform: 'none' }} - > - {t('auditLog.prevPage')} - </Button> - <Typography variant="body2" sx={{ fontSize: FONT_SIZE }}> - {currentPage} / {totalPages || 1} - </Typography> - <Button - size="small" - disabled={pageFrom + PAGE_SIZE >= total} - onClick={() => setPageFrom(pageFrom + PAGE_SIZE)} - sx={{ fontSize: FONT_SIZE, textTransform: 'none' }} - > - {t('auditLog.nextPage')} - </Button> - </Toolbar> - </Box> - ) -} - -export default AuditLog diff --git a/xinference/ui/web/ui/src/scenes/change_password/index.js b/xinference/ui/web/ui/src/scenes/change_password/index.js deleted file mode 100644 index 9b6b46a0bc..0000000000 --- a/xinference/ui/web/ui/src/scenes/change_password/index.js +++ /dev/null @@ -1,103 +0,0 @@ -import { Box } from '@mui/material' -import Alert from '@mui/material/Alert' -import Button from '@mui/material/Button' -import Container from '@mui/material/Container' -import TextField from '@mui/material/TextField' -import Typography from '@mui/material/Typography' -import * as React from 'react' -import { Fragment, useState } from 'react' -import { useNavigate } from 'react-router-dom' - -import fetchWrapper from '../../components/fetchWrapper' - -function ChangePassword() { - const navigate = useNavigate() - const [newPassword, setNewPassword] = useState('') - const [confirmPassword, setConfirmPassword] = useState('') - const [error, setError] = useState('') - const [success, setSuccess] = useState(false) - - const handleSubmit = async () => { - if (newPassword !== confirmPassword) { - setError('Passwords do not match') - return - } - if (newPassword.length < 8) { - setError('Password must be at least 8 characters') - return - } - try { - // Get user_id from token payload - const token = sessionStorage.getItem('token') - const payload = JSON.parse(atob(token.split('.')[1])) - await fetchWrapper.put(`/v1/admin/users/${payload.user_id}/password`, { - new_password: newPassword, - }) - setSuccess(true) - setTimeout(() => navigate('/launch_model/llm'), 1500) - } catch (e) { - setError(e.message || 'Failed to change password') - } - } - - return ( - <Fragment> - <Container component="main" maxWidth="sm" sx={{ marginTop: 10 }}> - <Box - sx={{ - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }} - > - <Typography component="h1" variant="h5"> - Change Password - </Typography> - <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}> - You must change your password before continuing. - </Typography> - {error && ( - <Alert severity="error" sx={{ mt: 2, width: '100%' }}> - {error} - </Alert> - )} - {success && ( - <Alert severity="success" sx={{ mt: 2, width: '100%' }}> - Password changed successfully. Redirecting... - </Alert> - )} - <Box sx={{ mt: 2, width: '100%' }}> - <TextField - margin="normal" - required - fullWidth - label="New Password" - type="password" - value={newPassword} - onChange={(e) => setNewPassword(e.target.value)} - /> - <TextField - margin="normal" - required - fullWidth - label="Confirm Password" - type="password" - value={confirmPassword} - onChange={(e) => setConfirmPassword(e.target.value)} - /> - <Button - fullWidth - variant="contained" - sx={{ mt: 3, mb: 2 }} - onClick={handleSubmit} - > - Change Password - </Button> - </Box> - </Box> - </Container> - </Fragment> - ) -} - -export default ChangePassword diff --git a/xinference/ui/web/ui/src/scenes/cluster_info/index.js b/xinference/ui/web/ui/src/scenes/cluster_info/index.js deleted file mode 100644 index e50a5a4624..0000000000 --- a/xinference/ui/web/ui/src/scenes/cluster_info/index.js +++ /dev/null @@ -1,116 +0,0 @@ -import { Box } from '@mui/material' -import Paper from '@mui/material/Paper' -import Grid from '@mui/material/Unstable_Grid2' -import React, { useContext, useEffect } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import TableTitle from '../../components/tableTitle' -import Title from '../../components/Title' -import { isValidBearerToken } from '../../components/utils' -import NodeInfo from './nodeInfo' - -const ClusterInfo = () => { - const endPoint = useContext(ApiContext).endPoint - const [cookie] = useCookies(['token']) - const navigate = useNavigate() - const { t } = useTranslation() - - useEffect(() => { - if ( - sessionStorage.getItem('auth') === 'true' && - !isValidBearerToken(sessionStorage.getItem('token')) && - !isValidBearerToken(cookie.token) - ) { - navigate('/login', { replace: true }) - } - }, [cookie.token]) - - const handleGoBack = () => { - const lastUrl = sessionStorage.getItem('lastActiveUrl') - if (lastUrl === 'launch_model') { - navigate(sessionStorage.getItem('modelType')) - } else if (lastUrl === 'running_models') { - navigate(sessionStorage.getItem('runningModelType')) - } else if (lastUrl === 'register_model') { - navigate(sessionStorage.getItem('registerModelType')) - } else { - navigate('/launch_model/llm') - } - } - - return ( - <Box - sx={{ - height: '100%', - width: '100%', - padding: '20px 20px 0 20px', - }} - > - <Title title={t('menu.clusterInfo')} /> - <Grid container spacing={3} style={{ width: '100%' }}> - <Grid item xs={12}> - <Paper - sx={{ - padding: 2, - display: 'flex', - overflow: 'auto', - flexDirection: 'column', - }} - > - <TableTitle>{t('clusterInfo.supervisor')}</TableTitle> - <NodeInfo - nodeRole="Supervisor" - endpoint={endPoint} - cookie={cookie} - handleGoBack={handleGoBack} - t={t} - /> - </Paper> - </Grid> - <Grid item xs={12}> - <Paper - sx={{ - padding: 2, - display: 'flex', - overflow: 'auto', - flexDirection: 'column', - }} - > - <TableTitle>{t('clusterInfo.workers')}</TableTitle> - <NodeInfo - nodeRole="Worker" - endpoint={endPoint} - cookie={cookie} - handleGoBack={handleGoBack} - t={t} - /> - </Paper> - </Grid> - <Grid item xs={12}> - <Paper - sx={{ - padding: 2, - display: 'flex', - overflow: 'auto', - flexDirection: 'column', - }} - > - <TableTitle>{t('clusterInfo.workerDetails')}</TableTitle> - <NodeInfo - nodeRole="Worker-Details" - endpoint={endPoint} - cookie={cookie} - handleGoBack={handleGoBack} - t={t} - /> - </Paper> - </Grid> - </Grid> - </Box> - ) -} - -export default ClusterInfo diff --git a/xinference/ui/web/ui/src/scenes/cluster_info/nodeInfo.js b/xinference/ui/web/ui/src/scenes/cluster_info/nodeInfo.js deleted file mode 100644 index 9d39206ae3..0000000000 --- a/xinference/ui/web/ui/src/scenes/cluster_info/nodeInfo.js +++ /dev/null @@ -1,366 +0,0 @@ -import Table from '@mui/material/Table' -import TableBody from '@mui/material/TableBody' -import TableHead from '@mui/material/TableHead' -import TableRow from '@mui/material/TableRow' -import Grid from '@mui/material/Unstable_Grid2' -import PropTypes from 'prop-types' -import React from 'react' - -import fetchWrapper from '../../components/fetchWrapper' -import { toReadableSize } from '../../components/utils' -import { StyledTableCell, StyledTableRow } from './style' - -class NodeInfo extends React.Component { - constructor(props) { - super(props) - this.nodeRole = props.nodeRole - this.endpoint = props.endpoint - this.state = { - version: {}, - info: [], - } - this.t = props.t - } - - refreshInfo() { - if ( - this.props.cookie.token === '' || - this.props.cookie.token === undefined || - (this.props.cookie.token !== 'no_auth' && - !sessionStorage.getItem('token')) - ) { - return - } - fetchWrapper - .get('/v1/cluster/info?detailed=true') - .then((data) => { - const { state } = this - state['info'] = data - this.setState(state) - }) - .catch((error) => { - console.error('Error:', error) - if (error.response.status == 403) { - this.props.handleGoBack() - } - }) - - if (JSON.stringify(this.state.version) === '{}') { - fetchWrapper - .get('/v1/cluster/version') - .then((data) => { - const { state } = this - state['version'] = { - release: 'v' + data['version'], - commit: data['full-revisionid'], - } - this.setState(state) - }) - .catch((error) => { - console.error('Error:', error) - if (error.response.status == 403) { - this.props.handleGoBack() - } - }) - } - } - - componentDidMount() { - this.interval = setInterval(() => this.refreshInfo(), 5000) - this.refreshInfo() - } - - componentWillUnmount() { - clearInterval(this.interval) - } - - render() { - if (this.state === undefined || this.state['info'] === []) { - return <div>Loading</div> - } - - if (this.nodeRole !== 'Worker-Details') { - const roleData = this.state['info'].filter( - (obj) => obj['node_type'] === this.nodeRole - ) - - const sum = (arr) => { - return arr.reduce((a, b) => a + b, 0) - } - - const gatherResourceStats = (prop) => - sum(roleData.map((obj) => obj[prop] || 0)) - - const nodesWithGpuLoad = roleData.filter( - (obj) => obj['gpu_utilization'] != null - ) - const gpu_utilization_avg = - nodesWithGpuLoad.length > 0 - ? sum(nodesWithGpuLoad.map((obj) => obj['gpu_utilization'])) / - nodesWithGpuLoad.length - : undefined - - const resourceStats = { - cpu_total: gatherResourceStats('cpu_count'), - cpu_avail: gatherResourceStats('cpu_available'), - memory_total: gatherResourceStats('mem_total'), - memory_avail: gatherResourceStats('mem_available'), - gpu_total: gatherResourceStats('gpu_count'), - gpu_memory_total: gatherResourceStats('gpu_vram_total'), - gpu_memory_avail: gatherResourceStats('gpu_vram_available'), - gpu_load: gpu_utilization_avg, - } - - //for all cases, we will at least have cpu information available. - resourceStats.cpu_used = resourceStats.cpu_total - resourceStats.cpu_avail - resourceStats.memory_used = - resourceStats.memory_total - resourceStats.memory_avail - - const row_count = ( - <StyledTableRow> - <StyledTableCell>{this.t('clusterInfo.count')}</StyledTableCell> - <StyledTableCell> - <Grid container> - <Grid>{roleData.length}</Grid> - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - - const CPU_row = ( - <StyledTableRow> - <StyledTableCell>{this.t('clusterInfo.cpuInfo')}</StyledTableCell> - <StyledTableCell> - <Grid container> - <Grid xs={4}> - {this.t('clusterInfo.usage')}{' '} - {resourceStats.cpu_used.toFixed(2)} - </Grid> - <Grid xs={8}> - {this.t('clusterInfo.total')}{' '} - {resourceStats.cpu_total.toFixed(2)} - </Grid> - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - - const CPU_Memory_Info_row = ( - <StyledTableRow> - <StyledTableCell> - {this.t('clusterInfo.cpuMemoryInfo')} - </StyledTableCell> - <StyledTableCell> - <Grid container> - <Grid xs={4}> - {this.t('clusterInfo.usage')}{' '} - {toReadableSize(resourceStats.memory_used)} - </Grid> - <Grid xs={8}> - {this.t('clusterInfo.total')}{' '} - {toReadableSize(resourceStats.memory_total)} - </Grid> - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - - const version_row = ( - <StyledTableRow> - <StyledTableCell>{this.t('clusterInfo.version')}</StyledTableCell> - <StyledTableCell> - <Grid container> - <Grid xs={4}> - {this.t('clusterInfo.release')} {this.state.version.release} - </Grid> - <Grid xs={8}> - {this.t('clusterInfo.commit')} {this.state.version.commit} - </Grid> - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - - let table_bodies - //case that we do not have GPU presents. - if (resourceStats.gpu_memory_total === 0) { - table_bodies = [row_count, CPU_row, CPU_Memory_Info_row, version_row] - } else { - resourceStats.gpu_memory_used = - resourceStats.gpu_memory_total - resourceStats.gpu_memory_avail - - const GPU_row = ( - <StyledTableRow> - <StyledTableCell>{this.t('clusterInfo.gpuInfo')}</StyledTableCell> - <StyledTableCell> - <Grid container> - {resourceStats.gpu_load != null ? ( - <React.Fragment> - <Grid xs={4}> - {this.t('clusterInfo.gpuLoad')}{' '} - {resourceStats.gpu_load.toFixed(2)}% - </Grid> - <Grid xs={8}> - {this.t('clusterInfo.total')}{' '} - {resourceStats.gpu_total.toFixed(2)} - </Grid> - </React.Fragment> - ) : ( - <Grid xs={12}> - {this.t('clusterInfo.total')}{' '} - {resourceStats.gpu_total.toFixed(2)} - </Grid> - )} - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - - const GPU_Memory_Info_row = ( - <StyledTableRow> - <StyledTableCell> - {this.t('clusterInfo.gpuMemoryInfo')} - </StyledTableCell> - <StyledTableCell> - <Grid container> - <Grid xs={4}> - {this.t('clusterInfo.usage')}{' '} - {toReadableSize(resourceStats.gpu_memory_used)} - </Grid> - <Grid xs={8}> - {this.t('clusterInfo.total')}{' '} - {toReadableSize(resourceStats.gpu_memory_total)} - </Grid> - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - - table_bodies = [ - row_count, - CPU_row, - CPU_Memory_Info_row, - GPU_row, - GPU_Memory_Info_row, - version_row, - ] - } - - if (this.nodeRole === 'Supervisor') { - const supervisor_addr_row = ( - <StyledTableRow> - <StyledTableCell>{this.t('clusterInfo.address')}</StyledTableCell> - <StyledTableCell> - <Grid container> - <Grid>{roleData[0] ? roleData[0]['ip_address'] : '-'}</Grid> - </Grid> - </StyledTableCell> - </StyledTableRow> - ) - table_bodies.splice(1, 0, supervisor_addr_row) - } - - return ( - <Table size="small"> - <TableHead> - <TableRow> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.item')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - <Grid container> - <Grid>{this.t('clusterInfo.value')}</Grid> - </Grid> - </StyledTableCell> - </TableRow> - </TableHead> - <TableBody>{table_bodies}</TableBody> - </Table> - ) - } else { - const workerData = this.state['info'].filter( - (obj) => obj['node_type'] === 'Worker' - ) - - return ( - <Table size="small"> - <TableHead> - <TableRow> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.nodeType')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.address')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.cpuUsage')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.cpuTotal')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.memUsage')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.memTotal')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.gpuCount')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.gpuLoad')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.gpuMemUsage')} - </StyledTableCell> - <StyledTableCell style={{ fontWeight: 'bolder' }}> - {this.t('clusterInfo.gpuMemTotal')} - </StyledTableCell> - </TableRow> - </TableHead> - <TableBody> - {workerData.map((row) => ( - <StyledTableRow> - <StyledTableCell> - {this.t('clusterInfo.worker')} - </StyledTableCell> - <StyledTableCell>{row['ip_address']}</StyledTableCell> - <StyledTableCell> - {(row['cpu_count'] - row['cpu_available']).toFixed(2)} - </StyledTableCell> - <StyledTableCell>{row['cpu_count'].toFixed(2)}</StyledTableCell> - <StyledTableCell> - {toReadableSize(row['mem_total'] - row['mem_available'])} - </StyledTableCell> - <StyledTableCell> - {toReadableSize(row['mem_total'])} - </StyledTableCell> - <StyledTableCell>{row['gpu_count'].toFixed(2)}</StyledTableCell> - <StyledTableCell> - {row['gpu_utilization'] != null - ? row['gpu_utilization'].toFixed(2) + '%' - : '-'} - </StyledTableCell> - <StyledTableCell> - {toReadableSize( - row['gpu_vram_total'] - row['gpu_vram_available'] - )} - </StyledTableCell> - <StyledTableCell> - {toReadableSize(row['gpu_vram_total'])} - </StyledTableCell> - </StyledTableRow> - ))} - </TableBody> - </Table> - ) - } - } -} - -NodeInfo.propTypes = { - nodeRole: PropTypes.string, - endpoint: PropTypes.string, -} - -export default NodeInfo diff --git a/xinference/ui/web/ui/src/scenes/cluster_info/style.js b/xinference/ui/web/ui/src/scenes/cluster_info/style.js deleted file mode 100644 index e5b028e70c..0000000000 --- a/xinference/ui/web/ui/src/scenes/cluster_info/style.js +++ /dev/null @@ -1,30 +0,0 @@ -import { createTheme, tableCellClasses } from '@mui/material' -import Paper from '@mui/material/Paper' -import TableCell from '@mui/material/TableCell' -import TableRow from '@mui/material/TableRow' -import { styled } from '@mui/system' - -export const theme = createTheme() - -export const StyledTableCell = styled(TableCell)(() => ({ - [`&.${tableCellClasses.body}`]: { - fontSize: 14, - }, -})) - -export const StyledTableRow = styled(TableRow)(({ theme }) => ({ - '&:nth-of-type(odd)': { - backgroundColor: theme.palette.action.hover, - }, - // hide last border - '&:last-child td, &:last-child th': { - border: 0, - }, -})) - -export const StyledPaper = styled(Paper)({ - padding: theme.spacing(2), - display: 'flex', - overflow: 'auto', - flexDirection: 'column', -}) diff --git a/xinference/ui/web/ui/src/scenes/launch_model/LaunchModel.js b/xinference/ui/web/ui/src/scenes/launch_model/LaunchModel.js deleted file mode 100644 index 6108fed42f..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/LaunchModel.js +++ /dev/null @@ -1,468 +0,0 @@ -import { - Box, - Chip, - CircularProgress, - FormControl, - InputLabel, - MenuItem, - Select, -} from '@mui/material' -import React, { - forwardRef, - useCallback, - useContext, - useEffect, - useImperativeHandle, - useRef, - useState, -} from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../components/apiContext' -import fetchWrapper from '../../components/fetchWrapper' -import HotkeyFocusTextField from '../../components/hotkeyFocusTextField' -import LaunchModelDrawer from './components/launchModelDrawer' -import ModelCard from './modelCard' - -// Toggle pagination globally for this page. Set to false to disable pagination and load all items. -const ENABLE_PAGINATION = false - -const LaunchModelComponent = forwardRef(({ modelType, gpuAvailable }, ref) => { - const { isCallingApi, setIsCallingApi, endPoint } = useContext(ApiContext) - const { isUpdatingModel } = useContext(ApiContext) - const { setErrorMsg } = useContext(ApiContext) - const [cookie] = useCookies(['token']) - - const [registrationData, setRegistrationData] = useState([]) - // States used for filtering - const [searchTerm, setSearchTerm] = useState('') - const [status, setStatus] = useState('') - const [statusArr, setStatusArr] = useState([]) - const [collectionArr, setCollectionArr] = useState([]) - const [filterArr, setFilterArr] = useState([]) - const { t } = useTranslation() - const [modelAbilityData, setModelAbilityData] = useState({ - type: modelType, - modelAbility: '', - options: [], - }) - const [selectedModel, setSelectedModel] = useState(null) - const [isOpenLaunchModelDrawer, setIsOpenLaunchModelDrawer] = useState(false) - - // Pagination status - const [displayedData, setDisplayedData] = useState([]) - // Virtual environments data - const [virtualEnvs, setVirtualEnvs] = useState([]) - const [currentPage, setCurrentPage] = useState(1) - const [hasMore, setHasMore] = useState(true) - const itemsPerPage = 20 - const loaderRef = useRef(null) - - const filter = useCallback( - (registration) => { - if (searchTerm !== '') { - if (!registration || typeof searchTerm !== 'string') return false - const modelName = registration.model_name - ? registration.model_name.toLowerCase() - : '' - const modelDescription = registration.model_description - ? registration.model_description.toLowerCase() - : '' - - if ( - !modelName.includes(searchTerm.toLowerCase()) && - !modelDescription.includes(searchTerm.toLowerCase()) - ) { - return false - } - } - - if ( - modelAbilityData.modelAbility && - ((Array.isArray(registration.model_ability) && - registration.model_ability.indexOf(modelAbilityData.modelAbility) < - 0) || - (typeof registration.model_ability === 'string' && - registration.model_ability !== modelAbilityData.modelAbility)) - ) - return false - - if (statusArr.length === 1) { - if (statusArr[0] === 'cached') { - const judge = - registration.model_specs?.some((spec) => filterCache(spec)) || - registration?.cache_status - return judge - } else { - return collectionArr?.includes(registration.model_name) - } - } else if (statusArr.length > 1) { - const judge = - registration.model_specs?.some((spec) => filterCache(spec)) || - registration?.cache_status - return judge && collectionArr?.includes(registration.model_name) - } - - return true - }, - [searchTerm, collectionArr, modelAbilityData.modelAbility, statusArr] - ) - - const filterCache = useCallback((spec) => { - if (Array.isArray(spec.cache_status)) { - return spec.cache_status?.some((cs) => cs) - } else { - return spec.cache_status === true - } - }, []) - - function getUniqueModelAbilities(arr) { - const uniqueAbilities = new Set() - - arr.forEach((item) => { - if (Array.isArray(item.model_ability)) { - item.model_ability.forEach((ability) => { - uniqueAbilities.add(ability) - }) - } - }) - - return Array.from(uniqueAbilities) - } - - const update = () => { - if ( - isCallingApi || - isUpdatingModel || - (cookie.token !== 'no_auth' && !sessionStorage.getItem('token')) - ) - return - - try { - setIsCallingApi(true) - - // Fetch both model registrations and virtual environments in parallel - Promise.all([ - fetchWrapper.get(`/v1/model_registrations/${modelType}?detailed=true`), - fetchWrapper.get('/v1/virtualenvs').catch(() => ({ list: [] })), // Fallback for virtual env API - ]) - .then(([modelData, virtualEnvData]) => { - const builtinRegistrations = modelData.filter((v) => v.is_builtin) - setModelAbilityData({ - ...modelAbilityData, - options: getUniqueModelAbilities(builtinRegistrations), - }) - setRegistrationData(builtinRegistrations) - setVirtualEnvs(virtualEnvData.list || []) - const collectionData = JSON.parse( - localStorage.getItem('collectionArr') - ) - setCollectionArr(collectionData) - - // Reset pagination status - setCurrentPage(1) - setHasMore(true) - }) - .catch((error) => { - console.error('Error:', error) - if (error.response.status !== 403 && error.response.status !== 401) { - setErrorMsg(error.message) - } - }) - } catch (error) { - console.error('Error:', error) - } finally { - setIsCallingApi(false) - } - } - - useEffect(() => { - update() - }, [cookie.token]) - - // Update pagination data - const updateDisplayedData = useCallback(() => { - const filteredData = registrationData.filter((registration) => - filter(registration) - ) - - const sortedData = [...filteredData].sort((a, b) => { - const isFavA = - Array.isArray(collectionArr) && collectionArr.includes(a.model_name) - const isFavB = - Array.isArray(collectionArr) && collectionArr.includes(b.model_name) - const rankA = a.featured === true ? 0 : isFavA ? 1 : 2 - const rankB = b.featured === true ? 0 : isFavB ? 1 : 2 - return rankA - rankB - }) - - // If pagination is disabled, show all data at once - if (!ENABLE_PAGINATION) { - setDisplayedData(sortedData) - setHasMore(false) - return - } - - const startIndex = (currentPage - 1) * itemsPerPage - const endIndex = currentPage * itemsPerPage - const newData = sortedData.slice(startIndex, endIndex) - - if (currentPage === 1) { - setDisplayedData(newData) - } else { - setDisplayedData((prev) => [...prev, ...newData]) - } - setHasMore(endIndex < sortedData.length) - }, [registrationData, filter, currentPage, itemsPerPage]) - - useEffect(() => { - updateDisplayedData() - }, [updateDisplayedData]) - - // Reset pagination when filters change - useEffect(() => { - setCurrentPage(1) - setHasMore(true) - }, [searchTerm, modelAbilityData.modelAbility, status]) - - // Infinite scroll observer - useEffect(() => { - if (!ENABLE_PAGINATION) return - - const observer = new IntersectionObserver( - (entries) => { - if (entries[0].isIntersecting && hasMore && !isCallingApi) { - setCurrentPage((prev) => prev + 1) - } - }, - { threshold: 1.0 } - ) - - if (loaderRef.current) { - observer.observe(loaderRef.current) - } - - return () => { - if (loaderRef.current) { - observer.unobserve(loaderRef.current) - } - } - }, [hasMore, isCallingApi, currentPage]) - - const getCollectionArr = (data) => { - setCollectionArr(data) - } - - const handleChangeFilter = (type, value) => { - const typeMap = { - modelAbility: { - setter: (value) => { - setModelAbilityData({ - ...modelAbilityData, - modelAbility: value, - }) - }, - filterArr: modelAbilityData.options, - }, - status: { setter: setStatus, filterArr: [] }, - } - - const { setter, filterArr: excludeArr } = typeMap[type] || {} - if (!setter) return - - setter(value) - - const updatedFilterArr = Array.from( - new Set([ - ...filterArr.filter((item) => !excludeArr.includes(item)), - value, - ]) - ) - - setFilterArr(updatedFilterArr) - - if (type === 'status') { - setStatusArr( - updatedFilterArr.filter( - (item) => ![...modelAbilityData.options].includes(item) - ) - ) - } - - // Reset pagination status - setDisplayedData([]) - setCurrentPage(1) - setHasMore(true) - } - - const handleDeleteChip = (item) => { - setFilterArr( - filterArr.filter((subItem) => { - return subItem !== item - }) - ) - if (item === modelAbilityData.modelAbility) { - setModelAbilityData({ - ...modelAbilityData, - modelAbility: '', - }) - } else { - setStatusArr( - statusArr.filter((subItem) => { - return subItem !== item - }) - ) - if (item === status) setStatus('') - } - - // Reset pagination status - setCurrentPage(1) - setHasMore(true) - } - - function getLabel(item) { - const translation = t(`launchModel.${item}`) - return translation === `launchModel.${item}` ? item : translation - } - - useImperativeHandle(ref, () => ({ - update, - })) - - return ( - <Box m="20px"> - <div - style={{ - display: 'grid', - gridTemplateColumns: (() => { - const hasAbility = modelAbilityData.options.length > 0 - const columns = hasAbility - ? ['150px', '150px', '1fr'] - : ['150px', '1fr'] - return columns.join(' ') - })(), - columnGap: '20px', - margin: '30px 2rem', - alignItems: 'center', - }} - > - {modelAbilityData.options.length > 0 && ( - <FormControl sx={{ minWidth: 120 }} size="small"> - <InputLabel id="ability-select-label"> - {t('launchModel.modelAbility')} - </InputLabel> - <Select - id="ability" - labelId="ability-select-label" - label="Model Ability" - onChange={(e) => - handleChangeFilter('modelAbility', e.target.value) - } - value={modelAbilityData.modelAbility} - size="small" - sx={{ width: '150px' }} - > - {modelAbilityData.options.map((item) => ( - <MenuItem key={item} value={item}> - {getLabel(item)} - </MenuItem> - ))} - </Select> - </FormControl> - )} - <FormControl sx={{ minWidth: 120 }} size="small"> - <InputLabel id="select-status">{t('launchModel.status')}</InputLabel> - <Select - id="status" - labelId="select-status" - label={t('launchModel.status')} - onChange={(e) => handleChangeFilter('status', e.target.value)} - value={status} - size="small" - sx={{ width: '150px' }} - > - <MenuItem value="cached">{t('launchModel.cached')}</MenuItem> - <MenuItem value="favorite">{t('launchModel.favorite')}</MenuItem> - </Select> - </FormControl> - - <FormControl sx={{ marginTop: 1 }} variant="outlined" margin="normal"> - <HotkeyFocusTextField - id="search" - type="search" - label={t('launchModel.search')} - value={searchTerm} - onChange={(e) => { - setSearchTerm(e.target.value) - }} - size="small" - hotkey="Enter" - t={t} - /> - </FormControl> - </div> - <div style={{ margin: '0 0 30px 30px' }}> - {filterArr.map((item, index) => ( - <Chip - key={index} - label={getLabel(item)} - variant="outlined" - size="small" - color="primary" - style={{ marginRight: 10 }} - onDelete={() => handleDeleteChip(item)} - /> - ))} - </div> - <div - style={{ - display: 'grid', - gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', - paddingLeft: '2rem', - gridGap: '2rem 0rem', - }} - > - {displayedData.map((filteredRegistration) => ( - <ModelCard - key={filteredRegistration.model_name} - url={endPoint} - modelData={filteredRegistration} - gpuAvailable={gpuAvailable} - modelType={modelType} - onGetCollectionArr={getCollectionArr} - onUpdate={update} - virtualEnvs={virtualEnvs} - onClick={() => { - setSelectedModel(filteredRegistration) - setIsOpenLaunchModelDrawer(true) - }} - /> - ))} - </div> - - <div ref={loaderRef} style={{ height: '20px', margin: '20px 0' }}> - {ENABLE_PAGINATION && hasMore && !isCallingApi && ( - <div style={{ textAlign: 'center', padding: '10px' }}> - <CircularProgress /> - </div> - )} - </div> - - {selectedModel && ( - <LaunchModelDrawer - key={selectedModel.model_name} - modelData={selectedModel} - modelType={modelType} - gpuAvailable={gpuAvailable} - open={isOpenLaunchModelDrawer} - onClose={() => setIsOpenLaunchModelDrawer(false)} - /> - )} - </Box> - ) -}) - -LaunchModelComponent.displayName = 'LaunchModelComponent' - -export default LaunchModelComponent diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/cachedListDialog.js b/xinference/ui/web/ui/src/scenes/launch_model/components/cachedListDialog.js deleted file mode 100644 index ee1a299bd8..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/cachedListDialog.js +++ /dev/null @@ -1,257 +0,0 @@ -import { Close, Delete } from '@mui/icons-material' -import { - Box, - Dialog, - DialogContent, - DialogTitle, - IconButton, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TablePagination, - TableRow, - Tooltip, -} from '@mui/material' -import { styled } from '@mui/material/styles' -import React, { useContext, useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../../components/apiContext' -import CopyComponent from '../../../components/copyComponent' -import DeleteDialog from '../../../components/deleteDialog' -import fetchWrapper from '../../../components/fetchWrapper' - -const EditCustomModel = ({ open, modelData, modelType, onClose, onUpdate }) => { - const { t } = useTranslation() - const { setErrorMsg } = useContext(ApiContext) - const [cachedListArr, setCachedListArr] = useState([]) - const [page, setPage] = useState(0) - const [isDeleteCached, setIsDeleteCached] = useState(false) - const [cachedModelVersion, setCachedModelVersion] = useState('') - - const StyledTableRow = styled(TableRow)(({ theme }) => ({ - '&:nth-of-type(odd)': { - backgroundColor: theme.palette.action.hover, - }, - })) - - const emptyRows = - page >= 0 ? Math.max(0, (1 + page) * 5 - cachedListArr.length) : 0 - - const getCachedList = () => { - fetchWrapper - .get(`/v1/cache/models?model_name=${modelData.model_name}`) - .then((data) => { - setCachedListArr(data.list) - if ( - page !== 0 && - data.list.length && - (page + 1) * 5 >= data.list.length && - data.list.length % 5 === 0 - ) { - setPage(data.list.length / 5 - 1) - } - }) - .catch((error) => { - console.error(error) - if (error.response.status !== 403) { - setErrorMsg(error.message) - } - }) - } - - const handleDeleteCached = () => { - fetchWrapper - .delete(`/v1/cache/models?model_version=${cachedModelVersion}`) - .then(() => { - getCachedList() - setIsDeleteCached(false) - }) - .catch((error) => { - console.error(error) - if (error.response.status !== 403) { - setErrorMsg(error.message) - } - }) - } - - const handleChangePage = (_, newPage) => { - setPage(newPage) - } - - const handleOpenDeleteCachedDialog = (model_version) => { - setCachedModelVersion(model_version) - setIsDeleteCached(true) - } - - const handleCloseCachedList = () => { - onClose() - onUpdate() - } - - useEffect(() => { - if (open) getCachedList() - }, [open]) - - return ( - <Dialog - open={open} - onClose={onClose} - maxWidth="xl" - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - > - <DialogTitle sx={{ m: 0, p: 2 }} id="customized-dialog-title"> - {modelData.model_name} - </DialogTitle> - <Box - sx={(theme) => ({ - position: 'absolute', - right: 8, - top: 8, - color: theme.palette.grey[500], - })} - > - <Close style={{ cursor: 'pointer' }} onClick={handleCloseCachedList} /> - </Box> - <DialogContent> - <TableContainer component={Paper}> - <Table - sx={{ minWidth: 500 }} - style={{ height: '500px', width: '100%' }} - stickyHeader - aria-label="simple pagination table" - > - <TableHead> - <TableRow> - {modelType === 'LLM' && ( - <> - <TableCell align="left"> - {t('launchModel.model_format')} - </TableCell> - <TableCell align="left"> - {t('launchModel.model_size_in_billions')} - </TableCell> - <TableCell align="left"> - {t('launchModel.quantizations')} - </TableCell> - </> - )} - <TableCell align="left" style={{ width: 192 }}> - {t('launchModel.real_path')} - </TableCell> - <TableCell align="left" style={{ width: 46 }}></TableCell> - <TableCell align="left" style={{ width: 192 }}> - {t('launchModel.path')} - </TableCell> - <TableCell align="left" style={{ width: 46 }}></TableCell> - <TableCell - align="left" - style={{ whiteSpace: 'nowrap', minWidth: 116 }} - > - {t('launchModel.ipAddress')} - </TableCell> - <TableCell align="left">{t('launchModel.operation')}</TableCell> - </TableRow> - </TableHead> - <TableBody style={{ position: 'relative' }}> - {cachedListArr.slice(page * 5, page * 5 + 5).map((row) => ( - <StyledTableRow style={{ maxHeight: 90 }} key={row.model_name}> - {modelType === 'LLM' && ( - <> - <TableCell component="th" scope="row"> - {row.model_format === null ? '—' : row.model_format} - </TableCell> - <TableCell> - {row.model_size_in_billions === null - ? '—' - : row.model_size_in_billions} - </TableCell> - <TableCell> - {row.quantization === null ? '—' : row.quantization} - </TableCell> - </> - )} - <TableCell> - <Tooltip title={row.real_path}> - <div - className={ - modelType === 'LLM' ? 'pathBox' : 'pathBox pathBox2' - } - > - {row.real_path} - </div> - </Tooltip> - </TableCell> - <TableCell> - <CopyComponent - tip={t('launchModel.copyRealPath')} - text={row.real_path} - /> - </TableCell> - <TableCell> - <Tooltip title={row.path}> - <div - className={ - modelType === 'LLM' ? 'pathBox' : 'pathBox pathBox2' - } - > - {row.path} - </div> - </Tooltip> - </TableCell> - <TableCell> - <CopyComponent - tip={t('launchModel.copyPath')} - text={row.path} - /> - </TableCell> - <TableCell>{row.actor_ip_address}</TableCell> - <TableCell align={modelType === 'LLM' ? 'center' : 'left'}> - <IconButton - aria-label="delete" - size="large" - onClick={() => - handleOpenDeleteCachedDialog(row.model_version) - } - > - <Delete /> - </IconButton> - </TableCell> - </StyledTableRow> - ))} - {emptyRows > 0 && ( - <TableRow style={{ height: 89.4 * emptyRows }}> - <TableCell /> - </TableRow> - )} - {cachedListArr.length === 0 && ( - <div className="empty">{t('launchModel.noCacheForNow')}</div> - )} - </TableBody> - </Table> - </TableContainer> - <TablePagination - style={{ float: 'right' }} - rowsPerPageOptions={[5]} - count={cachedListArr.length} - rowsPerPage={5} - page={page} - onPageChange={handleChangePage} - /> - </DialogContent> - - <DeleteDialog - text={t('launchModel.confirmDeleteCacheFiles')} - isDelete={isDeleteCached} - onHandleIsDelete={() => setIsDeleteCached(false)} - onHandleDelete={handleDeleteCached} - /> - </Dialog> - ) -} - -export default EditCustomModel diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/commandBuilder.js b/xinference/ui/web/ui/src/scenes/launch_model/components/commandBuilder.js deleted file mode 100644 index 997fd9a092..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/commandBuilder.js +++ /dev/null @@ -1,116 +0,0 @@ -import { Clear, Done, FilterNone } from '@mui/icons-material' -import { Tooltip } from '@mui/material' -import React, { useState } from 'react' -import { useTranslation } from 'react-i18next' - -import { copyToClipboard } from '../../../components/utils' - -const keyMap = { - model_size_in_billions: '--size-in-billions', - download_hub: '--download_hub', - enable_thinking: '--enable-thinking', - reasoning_content: '--reasoning_content', - lightning_version: '--lightning_version', - lightning_model_path: '--lightning_model_path', -} - -const CopyComponent = ({ getData, predefinedKeys }) => { - const { t } = useTranslation() - const [copyStatus, setCopyStatus] = useState('pending') - - const generateCommandLineStatement = (params) => { - const args = Object.entries(params) - .filter( - ([key, value]) => - (predefinedKeys.includes(key) && - value !== null && - value !== undefined) || - !predefinedKeys.includes(key) - ) - .flatMap(([key, value]) => { - if (key === 'gpu_idx' && Array.isArray(value)) { - return `--gpu-idx ${value.join(',')}` - } else if (key === 'peft_model_config' && typeof value === 'object') { - const peftArgs = [] - if (value.lora_list) { - peftArgs.push( - ...value.lora_list.map( - (lora) => `--lora-modules ${lora.lora_name} ${lora.local_path}` - ) - ) - } - if (value.image_lora_load_kwargs) { - peftArgs.push( - ...Object.entries(value.image_lora_load_kwargs).map( - ([k, v]) => `--image-lora-load-kwargs ${k} ${v}` - ) - ) - } - if (value.image_lora_fuse_kwargs) { - peftArgs.push( - ...Object.entries(value.image_lora_fuse_kwargs).map( - ([k, v]) => `--image-lora-fuse-kwargs ${k} ${v}` - ) - ) - } - return peftArgs - } else if (key === 'quantization_config' && typeof value === 'object') { - return Object.entries(value).map( - ([k, v]) => `--quantization-config ${k} ${v === null ? 'none' : v}` - ) - } else if (key === 'envs' && typeof value === 'object') { - return Object.entries(value).map(([k, v]) => `--env ${k} ${v}`) - } else if (key === 'virtual_env_packages' && Array.isArray(value)) { - return value.map((pkg) => `--virtual-env-package ${pkg}`) - } else if (key === 'enable_virtual_env') { - if (value === true) return `--enable-virtual-env` - if (value === false) return `--disable-virtual-env` - return [] - } else if (key === 'enable_thinking') { - if (value === true) return `--enable-thinking` - return [] - } else if (predefinedKeys.includes(key)) { - const newKey = keyMap[key] ?? `--${key.replace(/_/g, '-')}` - return `${newKey} ${ - value === false ? 'false' : value === null ? 'none' : value - }` - } else { - return `--${key} ${ - value === false ? 'false' : value === null ? 'none' : value - }` - } - }) - .join(' ') - - return `xinference launch ${args}` - } - - const showTooltipTemporarily = (status) => { - setCopyStatus(status) - setTimeout(() => setCopyStatus('pending'), 1500) - } - - const handleCopy = async (event) => { - const text = generateCommandLineStatement(getData()) - event.stopPropagation() - const textToCopy = String(text ?? '') - const success = await copyToClipboard(textToCopy) - showTooltipTemporarily(success ? 'success' : 'failed') - } - - return ( - <> - {copyStatus === 'pending' ? ( - <Tooltip title={t('launchModel.copyToCommandLine')} placement="top"> - <FilterNone className="copyToCommandLine" onClick={handleCopy} /> - </Tooltip> - ) : copyStatus === 'success' ? ( - <Done fontSize="small" color="success" /> - ) : ( - <Clear fontSize="small" color="error" /> - )} - </> - ) -} - -export default CopyComponent diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/dynamicFieldList.js b/xinference/ui/web/ui/src/scenes/launch_model/components/dynamicFieldList.js deleted file mode 100644 index 1a875eeeb9..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/dynamicFieldList.js +++ /dev/null @@ -1,169 +0,0 @@ -import AddCircle from '@mui/icons-material/AddCircle' -import DeleteIcon from '@mui/icons-material/Delete' -import { Autocomplete, Box, IconButton, Stack, TextField } from '@mui/material' -import React, { useContext } from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../../components/apiContext' - -const DynamicFieldList = ({ - name, - label, - mode, - value = [], - onChange, - keyPlaceholder = 'key', - valuePlaceholder = 'value', - keyOptions = [], -}) => { - const { t } = useTranslation() - const { setErrorMsg } = useContext(ApiContext) - const [errors, setErrors] = React.useState({}) - - const handleAdd = () => { - if (value.length > 0) { - const lastItem = value[value.length - 1] - let isIncomplete = false - - if (mode === 'key-value') { - isIncomplete = Object.values(lastItem).some((val) => - typeof val === 'string' - ? val.trim() === '' - : val === undefined || val === null - ) - } else if (mode === 'value') { - if (typeof lastItem === 'string') { - isIncomplete = lastItem.trim() === '' - } else { - isIncomplete = lastItem === undefined || lastItem === null - } - } - - if (isIncomplete) { - setErrorMsg(t('launchModel.fillCompleteParametersBeforeAdding')) - return - } - } - - const newItem = - mode === 'key-value' - ? { [keyPlaceholder]: '', [valuePlaceholder]: '' } - : '' - onChange(name, [...value, newItem]) - } - - const handleDelete = (index) => { - const newItems = [...value] - newItems.splice(index, 1) - onChange(name, newItems) - } - - const handleChange = (index, field, val) => { - const newItems = [...value] - newItems[index] = { ...newItems[index], [field]: val } - if (field === keyPlaceholder) { - const errorMap = {} - const keys = new Map() - - newItems.forEach((item, idx) => { - const key = item[keyPlaceholder] - if (!key) return - - if (keys.has(key)) { - const firstIdx = keys.get(key) - errorMap[firstIdx] = t('launchModel.mustBeUnique', { - key: keyPlaceholder, - }) - errorMap[idx] = t('launchModel.mustBeUnique', { key: keyPlaceholder }) - } else { - keys.set(key, idx) - } - }) - setErrors(errorMap) - } - onChange(name, newItems) - } - - const handleChangeValueOnly = (index, val) => { - const newItems = [...value] - newItems[index] = val - onChange(name, newItems) - } - - return ( - <Box> - <Stack spacing={2}> - <Box - display="flex" - alignItems="center" - gap={1} - paddingLeft={2} - paddingTop={1} - > - <div>{label}</div> - <IconButton color="primary" onClick={handleAdd}> - <AddCircle /> - </IconButton> - </Box> - {value.map((item, index) => ( - <Box - key={index} - display="flex" - alignItems="start" - justifyContent="space-between" - gap={1} - paddingLeft={2} - > - {mode === 'key-value' ? ( - <> - <Autocomplete - style={{ width: '44%' }} - freeSolo - disablePortal - options={keyOptions} - groupBy={() => t('components.suggestsCommonParameters')} - value={item[keyPlaceholder]} - inputValue={item[keyPlaceholder]} - onInputChange={(_, newValue) => - handleChange(index, keyPlaceholder, newValue) - } - renderInput={(params) => ( - <TextField - {...params} - className="textHighlight" - label={keyPlaceholder} - error={!!errors[index]} - helperText={errors[index]} - /> - )} - /> - <TextField - className="textHighlight" - style={{ width: '44%' }} - label={valuePlaceholder} - value={item[valuePlaceholder]} - onChange={(e) => - handleChange(index, valuePlaceholder, e.target.value) - } - /> - </> - ) : ( - <TextField - fullWidth - className="textHighlight" - label={valuePlaceholder} - value={item} - onChange={(e) => handleChangeValueOnly(index, e.target.value)} - /> - )} - <IconButton onClick={() => handleDelete(index)} size="large"> - <DeleteIcon /> - </IconButton> - </Box> - ))} - </Stack> - </Box> - ) -} - -export default DynamicFieldList diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/editCustomModelDialog.js b/xinference/ui/web/ui/src/scenes/launch_model/components/editCustomModelDialog.js deleted file mode 100644 index d7589acf74..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/editCustomModelDialog.js +++ /dev/null @@ -1,66 +0,0 @@ -import { - Box, - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - TextField, -} from '@mui/material' -import React from 'react' -import { useTranslation } from 'react-i18next' - -import CopyComponent from '../../../components/copyComponent' - -const EditCustomModel = ({ - open, - modelData, - onClose, - handleJsonDataPresentation, -}) => { - const { t } = useTranslation() - - return ( - <Dialog - open={open} - onClose={onClose} - maxWidth="md" - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - > - <DialogTitle sx={{ m: 0, p: 2 }} id="customized-dialog-title"> - {modelData.model_name} - </DialogTitle> - <Box - sx={(theme) => ({ - position: 'absolute', - right: 8, - top: 8, - color: theme.palette.grey[500], - })} - > - <CopyComponent - tip={t('launchModel.copyJson')} - text={JSON.stringify(modelData, null, 4)} - /> - </Box> - <DialogContent> - <TextField - sx={{ width: '700px' }} - multiline - rows={24} - disabled - defaultValue={JSON.stringify(modelData, null, 4)} - /> - </DialogContent> - <DialogActions> - <Button onClick={onClose}>{t('launchModel.cancel')}</Button> - <Button onClick={handleJsonDataPresentation} autoFocus> - {t('launchModel.edit')} - </Button> - </DialogActions> - </Dialog> - ) -} - -export default EditCustomModel diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/launchModelDrawer.js b/xinference/ui/web/ui/src/scenes/launch_model/components/launchModelDrawer.js deleted file mode 100644 index 8b1cbc3dfb..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/launchModelDrawer.js +++ /dev/null @@ -1,2121 +0,0 @@ -import { - ContentPasteGo, - ExpandLess, - ExpandMore, - RocketLaunchOutlined, - StopCircle, - UndoOutlined, -} from '@mui/icons-material' -import { - Box, - Button, - Chip, - CircularProgress, - Collapse, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Drawer, - FormControlLabel, - ListItemButton, - ListItemText, - Paper, - Radio, - RadioGroup, - Switch, - TextField, - Tooltip, - Typography, -} from '@mui/material' -import React, { useContext, useEffect, useMemo, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../../components/apiContext' -import fetchWrapper from '../../../components/fetchWrapper' -import TitleTypography from '../../../components/titleTypography' -import { llmAllDataKey } from '../data/data' -import CopyToCommandLine from './commandBuilder' -import DynamicFieldList from './dynamicFieldList' -import getModelFormConfig from './modelFormConfig' -import PasteDialog from './pasteDialog' -import Progress from './progress' -import SelectField from './selectField' - -const enginesWithNWorker = ['SGLang', 'vLLM', 'MLX'] -const modelEngineType = ['LLM', 'embedding', 'rerank', 'image'] -const historyStorageKey = 'historyArr' -const defaultHistoryUID = '__default_model_uid__' - -const LaunchModelDrawer = ({ - modelData, - modelType, - gpuAvailable, - open, - onClose, -}) => { - const navigate = useNavigate() - const { t } = useTranslation() - const { - isCallingApi, - isUpdatingModel, - setErrorMsg, - setSuccessMsg, - setIsCallingApi, - } = useContext(ApiContext) - const [formData, setFormData] = useState({}) - const [enginesObj, setEnginesObj] = useState({}) - const [engineOptions, setEngineOptions] = useState([]) - const [formatOptions, setFormatOptions] = useState([]) - const [sizeOptions, setSizeOptions] = useState([]) - const [quantizationOptions, setQuantizationOptions] = useState([]) - const [multimodalProjectorOptions, setMultimodalProjectorOptions] = useState( - [] - ) - const [multimodalProjector, setMultimodalProjector] = useState([]) - const [isOpenPasteDialog, setIsOpenPasteDialog] = useState(false) - const [collapseState, setCollapseState] = useState({}) - const [isShowProgress, setIsShowProgress] = useState(false) - const [isShowCancel, setIsShowCancel] = useState(false) - const [isLoading, setIsLoading] = useState(false) - const [progress, setProgress] = useState(0) - const [checkDynamicFieldComplete, setCheckDynamicFieldComplete] = useState([]) - const [replicaStatuses, setReplicaStatuses] = useState([]) - const [pendingHistory, setPendingHistory] = useState(null) - const [hasFetchedEngines, setHasFetchedEngines] = useState(false) - const [historyEntries, setHistoryEntries] = useState([]) - const [selectedHistoryKey, setSelectedHistoryKey] = useState(null) - const [isHistoryDialogOpen, setIsHistoryDialogOpen] = useState(false) - const [historyToDelete, setHistoryToDelete] = useState(null) - const [workerItems, setWorkerItems] = useState([]) - const [isLoadingWorkers, setIsLoadingWorkers] = useState(false) - const [hasWorkerLoadFailed, setHasWorkerLoadFailed] = useState(false) - const [fieldErrors, setFieldErrors] = useState({}) - const [saveAutostart, setSaveAutostart] = useState(false) - - const intervalRef = useRef(null) - - const modelSpecs = modelData.model_specs || [] - - const downloadHubOptions = useMemo( - () => ['none', ...(modelData?.download_hubs || [])], - [modelData?.download_hubs] - ) - - const hasHistory = historyEntries.length > 0 - - const selectedHistoryEntry = useMemo( - () => - historyEntries.find((item) => item.cache_key === selectedHistoryKey) || - historyEntries[0] || - null, - [historyEntries, selectedHistoryKey] - ) - - const isCached = (spec) => { - if (Array.isArray(spec.cache_status)) { - return spec.cache_status.some((cs) => cs) - } else { - return spec.cache_status === true - } - } - - const convertModelSize = (size) => { - return size.toString().includes('_') ? size : parseInt(size, 10) - } - - const range = (start, end) => { - return new Array(end - start + 1).fill(undefined).map((_, i) => i + start) - } - - const getNGPURange = (modelType) => { - if (['LLM', 'image'].includes(modelType)) { - return gpuAvailable > 0 - ? ['auto', 'CPU', ...range(1, gpuAvailable)] - : ['auto', 'CPU'] - } else { - return gpuAvailable === 0 ? ['CPU'] : ['GPU', 'CPU'] - } - } - - const normalizeNGPU = (value) => { - if (!value) return null - - if (value === 'CPU') return null - if (value === 'auto' || value === 'GPU') return 'auto' - - const num = parseInt(value, 10) - return isNaN(num) || num === 0 ? null : num - } - - const normalizeWorkerAddress = (value) => { - const normalized = String(value || '').trim() - if (!normalized) return '' - - try { - return new URL(`http://${normalized}`).hostname.replace(/^\[|\]$/g, '') - } catch { - if (normalized.startsWith('[')) { - const closingBracketIndex = normalized.indexOf(']') - if (closingBracketIndex !== -1) { - return normalized.slice(1, closingBracketIndex).trim() - } - } - - const lastColonIndex = normalized.lastIndexOf(':') - if (lastColonIndex === -1) return normalized - - const hasMultipleColons = normalized.indexOf(':') !== lastColonIndex - if (hasMultipleColons) { - return normalized - } - - return normalized.slice(0, lastColonIndex).trim() - } - } - - const normalizeWorkerIp = (value) => { - let workerValues = [] - if (Array.isArray(value)) { - workerValues = value - } else if (typeof value === 'string') { - workerValues = value.split(',') - } - - const seen = new Set() - return workerValues - .map((item) => normalizeWorkerAddress(item)) - .filter((item) => { - if (!item || seen.has(item)) return false - seen.add(item) - return true - }) - } - - const isCpuOnlySelection = (value) => value === 'CPU' || value === null - - const requiresGpuWorkers = (value) => - value !== undefined && value !== '' && !isCpuOnlySelection(value) - - const extractWorkerItems = (clusterInfo) => { - const workerMap = new Map() - const isFlatNodeList = Array.isArray(clusterInfo) - const nodes = isFlatNodeList - ? clusterInfo - : Array.isArray(clusterInfo?.workers) - ? clusterInfo.workers - : [] - - nodes.forEach((node) => { - if (isFlatNodeList && node?.node_type !== 'Worker') return - - const workerIp = normalizeWorkerAddress(node?.ip_address ?? node?.ip) - if (!workerIp) return - - const gpuCount = Number(node?.gpu_count || 0) - const existingWorker = workerMap.get(workerIp) - - if (existingWorker) { - existingWorker.gpuCount = Math.max(existingWorker.gpuCount, gpuCount) - return - } - - workerMap.set(workerIp, { - value: workerIp, - label: workerIp, - gpuCount, - }) - }) - - return Array.from(workerMap.values()).sort((a, b) => - a.label.localeCompare(b.label) - ) - } - - const clearFieldErrors = (...names) => { - if (!names.length) return - setFieldErrors((prev) => { - const next = { ...prev } - let changed = false - names.forEach((name) => { - if (next[name]) { - delete next[name] - changed = true - } - }) - return changed ? next : prev - }) - } - - const filteredWorkerItems = useMemo(() => { - if (!requiresGpuWorkers(formData.n_gpu)) { - return workerItems - } - return workerItems.filter((item) => item.gpuCount > 0) - }, [workerItems, formData.n_gpu]) - - const availableWorkerValues = useMemo( - () => new Set(filteredWorkerItems.map((item) => item.value)), - [filteredWorkerItems] - ) - - const workerFieldType = hasWorkerLoadFailed ? 'input' : 'select' - - const workerFieldDisabled = - workerFieldType === 'select' && - (isLoadingWorkers || filteredWorkerItems.length === 0) - - const workerFieldHelperText = useMemo(() => { - if (isLoadingWorkers) { - return t('launchModel.loadingWorkerNodes') - } - if (hasWorkerLoadFailed) { - return t('launchModel.workerNodesLoadFailed') - } - if (!workerItems.length) { - return t('launchModel.noWorkerNodesAvailable') - } - if (requiresGpuWorkers(formData.n_gpu) && !filteredWorkerItems.length) { - return t('launchModel.noAvailableGpuWorkers') - } - return '' - }, [ - t, - isLoadingWorkers, - hasWorkerLoadFailed, - workerItems, - filteredWorkerItems, - formData.n_gpu, - ]) - - const handleValueType = (str) => { - let val = String(str).trim() - - const isBracketed = (s) => - (s.startsWith('{') && s.endsWith('}')) || - (s.startsWith('[') && s.endsWith(']')) - - const tryParseStructured = (s) => { - try { - const normalized = s - .replace(/\bNone\b/g, 'null') - .replace(/\bTrue\b/g, 'true') - .replace(/\bFalse\b/g, 'false') - .replace(/'([^']*)'/g, '"$1"') - return JSON.parse(normalized) - } catch (e) { - return null - } - } - - if (val.toLowerCase() === 'none') { - return null - } else if (val.toLowerCase() === 'true') { - return true - } else if (val.toLowerCase() === 'false') { - return false - } else if (isBracketed(val)) { - const parsed = tryParseStructured(val) - if (parsed !== null) return parsed - // parsing failed: keep original string without splitting by comma - return val - } else if (val.includes(',')) { - return val.split(',').map((item) => item.trim()) - } else if (val.includes(',')) { - return val.split(',').map((item) => item.trim()) - } else if ( - !Number.isNaN(Number(val)) && - (val !== '' || Number(val) === 0) - ) { - return Number(val) - } else { - return val - } - } - - const arrayToObject = (arr, transformValue = (v) => v) => - Object.fromEntries( - arr.map(({ key, value }) => [key, transformValue(value)]) - ) - - const buildHistoryKey = (modelName, modelUID, createdBy = '') => - `${modelName}::${modelUID || defaultHistoryUID}::${createdBy}` - - const normalizeHistoryEntry = (item) => { - if (!item || typeof item !== 'object') return null - - const data = - item.data && typeof item.data === 'object' && !Array.isArray(item.data) - ? item.data - : item - const modelName = data.model_name || item.model_name - - if (!modelName) return null - - const modelUID = data.model_uid || item.model_uid || '' - - const rawUpdatedAt = item.updated_at - const updatedAt = - typeof rawUpdatedAt === 'number' ? rawUpdatedAt : Date.parse(rawUpdatedAt) - - const createdBy = item.created_by || data.created_by || '' - - return { - cache_key: buildHistoryKey(modelName, modelUID, createdBy), - model_name: modelName, - model_uid: modelUID, - updated_at: Number.isFinite(updatedAt) ? updatedAt : 0, - created_by: createdBy, - data, - } - } - - const readHistoryEntries = () => { - try { - const historyArr = - JSON.parse(localStorage.getItem(historyStorageKey)) || [] - if (!Array.isArray(historyArr)) return [] - return historyArr.map(normalizeHistoryEntry).filter(Boolean) - } catch (error) { - console.error('Failed to read history cache:', error) - return [] - } - } - - const sortHistoryEntries = (entries) => - [...entries].sort((a, b) => (b.updated_at || 0) - (a.updated_at || 0)) - - const getHistoryEntriesForModel = (entries = readHistoryEntries()) => - sortHistoryEntries( - entries.filter((item) => item.model_name === modelData.model_name) - ) - - const writeHistoryEntries = (entries) => { - localStorage.setItem( - historyStorageKey, - JSON.stringify( - entries.map((item) => ({ - model_name: item.model_name, - model_uid: item.model_uid, - updated_at: item.updated_at, - created_by: item.created_by || '', - data: item.data, - })) - ) - ) - } - - // Replace this model's cached entries with the authoritative server set - // while preserving other models' offline entries in localStorage. - const mirrorModelEntriesToLocal = (modelName, modelEntries) => { - const others = readHistoryEntries().filter( - (item) => item.model_name !== modelName - ) - writeHistoryEntries([...others, ...modelEntries]) - } - - const loadHistoryFromServer = async () => { - try { - const res = await fetchWrapper.get( - `/v1/launch_history?model_name=${encodeURIComponent( - modelData.model_name - )}` - ) - const entries = (Array.isArray(res) ? res : []) - .map(normalizeHistoryEntry) - .filter(Boolean) - mirrorModelEntriesToLocal(modelData.model_name, entries) - return sortHistoryEntries(entries) - } catch (error) { - console.error('Failed to load launch history from server:', error) - // Offline fallback: use whatever is cached locally. - return getHistoryEntriesForModel() - } - } - - const syncHistoryToServer = async (data) => { - try { - await fetchWrapper.post('/v1/launch_history', { - model_name: data.model_name, - model_uid: data.model_uid || '', - data, - }) - // Refresh from server so created_by populated by the backend shows up. - setHistoryEntries(await loadHistoryFromServer()) - } catch (error) { - console.error('Failed to sync launch history to server:', error) - } - } - - const deleteHistoryOnServer = async (modelName, modelUID) => { - try { - const path = modelUID - ? `/v1/launch_history/${encodeURIComponent( - modelName - )}/${encodeURIComponent(modelUID)}` - : `/v1/launch_history/${encodeURIComponent(modelName)}` - await fetchWrapper.delete(path) - } catch (error) { - console.error('Failed to delete launch history on server:', error) - } - } - - const upsertHistoryEntry = (data) => { - const nextEntry = normalizeHistoryEntry({ - model_name: data.model_name, - model_uid: data.model_uid, - updated_at: Date.now(), - data, - }) - const entries = readHistoryEntries().filter( - (item) => item.cache_key !== nextEntry.cache_key - ) - const nextEntries = [...entries, nextEntry] - writeHistoryEntries(nextEntries) - return getHistoryEntriesForModel(nextEntries) - } - - const removeHistoryEntry = (cacheKey) => { - const nextEntries = readHistoryEntries().filter( - (item) => item.cache_key !== cacheKey - ) - writeHistoryEntries(nextEntries) - return getHistoryEntriesForModel(nextEntries) - } - - const isHistoryEngineValid = (historyData) => { - if (!historyData?.model_engine) return false - - const engineData = enginesObj[historyData.model_engine] - return ( - engineOptions.includes(historyData.model_engine) && - Array.isArray(engineData) && - engineData.length > 0 - ) - } - - const loadHistoryEntry = (entry, shouldCloseDialog = true) => { - if (!entry) return - - setSelectedHistoryKey(entry.cache_key) - if (shouldCloseDialog) { - setIsHistoryDialogOpen(false) - } - - if (modelEngineType.includes(modelType)) { - if (open && hasFetchedEngines) { - if (isHistoryEngineValid(entry.data)) { - applyHistory(entry.data) - } else { - setErrorMsg(t('launchModel.invalidConfigCache')) - } - } else { - setPendingHistory(entry.data) - } - return - } - - applyHistory(entry.data) - } - - const handleDeleteHistory = () => { - if (!historyToDelete) return - - const wasSelected = historyToDelete.cache_key === selectedHistoryKey - const nextEntries = removeHistoryEntry(historyToDelete.cache_key) - - deleteHistoryOnServer(historyToDelete.model_name, historyToDelete.model_uid) - - setHistoryEntries(nextEntries) - setHistoryToDelete(null) - - if (!nextEntries.length) { - setSelectedHistoryKey(null) - setPendingHistory(null) - setFormData({}) - setCollapseState({}) - return - } - - if (!wasSelected) return - - const latestEntry = nextEntries[0] - setSelectedHistoryKey(latestEntry.cache_key) - - if (modelEngineType.includes(modelType)) { - if (open && hasFetchedEngines) { - if (isHistoryEngineValid(latestEntry.data)) { - applyHistory(latestEntry.data) - } else { - setFormData({}) - setCollapseState({}) - } - } else { - setPendingHistory(latestEntry.data) - } - return - } - - applyHistory(latestEntry.data) - } - - const formatHistoryTime = (updatedAt) => { - if (!updatedAt) return '--' - - const date = new Date(updatedAt) - return Number.isNaN(date.getTime()) ? '--' : date.toLocaleString() - } - - const objectToArray = (obj) => { - if (!obj || typeof obj !== 'object') return [] - return Object.entries(obj).map(([key, value]) => ({ key, value })) - } - - const getReplicaWorkerAddress = (replica) => replica?.worker_address || '--' - - const restoreNGPU = (value) => { - if (value === null) return 'CPU' - if (value === 'auto') { - return ['LLM', 'image'].includes(modelType) ? 'auto' : 'GPU' - } - if (typeof value === 'number') return String(value) - return value || 'CPU' - } - - const stringifyStructuredForInput = (val) => { - if (val === null) return 'none' - - if (Array.isArray(val)) { - const allPrimitives = val.every( - (item) => - item === null || ['string', 'number', 'boolean'].includes(typeof item) - ) - if (allPrimitives) { - return val.map((v) => String(v)).join(',') - } - } - - try { - const json = JSON.stringify(val) - return json.replace(/"/g, "'").replace(/:/g, ': ').replace(/,/g, ', ') - } catch (e) { - return String(val) - } - } - - const restoreFormDataFormat = (finalData) => { - const result = { ...finalData } - - let customData = [] - for (let key in result) { - !llmAllDataKey.includes(key) && - customData.push({ - key: key, - value: - result[key] === null - ? 'none' - : typeof result[key] === 'object' - ? stringifyStructuredForInput(result[key]) - : result[key], - }) - } - if (customData.length) result.custom = customData - - result.n_gpu = restoreNGPU(result.n_gpu) - if (result?.gpu_idx && Array.isArray(result.gpu_idx)) { - result.gpu_idx = result.gpu_idx.join(',') - } - if (result.worker_ip !== undefined) { - const workerIpList = normalizeWorkerIp(result.worker_ip) - if (workerIpList.length) { - result.worker_ip = workerIpList - } else { - delete result.worker_ip - } - } - - if (result?.peft_model_config) { - const pmc = result.peft_model_config - - if (pmc.image_lora_load_kwargs) { - result.image_lora_load_kwargs = objectToArray( - pmc.image_lora_load_kwargs - ) - } - - if (pmc.image_lora_fuse_kwargs) { - result.image_lora_fuse_kwargs = objectToArray( - pmc.image_lora_fuse_kwargs - ) - } - - if (pmc.lora_list) { - result.lora_list = pmc.lora_list - } - - delete result.peft_model_config - } - - if ( - result?.envs && - typeof result.envs === 'object' && - !Array.isArray(result.envs) - ) { - result.envs = objectToArray(result.envs) - } - - if ( - result?.quantization_config && - typeof result.quantization_config === 'object' && - !Array.isArray(result.quantization_config) - ) { - result.quantization_config = objectToArray(result.quantization_config) - } - - return result - } - - const applyHistory = (data) => { - const restoredData = restoreFormDataFormat(data) - setFormData(restoredData) - const collapseFromData = getCollapseStateFromData(restoredData) - setCollapseState((prev) => ({ ...prev, ...collapseFromData })) - } - - const getCollapseStateFromData = (result) => { - const newState = {} - - if ( - result.model_uid || - result.request_limits || - result.worker_ip?.length || - result.gpu_idx || - result.download_hub || - result.model_path - ) { - newState.nested_section_optional = true - } - - if ( - result.image_lora_load_kwargs?.length || - result.image_lora_fuse_kwargs?.length || - result.lora_list?.length - ) { - newState.nested_section_optional = true - newState.nested_section_lora = true - } - - if (result.envs?.length) { - newState.nested_section_optional = true - newState.nested_section_env = true - } - - if ( - (result.virtual_env_packages?.length ?? 0) > 0 || - result.enable_virtual_env !== undefined - ) { - newState.nested_section_optional = true - newState.nested_section_virtualEnv = true - } - - return newState - } - - const handleCommandLine = (data) => { - if (data.model_name === modelData.model_name) { - const restoredData = restoreFormDataFormat(data) - setFormData(restoredData) - - const collapseFromData = getCollapseStateFromData(restoredData) - setCollapseState((prev) => ({ ...prev, ...collapseFromData })) - } else { - setErrorMsg(t('launchModel.commandLineTip')) - } - } - - const fetchWorkers = async () => { - if (!open) return - - setIsLoadingWorkers(true) - setHasWorkerLoadFailed(false) - try { - const data = await fetchWrapper.get('/v1/cluster/info?detailed=true') - setWorkerItems(extractWorkerItems(data)) - } catch (error) { - console.error('Error:', error) - setWorkerItems([]) - setHasWorkerLoadFailed(true) - if (error?.response?.status !== 403) { - setErrorMsg(error.message) - } - } finally { - setIsLoadingWorkers(false) - } - } - - const fetchModelEngine = (model_name, model_type) => { - setHasFetchedEngines(false) - const enableVirtualEnv = - formData?.enable_virtual_env === true || - formData?.enable_virtual_env === 'true' - ? 'true' - : formData?.enable_virtual_env === false || - formData?.enable_virtual_env === 'false' - ? 'false' - : null - const enableVirtualEnvQuery = enableVirtualEnv - ? `?enable_virtual_env=${enableVirtualEnv}` - : '' - fetchWrapper - .get( - model_type === 'LLM' - ? `/v1/engines/${model_name}${enableVirtualEnvQuery}` - : `/v1/engines/${model_type}/${model_name}${enableVirtualEnvQuery}` - ) - .then((data) => { - if (!data) { - setEnginesObj({}) - setEngineOptions([]) - return - } - setEnginesObj(data) - setEngineOptions(Object.keys(data)) - }) - .catch((error) => { - console.error('Error:', error) - if (error?.response?.status !== 403) { - setErrorMsg(error.message) - } - }) - .finally(() => { - setIsCallingApi(false) - setHasFetchedEngines(true) - }) - } - - const fetchCancelModel = async () => { - try { - await fetchWrapper.post(`/v1/models/${modelData.model_name}/cancel`) - setIsLoading(true) - } catch (error) { - console.error('Error:', error) - if (error?.response?.status !== 403) { - setErrorMsg(error.message) - } - } finally { - setProgress(0) - stopPolling() - setIsShowProgress(false) - setIsShowCancel(false) - } - } - - const fetchProgress = async () => { - try { - const data = getFinalFormData() - const modelUid = data.model_uid || data.model_name - - // Fetch overall progress (existing logic) - const res = await fetchWrapper.get( - `/v1/models/${modelData.model_name}/progress` - ) - if (res.progress !== 1.0) setProgress(Number(res.progress)) - - // Fetch replica statuses (new logic) - const replicaRes = await fetchWrapper.get( - `/v1/models/${modelUid}/replicas` - ) - setReplicaStatuses(replicaRes) - } catch (error) { - console.error('Error:', error) - // Suppress 404 errors during early launch phase as model might not exist yet - if (error?.response?.status !== 403 && error?.response?.status !== 404) { - setErrorMsg(error.message) - } - } - } - - const startPolling = () => { - if (intervalRef.current) return - intervalRef.current = setInterval(fetchProgress, 500) - } - - const stopPolling = () => { - if (intervalRef.current !== null) { - clearInterval(intervalRef.current) - intervalRef.current = null - } - } - - useEffect(() => { - // Show locally cached entries immediately for a fast open, then refresh - // from the server (source of truth) which also brings in created_by. - const entries = getHistoryEntriesForModel() - setHistoryEntries(entries) - - const latestEntry = entries[0] - if (latestEntry) { - setSelectedHistoryKey(latestEntry.cache_key) - if (modelEngineType.includes(modelType)) { - setPendingHistory(latestEntry.data) - } else { - applyHistory(latestEntry.data) - } - } - - loadHistoryFromServer().then((serverEntries) => { - setHistoryEntries(serverEntries) - const serverLatest = serverEntries[0] - if (serverLatest) { - const shouldApply = - !latestEntry || - serverLatest.updated_at > (latestEntry.updated_at || 0) - if (shouldApply) { - setSelectedHistoryKey(serverLatest.cache_key) - if (modelEngineType.includes(modelType)) { - setPendingHistory(serverLatest.data) - } else { - applyHistory(serverLatest.data) - } - } - } - }) - }, []) - - useEffect(() => { - if (!pendingHistory || !modelEngineType.includes(modelType)) return - if (!open || !hasFetchedEngines) return - - if (!pendingHistory.model_engine) { - setFormData({}) - setCollapseState({}) - setPendingHistory(null) - return - } - - if (isHistoryEngineValid(pendingHistory)) { - applyHistory(pendingHistory) - } else { - setFormData({}) - setCollapseState({}) - } - setPendingHistory(null) - }, [pendingHistory, open, hasFetchedEngines, engineOptions, modelType]) - - useEffect(() => { - if (open) { - fetchWorkers() - } - }, [open]) - - useEffect(() => { - setFormData((prev) => { - const next = { ...prev } - let changed = false - - if (isCpuOnlySelection(normalizeNGPU(prev.n_gpu)) && prev.gpu_idx) { - next.gpu_idx = '' - changed = true - } - - if (workerItems.length > 0 && !isLoadingWorkers && !hasWorkerLoadFailed) { - const selectedWorkers = normalizeWorkerIp(prev.worker_ip) - if (selectedWorkers.length) { - const filteredWorkers = selectedWorkers.filter((ip) => - availableWorkerValues.has(ip) - ) - if (filteredWorkers.length !== selectedWorkers.length) { - next.worker_ip = filteredWorkers - changed = true - } - } - } - - return changed ? next : prev - }) - }, [ - formData.n_gpu, - availableWorkerValues, - isLoadingWorkers, - hasWorkerLoadFailed, - workerItems.length, - ]) - - useEffect(() => { - if (open && modelEngineType.includes(modelType)) - fetchModelEngine(modelData.model_name, modelType) - }, [open, modelData.model_name, modelType]) - - useEffect(() => { - if (formData.model_engine && modelEngineType.includes(modelType)) { - const format = [ - ...new Set( - enginesObj[formData.model_engine]?.map((item) => item.model_format) - ), - ].filter((value) => value !== undefined && value !== null && value !== '') - setFormatOptions(format) - - if (!format.includes(formData.model_format)) { - setFormData((prev) => ({ - ...prev, - model_format: '', - })) - } - if (format.length === 1) { - setFormData((prev) => ({ - ...prev, - model_format: format[0], - })) - } - } - }, [formData.model_engine, enginesObj]) - - useEffect(() => { - if (!formData.model_engine || !formData.model_format) return - - const configMap = { - LLM: { - field: 'model_size_in_billions', - optionSetter: setSizeOptions, - extractor: (item) => item.model_size_in_billions, - }, - embedding: { - field: 'quantization', - optionSetter: setQuantizationOptions, - extractor: (item) => item.quantization, - }, - rerank: { - field: 'quantization', - optionSetter: setQuantizationOptions, - extractor: (item) => item.quantization, - }, - image: { - field: 'quantization', - optionSetter: setQuantizationOptions, - extractor: (item) => item.quantization, - }, - } - - const config = configMap[modelType] - if (!config) return - - const options = [ - ...new Set( - enginesObj[formData.model_engine] - ?.filter((item) => item.model_format === formData.model_format) - ?.map(config.extractor) - ), - ].filter( - (option) => option !== undefined && option !== null && option !== '' - ) - - config.optionSetter(options) - if (!options.includes(formData[config.field])) { - setFormData((prev) => ({ ...prev, [config.field]: '' })) - } - - if (options.length === 1) { - setFormData((prev) => ({ ...prev, [config.field]: options[0] })) - } - }, [formData.model_engine, formData.model_format, enginesObj]) - - useEffect(() => { - if ( - formData.model_engine && - formData.model_format && - formData.model_size_in_billions - ) { - const quants = [ - ...new Set( - enginesObj[formData.model_engine] - ?.filter( - (item) => - item.model_format === formData.model_format && - item.model_size_in_billions === - convertModelSize(formData.model_size_in_billions) - ) - .flatMap((item) => item.quantizations) - ), - ] - const multimodal_projectors = [ - ...new Set( - enginesObj[formData.model_engine] - ?.filter( - (item) => - item.model_format === formData.model_format && - item.model_size_in_billions === - convertModelSize(formData.model_size_in_billions) - ) - .flatMap((item) => item.multimodal_projectors || []) - ), - ] - setQuantizationOptions(quants) - setMultimodalProjectorOptions(multimodal_projectors || []) - if (!quants.includes(formData.quantization)) { - setFormData((prev) => ({ - ...prev, - quantization: '', - })) - } - if (quants.length === 1) { - setFormData((prev) => ({ - ...prev, - quantization: quants[0], - })) - } - if (!multimodal_projectors.includes(multimodalProjector)) { - setMultimodalProjector('') - } - if (multimodal_projectors.length > 0 && !multimodalProjector) { - setMultimodalProjector(multimodal_projectors[0]) - } - } - }, [ - formData.model_engine, - formData.model_format, - formData.model_size_in_billions, - enginesObj, - ]) - - const engineItems = useMemo(() => { - return engineOptions.map((engine) => { - const engineData = enginesObj[engine] - let modelFormats = [] - let label = engine - let disabled = false - - if (Array.isArray(engineData)) { - modelFormats = Array.from( - new Set(engineData.map((item) => item.model_format)) - ) - - const relevantSpecs = modelSpecs.filter((spec) => - modelFormats.includes(spec.model_format) - ) - - const cached = relevantSpecs.some((spec) => isCached(spec)) - - label = cached ? `${engine} ${t('launchModel.cached')}` : engine - } else if (typeof engineData === 'string') { - label = `${engine} (${engineData})` - disabled = true - } - - return { - value: engine, - label, - disabled, - } - }) - }, [engineOptions, enginesObj, modelData]) - - const formatItems = useMemo(() => { - return formatOptions - .filter( - (format) => format !== undefined && format !== null && format !== '' - ) - .map((format) => { - const specs = modelSpecs.filter((spec) => spec.model_format === format) - - const cached = specs.some((spec) => isCached(spec)) - - return { - value: format, - label: cached ? `${format} ${t('launchModel.cached')}` : format, - } - }) - }, [formatOptions, modelData]) - - const sizeItems = useMemo(() => { - return sizeOptions.map((size) => { - const specs = modelSpecs - .filter((spec) => spec.model_format === formData.model_format) - .filter((spec) => spec.model_size_in_billions === size) - const cached = specs.some((spec) => isCached(spec)) - - return { - value: size, - label: cached ? `${size} ${t('launchModel.cached')}` : size, - } - }) - }, [sizeOptions, modelData]) - - const quantizationItems = useMemo(() => { - return quantizationOptions.map((quant) => { - const specs = modelSpecs - .filter((spec) => spec.model_format === formData.model_format) - .filter((spec) => - modelType === 'LLM' - ? spec.model_size_in_billions === - convertModelSize(formData.model_size_in_billions) - : true - ) - - const spec = specs.find((s) => { - return modelType === 'LLM' - ? s.quantizations === quant - : s.quantization === quant - }) - const cached = - modelType === 'LLM' && Array.isArray(spec?.cache_status) - ? spec?.cache_status[spec?.quantizations.indexOf(quant)] - : spec?.cache_status - - return { - value: quant, - label: cached ? `${quant} ${t('launchModel.cached')}` : quant, - } - }) - }, [quantizationOptions, modelData]) - - const modelFormConfig = useMemo( - () => - getModelFormConfig({ - t, - formData, - modelData, - gpuAvailable, - engineItems, - formatItems, - sizeItems, - quantizationItems, - getNGPURange, - downloadHubOptions, - enginesWithNWorker, - multimodalProjectorOptions, - workerItems: filteredWorkerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText, - }), - [ - t, - formData, - modelData, - gpuAvailable, - engineItems, - formatItems, - sizeItems, - quantizationItems, - getNGPURange, - downloadHubOptions, - enginesWithNWorker, - multimodalProjectorOptions, - filteredWorkerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText, - ] - ) - - useEffect(() => { - if (modelFormConfig[modelType]) { - const defaults = {} - const traverse = (fields) => { - fields.forEach((field) => { - if ( - field.default !== undefined && - formData[field.name] === undefined - ) { - defaults[field.name] = field.default - } - if (field.children) { - traverse(field.children) - } - }) - } - traverse(modelFormConfig[modelType]) - if (Object.keys(defaults).length > 0) { - setFormData((prev) => ({ ...prev, ...defaults })) - } - } - }, [modelFormConfig, modelType]) - - const checkRequiredFields = (fields, data) => { - return fields.every((field) => { - if (field.type === 'collapse' && field.children) { - return checkRequiredFields(field.children, data) - } - if (field.visible && field.required) { - const value = data[field.name] - return ( - value !== undefined && value !== null && String(value).trim() !== '' - ) - } - return true - }) - } - - const isDynamicFieldComplete = (val) => { - if (!val) return false - if (Array.isArray(val) && typeof val[0] === 'string') { - return val.every((item) => item?.trim()) - } - if (Array.isArray(val) && typeof val[0] === 'object') { - return val.every((obj) => { - return Object.values(obj).every( - (v) => typeof v !== 'string' || v.trim() - ) - }) - } - return true - } - - const handleDynamicField = (name, val) => { - clearFieldErrors(name) - setCheckDynamicFieldComplete((prev) => { - const filtered = prev.filter((item) => item.name !== name) - return [...filtered, { name, isComplete: isDynamicFieldComplete(val) }] - }) - setFormData((prev) => ({ - ...prev, - [name]: val, - })) - } - - const handleChange = (e) => { - const { name, value, type, checked } = e.target - const nextValue = - name === 'worker_ip' && workerFieldType === 'input' - ? value - : name === 'worker_ip' && typeof value === 'string' - ? normalizeWorkerIp(value) - : type === 'checkbox' - ? checked - : value - - if (name === 'n_gpu') { - clearFieldErrors('n_gpu', 'gpu_idx', 'worker_ip') - } else { - clearFieldErrors(name) - } - - setFormData((prev) => ({ - ...prev, - [name]: nextValue, - })) - } - - const handleGPUIdx = (data) => { - const arr = [] - data?.split(',').forEach((item) => { - arr.push(Number(item)) - }) - return arr - } - - const processFieldsRecursively = (fields, result) => { - fields.forEach((field) => { - if (result[field.name] === undefined && field.default !== undefined) { - result[field.name] = field.default - } - if ( - (result[field.name] || result[field.name] === 0) && - field.type === 'number' && - typeof result[field.name] !== 'number' - ) { - result[field.name] = parseInt(result[field.name], 10) - } - if (field.name === 'gpu_idx' && result[field.name]) { - result[field.name] = handleGPUIdx(result[field.name]) - } - if ( - field.visible === false || - result[field.name] === '' || - result[field.name] == null - ) { - delete result[field.name] - } - if (field.type === 'dynamicField' && Array.isArray(result[field.name])) { - result[field.name] = result[field.name].filter((item) => { - if (typeof item === 'string') { - return item.trim() !== '' - } else if (typeof item === 'object' && item !== null) { - return Object.values(item).every((val) => { - if (typeof val === 'string') { - return val.trim() !== '' - } - return val !== undefined && val !== null - }) - } - return false - }) - if (result[field.name].length === 0) { - delete result[field.name] - } - } - if (field.type === 'collapse' && Array.isArray(field.children)) { - processFieldsRecursively(field.children, result) - } - }) - } - - const getFinalFormData = () => { - const fields = modelFormConfig[modelType] || [] - let result = { - model_name: modelData.model_name, - model_type: modelType, - ...formData, - } - - processFieldsRecursively(fields, result) - - if (result.n_gpu) { - result.n_gpu = normalizeNGPU(result.n_gpu) - } - - if ( - Array.isArray(result.worker_ip) || - typeof result.worker_ip === 'string' - ) { - const workerIpList = normalizeWorkerIp(result.worker_ip) - if (workerIpList.length) { - result.worker_ip = workerIpList.join(',') - } else { - delete result.worker_ip - } - } - - if (result.n_gpu_layers < 0) { - delete result.n_gpu_layers - } - if (result.download_hub === 'none') { - delete result.download_hub - } - if (result.gguf_quantization === 'none') { - delete result.gguf_quantization - } - - const peft_model_config = {} - ;['image_lora_load_kwargs', 'image_lora_fuse_kwargs'].forEach((key) => { - if (result[key]?.length) { - peft_model_config[key] = arrayToObject(result[key], handleValueType) - delete result[key] - } - }) - if (result.lora_list?.length) { - peft_model_config.lora_list = result.lora_list - delete result.lora_list - } - if (Object.keys(peft_model_config).length) { - result.peft_model_config = peft_model_config - } - - if (result.enable_virtual_env === 'unset') { - delete result.enable_virtual_env - } else if (result.enable_virtual_env === 'true') { - result.enable_virtual_env = true - } else if (result.enable_virtual_env === 'false') { - result.enable_virtual_env = false - } - - if (result.envs?.length) { - result.envs = arrayToObject(result.envs) - } - - if (result.quantization_config?.length) { - result.quantization_config = arrayToObject( - result.quantization_config, - handleValueType - ) - } - - for (const key in result) { - if (![...llmAllDataKey, 'custom'].includes(key)) { - delete result[key] - } - } - if (result.custom?.length) { - Object.assign(result, arrayToObject(result.custom, handleValueType)) - delete result.custom - } - - return result - } - - const collectVisibleFieldErrors = (fields = [], errors = []) => { - fields.forEach((field) => { - if (field.type === 'collapse') { - collectVisibleFieldErrors(field.children || [], errors) - return - } - if (field.visible && field.error) { - errors.push(field.name) - } - }) - return errors - } - - const validateBeforeLaunch = (data) => { - const nextErrors = {} - const selectedWorkers = normalizeWorkerIp(data.worker_ip) - - if ( - selectedWorkers.length && - !isLoadingWorkers && - !hasWorkerLoadFailed && - workerItems.length > 0 && - !selectedWorkers.every((ip) => availableWorkerValues.has(ip)) - ) { - nextErrors.worker_ip = t('launchModel.invalidWorkerSelection') - } - - if (isCpuOnlySelection(data.n_gpu) && data.gpu_idx?.length) { - nextErrors.gpu_idx = t('launchModel.gpuIdxNotAllowedForCpu') - } else if ( - Array.isArray(data.gpu_idx) && - data.gpu_idx.length && - data.gpu_idx.length % (data.replica || 1) - ) { - nextErrors.gpu_idx = t('launchModel.gpuIdxMustMatchReplica') - } - - return nextErrors - } - - const handleSubmit = () => { - if (isCallingApi || isUpdatingModel) { - return - } - - const visibleFieldErrors = collectVisibleFieldErrors( - modelFormConfig[modelType] || [] - ) - if (visibleFieldErrors.length) { - setErrorMsg(t('launchModel.fixFieldErrorsBeforeLaunch')) - return - } - - try { - const data = getFinalFormData() - const nextFieldErrors = validateBeforeLaunch(data) - setFieldErrors(nextFieldErrors) - - if (Object.keys(nextFieldErrors).length) { - setErrorMsg(Object.values(nextFieldErrors)[0]) - return - } - - setIsCallingApi(true) - setProgress(0) - setIsShowProgress(true) - setIsShowCancel(true) - setFieldErrors({}) - - // First fetcher request to initiate the model - fetchWrapper - .post('/v1/models', data) - .then(async (launchResponse) => { - const launchedData = { - ...data, - model_uid: - launchResponse?.model_uid || data.model_uid || data.model_name, - } - navigate(`/running_models/${modelType}`) - sessionStorage.setItem( - 'runningModelType', - `/running_models/${modelType}` - ) - const nextHistoryEntries = upsertHistoryEntry(launchedData) - setHistoryEntries(nextHistoryEntries) - setSelectedHistoryKey( - buildHistoryKey(launchedData.model_name, launchedData.model_uid) - ) - syncHistoryToServer(launchedData) - if (saveAutostart) { - try { - await fetchWrapper.post('/v1/autostart/models', { - enabled: true, - priority: 100, - launch: launchedData, - }) - setSuccessMsg(t('launchModel.launchCompletedWithAutostart')) - } catch (error) { - console.error('Failed to save autostart config:', error) - setErrorMsg(t('launchModel.autostartSaveFailed')) - } - } - }) - .catch((error) => { - console.error('Error:', error) - if (error.response?.status === 499) { - setSuccessMsg(t('launchModel.cancelledSuccessfully')) - } else if (error.response?.status !== 403) { - setErrorMsg(error.message) - } - }) - .finally(() => { - setIsCallingApi(false) - stopPolling() - setIsShowProgress(false) - setIsShowCancel(false) - setIsLoading(false) - }) - startPolling() - } catch (error) { - setErrorMsg(`${error}`) - setIsCallingApi(false) - } - } - - const areRequiredFieldsFilled = useMemo(() => { - const data = getFinalFormData() - const fields = modelFormConfig[modelType] || [] - return checkRequiredFields(fields, data) - }, [formData, modelType, modelFormConfig]) - - const renderFormFields = (fields = []) => { - const enhancedFields = fields.map((field) => { - if (field.name === 'reasoning_content') { - const enable_thinking_default = fields.find( - (item) => item.name === 'enable_thinking' - ).default - return { - ...field, - visible: - !!modelData.model_ability?.includes('reasoning') && - (formData.enable_thinking ?? - enable_thinking_default ?? - field.default ?? - false), - } - } - - return field - }) - - return enhancedFields - .filter((field) => field.visible) - .map((field) => { - const fieldKey = field.name - const inlineFieldError = fieldErrors[fieldKey] - const hasFieldError = Boolean(inlineFieldError || field.error) - - switch (field.type) { - case 'collapse': { - const open = collapseState[fieldKey] ?? false - - const toggleCollapse = () => { - setCollapseState((prev) => ({ - ...prev, - [fieldKey]: !prev[fieldKey], - })) - } - - return ( - <Box key={fieldKey} sx={{ mt: 2 }}> - <ListItemButton onClick={toggleCollapse}> - <div - style={{ display: 'flex', alignItems: 'center', gap: 10 }} - > - <ListItemText primary={field.label} /> - {open ? <ExpandLess /> : <ExpandMore />} - </div> - </ListItemButton> - <Collapse in={open} timeout="auto" unmountOnExit> - <Box sx={{ pl: 2 }}> - {renderFormFields(field.children || [])} - </Box> - </Collapse> - </Box> - ) - } - case 'select': - return ( - <SelectField - key={fieldKey} - label={field.label} - labelId={`${field.name}-label`} - name={field.name} - disabled={field.disabled} - value={formData[field.name] ?? field.default ?? ''} - onChange={handleChange} - options={field.options} - required={field.required} - multiple={field.multiple} - error={hasFieldError} - helperText={inlineFieldError || field.helperText || ''} - /> - ) - case 'number': - return ( - <TextField - key={fieldKey} - name={field.name} - label={field.label} - type="number" - disabled={field.disabled} - InputProps={field.inputProps} - value={formData[field.name] ?? field.default ?? ''} - onChange={handleChange} - required={field.required} - error={hasFieldError} - helperText={ - inlineFieldError || (field.error ? field.helperText : '') - } - fullWidth - margin="normal" - className="textHighlight" - /> - ) - case 'input': { - const inputValue = - field.name === 'worker_ip' && Array.isArray(formData[field.name]) - ? formData[field.name].join(',') - : formData[field.name] ?? field.default ?? '' - - return ( - <TextField - key={fieldKey} - name={field.name} - label={field.label} - disabled={field.disabled} - InputProps={field.inputProps} - value={inputValue} - onChange={handleChange} - required={field.required} - error={hasFieldError} - helperText={ - inlineFieldError || - (field.showHelperText || field.error ? field.helperText : '') - } - placeholder={field.placeholder} - fullWidth - margin="normal" - className="textHighlight" - /> - ) - } - case 'switch': - return ( - <div key={fieldKey}> - <Tooltip title={field.tip} placement="top"> - <FormControlLabel - name={field.name} - label={field.label} - labelPlacement="start" - control={ - <Switch - checked={formData[field.name] ?? field.default ?? false} - /> - } - onChange={handleChange} - required={field.required} - /> - </Tooltip> - </div> - ) - case 'radio': - return ( - <div - key={fieldKey} - style={{ - display: 'flex', - alignItems: 'center', - gap: 10, - marginLeft: 15, - }} - > - <span>{field.label}</span> - <RadioGroup - row - name={field.name} - value={ - formData[field.name] ?? - field.default ?? - field.options?.[0]?.value ?? - '' - } - onChange={handleChange} - > - {field.options.map((item) => ( - <FormControlLabel - key={item.label} - value={item.value} - control={<Radio />} - label={item.label} - /> - ))} - </RadioGroup> - </div> - ) - case 'dynamicField': - return ( - <DynamicFieldList - key={fieldKey} - name={field.name} - label={field.label} - mode={field.mode} - keyPlaceholder={field.keyPlaceholder} - valuePlaceholder={field.valuePlaceholder} - value={formData[field.name]} - onChange={handleDynamicField} - keyOptions={field.keyOptions} - /> - ) - default: - return null - } - }) - } - - const renderButtonContent = () => { - if (isShowCancel) { - return <StopCircle sx={{ fontSize: 26 }} /> - } - if (isLoading) { - return <CircularProgress size={26} /> - } - - return <RocketLaunchOutlined sx={{ fontSize: 26 }} /> - } - - const handleClose = () => { - setSaveAutostart(false) - onClose() - } - - return ( - <Drawer open={open} onClose={handleClose} anchor="right"> - <Box className="drawerCard"> - <Box display="flex" alignItems="center" justifyContent="space-between"> - <Box display="flex" alignItems="center"> - <TitleTypography value={modelData.model_name} /> - {hasHistory && ( - <Chip - label={`${t('launchModel.configCache')} (${ - historyEntries.length - })`} - variant="outlined" - size="small" - color="primary" - onClick={() => setIsHistoryDialogOpen(true)} - onDelete={() => setHistoryToDelete(selectedHistoryEntry)} - /> - )} - </Box> - <Box display="flex" alignItems="center" gap={1}> - <Tooltip - title={t('launchModel.commandLineParsing')} - placement="top" - > - <ContentPasteGo - className="pasteText" - onClick={() => setIsOpenPasteDialog(true)} - /> - </Tooltip> - - {areRequiredFieldsFilled && ( - <CopyToCommandLine - getData={getFinalFormData} - predefinedKeys={llmAllDataKey} - /> - )} - </Box> - </Box> - - <Box - sx={{ - flex: 1, - display: 'flex', - flexDirection: 'column', - justifyContent: 'space-between', - }} - component="form" - onSubmit={handleSubmit} - > - <Box>{renderFormFields(modelFormConfig[modelType])}</Box> - - <Box marginTop={4}> - <Box height={16}> - {isShowProgress && ( - <Progress style={{ marginBottom: 20 }} progress={progress} /> - )} - </Box> - <FormControlLabel - sx={{ mb: 1 }} - control={ - <Switch - checked={saveAutostart} - disabled={isShowCancel || isLoading || isCallingApi} - onChange={(event) => setSaveAutostart(event.target.checked)} - /> - } - label={t('launchModel.saveAutostart')} - /> - <Box display="flex" gap={2}> - <Tooltip - title={ - isShowCancel ? ( - <Box sx={{ minWidth: 200 }}> - <Typography - variant="subtitle2" - sx={{ mb: 1, fontWeight: 600, color: 'inherit' }} - > - {t('launchModel.launchProgress')}: - </Typography> - {replicaStatuses.length > 0 ? ( - replicaStatuses.map((replica) => ( - <Box - key={replica.replica_id} - sx={{ - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - mb: 0.75, - gap: 1.5, - }} - > - <Box sx={{ minWidth: 0 }}> - <Typography - variant="caption" - display="block" - sx={{ fontWeight: 600, color: 'inherit' }} - > - {t('modelReplicaDetails.replica')}{' '} - {replica.replica_id}: - </Typography> - <Typography - variant="caption" - display="block" - sx={{ - fontFamily: 'monospace', - color: 'rgba(255, 255, 255, 0.82)', - lineHeight: 1.4, - wordBreak: 'break-all', - }} - > - {getReplicaWorkerAddress(replica)} - </Typography> - </Box> - <Chip - label={replica.status} - color={ - replica.status === 'READY' - ? 'success' - : replica.status === 'ERROR' - ? 'error' - : 'default' - } - size="small" - sx={{ - 'height': 22, - 'fontSize': '0.7rem', - 'fontWeight': 600, - '&.MuiChip-colorDefault': { - bgcolor: 'rgba(255, 255, 255, 0.14)', - color: '#fff', - }, - }} - /> - </Box> - )) - ) : ( - <Typography variant="caption" sx={{ color: 'inherit' }}> - {t('launchModel.initializing')} - </Typography> - )} - </Box> - ) : ( - t('launchModel.launch') - ) - } - placement="top" - arrow - slotProps={{ - tooltip: { - sx: { - bgcolor: 'rgba(17, 24, 39, 0.96)', - color: '#fff', - border: '1px solid rgba(255, 255, 255, 0.12)', - boxShadow: 6, - px: 1.5, - py: 1.25, - maxWidth: 360, - }, - }, - arrow: { - sx: { - color: 'rgba(17, 24, 39, 0.96)', - }, - }, - }} - > - <Button - style={{ flex: 1 }} - variant="outlined" - color="primary" - disabled={ - !isShowCancel && - (!areRequiredFieldsFilled || - isLoading || - isCallingApi || - checkDynamicFieldComplete.some( - (item) => !item.isComplete - )) - } - onClick={() => { - if (isShowCancel) { - fetchCancelModel() - } else { - handleSubmit() - } - }} - > - {renderButtonContent()} - </Button> - </Tooltip> - <Button - style={{ flex: 1 }} - variant="outlined" - color="primary" - onClick={handleClose} - title={t('launchModel.goBack')} - > - <UndoOutlined sx={{ fontSize: 26 }} /> - </Button> - </Box> - </Box> - </Box> - - <PasteDialog - open={isOpenPasteDialog} - onHandleClose={() => setIsOpenPasteDialog(false)} - onHandleCommandLine={handleCommandLine} - /> - - <Dialog - open={isHistoryDialogOpen} - onClose={() => setIsHistoryDialogOpen(false)} - fullWidth - maxWidth="sm" - > - <DialogTitle>{t('launchModel.configCache')}</DialogTitle> - <DialogContent dividers> - {historyEntries.length ? ( - historyEntries.map((entry, index) => { - const isSelected = entry.cache_key === selectedHistoryKey - return ( - <Paper - key={entry.cache_key} - variant="outlined" - sx={{ - p: 2, - mb: index === historyEntries.length - 1 ? 0 : 1.5, - borderColor: isSelected ? 'primary.main' : 'divider', - }} - > - <Box - sx={{ - display: 'flex', - justifyContent: 'space-between', - gap: 2, - flexWrap: 'wrap', - }} - > - <Box sx={{ minWidth: 0 }}> - <Box - sx={{ - display: 'flex', - alignItems: 'center', - gap: 1, - flexWrap: 'wrap', - mb: 0.5, - }} - > - <Typography variant="subtitle2"> - {entry.model_uid || t('launchModel.defaultConfig')} - </Typography> - </Box> - <Typography variant="body2" color="text.secondary"> - {t('modelReplicaDetails.modelUid')}:{' '} - {entry.model_uid || '--'} - </Typography> - <Typography variant="body2" color="text.secondary"> - {t('launchModel.lastUpdated')}:{' '} - {formatHistoryTime(entry.updated_at)} - </Typography> - {entry.created_by ? ( - <Typography variant="body2" color="text.secondary"> - {t('launchModel.createdBy')}: {entry.created_by} - </Typography> - ) : null} - </Box> - <Box - sx={{ - display: 'flex', - gap: 1, - alignItems: 'center', - flexWrap: 'wrap', - }} - > - <Button - size="small" - variant={isSelected ? 'contained' : 'outlined'} - onClick={() => loadHistoryEntry(entry)} - > - {t('launchModel.loadCache')} - </Button> - <Button - size="small" - color="error" - onClick={() => setHistoryToDelete(entry)} - > - {t('launchModel.deleteCache')} - </Button> - </Box> - </Box> - </Paper> - ) - }) - ) : ( - <Typography color="text.secondary"> - {t('launchModel.noConfigCache')} - </Typography> - )} - </DialogContent> - <DialogActions style={{ justifyContent: 'space-between' }}> - <Button - onClick={() => { - setFormData({}) - setCollapseState({}) - setSelectedHistoryKey(null) - setPendingHistory(null) - setIsHistoryDialogOpen(false) - }} - > - {t('launchModel.newCache')} - </Button> - <Button onClick={() => setIsHistoryDialogOpen(false)}> - {t('modelReplicaDetails.close')} - </Button> - </DialogActions> - </Dialog> - - <Dialog - open={!!historyToDelete} - onClose={() => setHistoryToDelete(null)} - aria-labelledby="delete-history-cache-title" - > - <DialogTitle id="delete-history-cache-title"> - {t('components.warning')} - </DialogTitle> - <DialogContent> - {t('launchModel.confirmDeleteConfigCache')} - </DialogContent> - <DialogActions> - <Button onClick={() => setHistoryToDelete(null)}> - {t('components.cancel')} - </Button> - <Button color="error" onClick={handleDeleteHistory} autoFocus> - {t('components.ok')} - </Button> - </DialogActions> - </Dialog> - </Box> - </Drawer> - ) -} - -export default LaunchModelDrawer diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/modelFormConfig.js b/xinference/ui/web/ui/src/scenes/launch_model/components/modelFormConfig.js deleted file mode 100644 index 7263b75a5b..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/modelFormConfig.js +++ /dev/null @@ -1,1287 +0,0 @@ -import { - additionalParameterTipList, - quantizationParametersTipList, -} from '../data/data' - -const createWorkerIpField = ( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText -) => ({ - name: 'worker_ip', - label: t('launchModel.workerIp.optional'), - type: workerFieldType, - multiple: workerFieldType === 'select', - options: workerItems, - disabled: workerFieldDisabled, - helperText: workerFieldHelperText, - showHelperText: Boolean(workerFieldHelperText), - placeholder: workerFieldType === 'input' ? 'ip1,ip2' : undefined, - visible: true, -}) - -export default function getModelFormConfig({ - t, - formData, - modelData, - gpuAvailable, - engineItems, - formatItems, - sizeItems, - quantizationItems, - getNGPURange, - downloadHubOptions, - enginesWithNWorker, - multimodalProjectorOptions, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText, -}) { - const ggufQuantizations = - modelData?.gguf_quantizations ?? - modelData?.model_specs?.find((spec) => spec.gguf_quantizations) - ?.gguf_quantizations - const config = { - LLM: [ - { - name: 'model_engine', - label: t('launchModel.modelEngine'), - type: 'select', - options: engineItems, - visible: true, - required: true, - }, - { - name: 'model_format', - label: t('launchModel.modelFormat'), - type: 'select', - options: formatItems, - visible: true, - disabled: !formData.model_engine, - required: true, - }, - { - name: 'model_size_in_billions', - label: t('launchModel.modelSize'), - type: 'select', - options: sizeItems, - visible: true, - disabled: !formData.model_format, - required: true, - }, - { - name: 'quantization', - label: t('launchModel.quantization'), - type: 'select', - options: quantizationItems, - visible: true, - disabled: !formData.model_size_in_billions, - required: true, - }, - { - name: 'multimodal_projector', - label: t('launchModel.multimodelProjector'), - type: 'select', - default: multimodalProjectorOptions[0], - options: multimodalProjectorOptions, - disabled: !formData.model_size_in_billions, - required: true, - visible: !!multimodalProjectorOptions.length, - }, - { - name: 'n_gpu', - label: t( - enginesWithNWorker.includes(formData.model_engine) - ? 'launchModel.nGPUPerWorker' - : 'launchModel.nGPU' - ), - type: 'select', - default: 'auto', - options: getNGPURange('LLM'), - disabled: !formData.quantization, - visible: true, - }, - { - name: 'n_gpu_layers', - label: t('launchModel.nGpuLayers'), - type: 'number', - default: -1, - inputProps: { - inputProps: { - min: -1, - }, - }, - disabled: !formData.quantization, - visible: !!['ggufv2', 'ggmlv3'].includes(formData.model_format), - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - disabled: !formData.quantization, - visible: true, - }, - { - name: 'enable_thinking', - label: t('launchModel.enableThinking'), - type: 'switch', - visible: !!modelData.model_ability?.includes('hybrid'), - default: true, - }, - { - name: 'reasoning_content', - label: t('launchModel.parsingReasoningContent'), - type: 'switch', - default: false, - }, - { - name: 'nested_section_optional', - label: t('launchModel.optionalConfigurations'), - type: 'collapse', - visible: true, - children: [ - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'n_worker', - label: t('launchModel.workerCount.optional'), - type: 'number', - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.n_worker && !/^[1-9]\d*$/.test(formData.n_worker), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: - !!formData.model_engine && - enginesWithNWorker.includes(formData.model_engine), - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: - !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu !== 'CPU', - }, - { - name: 'download_hub', - label: t('launchModel.downloadHub.optional'), - type: 'select', - options: downloadHubOptions, - visible: true, - }, - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'nested_section_lora', - label: t('launchModel.loraConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'lora_list', - label: t('launchModel.loraModelConfig'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'lora_name', - valuePlaceholder: 'local_path', - visible: true, - }, - ], - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - ], - }, - { - name: 'quantization_config', - label: t( - 'launchModel.additionalQuantizationParametersForInferenceEngine' - ), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - keyOptions: quantizationParametersTipList, - visible: - !!formData.model_engine && formData.model_engine === 'Transformers', - }, - { - name: 'custom', - label: `${t('launchModel.additionalParametersForInferenceEngine')}${ - formData.model_engine ? ': ' + formData.model_engine : '' - }`, - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - keyOptions: - additionalParameterTipList[ - formData.model_engine?.toLocaleLowerCase() - ], - visible: true, - }, - ], - embedding: [ - { - name: 'model_engine', - label: t('launchModel.modelEngine'), - type: 'select', - options: engineItems, - visible: true, - }, - { - name: 'model_format', - label: t('launchModel.modelFormat'), - type: 'select', - options: formatItems, - visible: true, - disabled: !formData.model_engine, - }, - { - name: 'quantization', - label: t('launchModel.quantization'), - type: 'select', - options: quantizationItems, - visible: true, - disabled: !formData.model_format, - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - visible: true, - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - disabled: !formData.quantization, - }, - { - name: 'n_gpu', - label: t('launchModel.device'), - type: 'select', - default: gpuAvailable === 0 ? 'CPU' : 'GPU', - options: getNGPURange('embedding'), - visible: true, - }, - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu === 'GPU', - }, - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'download_hub', - label: t('launchModel.downloadHub.optional'), - type: 'select', - options: downloadHubOptions, - visible: true, - }, - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'custom', - label: `${t('launchModel.additionalParametersForInferenceEngine')}${ - formData.model_engine ? ': ' + formData.model_engine : '' - }`, - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - rerank: [ - { - name: 'model_engine', - label: t('launchModel.modelEngine'), - type: 'select', - options: engineItems, - visible: true, - }, - { - name: 'model_format', - label: t('launchModel.modelFormat'), - type: 'select', - options: formatItems, - visible: true, - disabled: !formData.model_engine, - }, - { - name: 'quantization', - label: t('launchModel.quantization'), - type: 'select', - options: quantizationItems, - visible: true, - disabled: !formData.model_format, - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - visible: true, - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - }, - { - name: 'n_gpu', - label: t('launchModel.device'), - type: 'select', - default: gpuAvailable === 0 ? 'CPU' : 'GPU', - options: getNGPURange('rerank'), - visible: true, - }, - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu === 'GPU', - }, - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'download_hub', - label: t('launchModel.downloadHub.optional'), - type: 'select', - options: downloadHubOptions, - visible: true, - }, - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'gguf_quantization', - label: t('launchModel.GGUFQuantization.optional'), - type: 'select', - options: ['none', ...(ggufQuantizations || [])], - visible: !!ggufQuantizations, - }, - { - name: 'gguf_model_path', - label: t('launchModel.GGUFModelPath.optional'), - type: 'input', - visible: !!ggufQuantizations, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'custom', - label: t('launchModel.additionalParametersForInferenceEngine'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - image: [ - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - { - name: 'model_engine', - label: t('launchModel.modelEngine'), - type: 'select', - options: engineItems, - visible: !!engineItems?.length, - required: false, - }, - { - name: 'model_format', - label: t('launchModel.modelFormat'), - type: 'select', - options: formatItems, - visible: !!formatItems?.length, - disabled: !formData.model_engine, - }, - { - name: 'quantization', - label: t('launchModel.quantization'), - type: 'select', - options: quantizationItems, - visible: !!quantizationItems?.length, - disabled: !formData.model_format, - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - visible: true, - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - }, - { - name: 'n_gpu', - label: t('launchModel.nGPU'), - type: 'select', - default: 'auto', - options: getNGPURange('image'), - visible: true, - }, - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu !== 'CPU', - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'download_hub', - label: t('launchModel.downloadHub.optional'), - type: 'select', - options: downloadHubOptions, - visible: true, - }, - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'gguf_quantization', - label: t('launchModel.GGUFQuantization.optional'), - type: 'select', - options: ['none', ...(ggufQuantizations || [])], - visible: !!ggufQuantizations, - }, - { - name: 'gguf_model_path', - label: t('launchModel.GGUFModelPath.optional'), - type: 'input', - visible: !!ggufQuantizations, - }, - { - name: 'lightning_version', - label: t('launchModel.lightningVersions.optional'), - type: 'select', - options: ['none', ...(modelData.lightning_versions || [])], - visible: !!modelData.lightning_versions, - }, - { - name: 'lightning_model_path', - label: t('launchModel.lightningModelPath.optional'), - type: 'input', - visible: !!modelData.lightning_versions, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'cpu_offload', - label: t('launchModel.CPUOffload'), - type: 'switch', - default: false, - tip: t('launchModel.CPUOffload.tip'), - visible: true, - }, - { - name: 'nested_section_lora', - label: t('launchModel.loraConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'lora_list', - label: t('launchModel.loraModelConfig'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'lora_name', - valuePlaceholder: 'local_path', - visible: true, - }, - { - name: 'image_lora_load_kwargs', - label: t('launchModel.loraLoadKwargsForImageModel'), - type: 'dynamicField', - mode: 'key-value', - visible: true, - }, - { - name: 'image_lora_fuse_kwargs', - label: t('launchModel.loraFuseKwargsForImageModel'), - type: 'dynamicField', - mode: 'key-value', - visible: true, - }, - ], - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'custom', - label: t('launchModel.additionalParametersForInferenceEngine'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - audio: [ - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - visible: true, - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - }, - { - name: 'n_gpu', - label: t('launchModel.device'), - type: 'select', - default: gpuAvailable === 0 ? 'CPU' : 'GPU', - options: getNGPURange('audio'), - visible: true, - }, - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu === 'GPU', - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'download_hub', - label: t('launchModel.downloadHub.optional'), - type: 'select', - options: downloadHubOptions, - visible: true, - }, - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'gguf_quantization', - label: t('launchModel.GGUFQuantization.optional'), - type: 'select', - options: ['none', ...(ggufQuantizations || [])], - visible: !!ggufQuantizations, - }, - { - name: 'gguf_model_path', - label: t('launchModel.GGUFModelPath.optional'), - type: 'input', - visible: !!ggufQuantizations, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'custom', - label: t('launchModel.additionalParametersForInferenceEngine'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - video: [ - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - visible: true, - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - }, - { - name: 'n_gpu', - label: t('launchModel.device'), - type: 'select', - default: gpuAvailable === 0 ? 'CPU' : 'GPU', - options: getNGPURange('video'), - visible: true, - }, - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu === 'GPU', - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'download_hub', - label: t('launchModel.downloadHub.optional'), - type: 'select', - options: downloadHubOptions, - visible: true, - }, - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'gguf_quantization', - label: t('launchModel.GGUFQuantization.optional'), - type: 'select', - options: ['none', ...(ggufQuantizations || [])], - visible: !!ggufQuantizations, - }, - { - name: 'gguf_model_path', - label: t('launchModel.GGUFModelPath.optional'), - type: 'input', - visible: !!ggufQuantizations, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'cpu_offload', - label: t('launchModel.CPUOffload'), - type: 'switch', - default: false, - tip: t('launchModel.CPUOffload.tip'), - visible: true, - }, - { - name: 'nested_section_lora', - label: t('launchModel.loraConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'lora_list', - label: t('launchModel.loraModelConfig'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'lora_name', - valuePlaceholder: 'local_path', - visible: true, - }, - { - name: 'image_lora_load_kwargs', - label: t('launchModel.loraLoadKwargsForImageModel'), - type: 'dynamicField', - mode: 'key-value', - visible: true, - }, - { - name: 'image_lora_fuse_kwargs', - label: t('launchModel.loraFuseKwargsForImageModel'), - type: 'dynamicField', - mode: 'key-value', - visible: true, - }, - ], - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'custom', - label: t('launchModel.additionalParametersForInferenceEngine'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - flexible: [ - { - name: 'model_uid', - label: t('launchModel.modelUID.optional'), - type: 'input', - visible: true, - }, - { - name: 'replica', - label: t('launchModel.replica'), - type: 'number', - visible: true, - default: 1, - inputProps: { - inputProps: { - min: 1, - }, - }, - error: !!formData.replica && !/^[1-9]\d*$/.test(formData.replica), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - }, - { - name: 'n_gpu', - label: t('launchModel.device'), - type: 'select', - default: gpuAvailable === 0 ? 'CPU' : 'GPU', - options: getNGPURange('audio'), - visible: true, - }, - { - name: 'gpu_idx', - label: t('launchModel.GPUIdx'), - type: 'input', - error: !!formData.gpu_idx && !/^\d+(?:,\d+)*$/.test(formData.gpu_idx), - helperText: t('launchModel.enterCommaSeparatedNumbers'), - visible: !!formData.n_gpu && formData.n_gpu === 'GPU', - }, - createWorkerIpField( - t, - workerItems, - workerFieldType, - workerFieldDisabled, - workerFieldHelperText - ), - { - name: 'model_path', - label: t('launchModel.modelPath.optional'), - type: 'input', - visible: true, - }, - { - name: 'request_limits', - label: t('launchModel.requestLimits.optional'), - type: 'number', - inputProps: { - inputProps: { - min: 1, - }, - }, - error: - !!formData.request_limits && - !/^[1-9]\d*$/.test(formData.request_limits), - helperText: t('launchModel.enterIntegerGreaterThanZero'), - visible: true, - }, - { - name: 'nested_section_virtualEnv', - label: t('launchModel.virtualEnvConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'enable_virtual_env', - label: t('launchModel.modelVirtualEnv'), - type: 'radio', - options: [ - { label: 'Unset', value: 'unset' }, - { label: 'False', value: false }, - { label: 'True', value: true }, - ], - default: 'unset', - visible: true, - }, - { - name: 'virtual_env_packages', - label: t('launchModel.virtualEnvPackage'), - type: 'dynamicField', - mode: 'value', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'nested_section_env', - label: t('launchModel.envVariableConfig'), - type: 'collapse', - visible: true, - children: [ - { - name: 'envs', - label: t('launchModel.envVariable'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - }, - { - name: 'custom', - label: t('launchModel.additionalParametersForInferenceEngine'), - type: 'dynamicField', - mode: 'key-value', - keyPlaceholder: 'key', - valuePlaceholder: 'value', - visible: true, - }, - ], - } - - return config -} diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/pasteDialog.js b/xinference/ui/web/ui/src/scenes/launch_model/components/pasteDialog.js deleted file mode 100644 index 2dc6bffebc..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/pasteDialog.js +++ /dev/null @@ -1,147 +0,0 @@ -import { - Button, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - TextField, -} from '@mui/material' -import React, { useState } from 'react' -import { useTranslation } from 'react-i18next' - -const PasteDialog = ({ open, onHandleClose, onHandleCommandLine }) => { - const { t } = useTranslation() - const [command, setCommand] = useState('') - - const handleClose = () => { - onHandleClose() - setCommand('') - } - - const parseXinferenceCommand = () => { - const params = {} - const peftModelConfig = { - lora_list: [], - image_lora_load_kwargs: {}, - image_lora_fuse_kwargs: {}, - } - const quantizationConfig = {} - const virtualEnvPackages = [] - const envs = {} - - let newcommand = command.replace('xinference launch', '').trim() - const args = - newcommand.match( - /--[\w-]+(?:\s+(?:"[^"]*"|'[^']*'|(?:[^\s-][^\s]*\s*)+))?/g - ) || [] - - for (const arg of args) { - const match = arg - .trim() - .match(/^--([\w-]+)(?:\s+(?:"([^"]+)"|'([^']+)'|(.+)))?$/) - if (!match) continue - - const key = match[1] - const value = match[2] || match[3] || match[4] || '' - const normalizedKey = key.replace(/-/g, '_') - - if (normalizedKey === 'gpu_idx') { - params[normalizedKey] = value.split(',').map(Number) - } else if (normalizedKey === 'lora_modules') { - const loraPairs = value.split(/\s+/) - for (let i = 0; i < loraPairs.length; i += 2) { - const lora_name = loraPairs[i] - const local_path = loraPairs[i + 1] - if (lora_name && local_path) { - peftModelConfig.lora_list.push({ lora_name, local_path }) - } - } - } else if (normalizedKey === 'image_lora_load_kwargs') { - peftModelConfig.image_lora_load_kwargs = {} - const [load_param, load_value] = value.split(/\s+/) - peftModelConfig.image_lora_load_kwargs[load_param] = load_value - } else if (normalizedKey === 'image_lora_fuse_kwargs') { - peftModelConfig.image_lora_fuse_kwargs = {} - const [fuse_param, fuse_value] = value.split(/\s+/) - peftModelConfig.image_lora_fuse_kwargs[fuse_param] = fuse_value - } else if (normalizedKey === 'quantization_config') { - const [k, v] = value.split(/\s+/) - quantizationConfig[k] = v - } else if (key === 'enable-virtual-env') { - params.enable_virtual_env = true - } else if (key === 'disable-virtual-env') { - params.enable_virtual_env = false - } else if (normalizedKey === 'virtual_env_package') { - virtualEnvPackages.push(value) - } else if (normalizedKey === 'env') { - const [envKey, envVal] = value.split(/\s+/) - if (envKey && envVal !== undefined) { - envs[envKey] = envVal - } - } else { - if ( - ['enable_thinking', 'cpu_offload', 'reasoning_content'].includes( - normalizedKey - ) - ) { - params[normalizedKey] = value === 'true' - } else if (normalizedKey === 'size_in_billions') { - params['model_size_in_billions'] = value - } else { - params[normalizedKey] = value - } - } - } - - if ( - peftModelConfig.lora_list.length > 0 || - Object.keys(peftModelConfig.image_lora_load_kwargs)?.length > 0 || - Object.keys(peftModelConfig.image_lora_fuse_kwargs)?.length > 0 - ) { - params.peft_model_config = peftModelConfig - } - - if (Object.keys(quantizationConfig).length > 0) { - params.quantization_config = quantizationConfig - } - - if (virtualEnvPackages.length > 0) { - params.virtual_env_packages = virtualEnvPackages - } - - if (Object.keys(envs).length > 0) { - params.envs = envs - } - - onHandleCommandLine(params) - handleClose() - } - - return ( - <Dialog open={open}> - <DialogTitle>{t('launchModel.commandLineParsing')}</DialogTitle> - <DialogContent> - <div style={{ width: '500px', height: '120px' }}> - <TextField - multiline - fullWidth - rows={5} - placeholder={t('launchModel.placeholderTip')} - value={command} - onChange={(e) => { - setCommand(e.target.value) - }} - /> - </div> - </DialogContent> - <DialogActions> - <Button onClick={handleClose}>{t('launchModel.cancel')}</Button> - <Button autoFocus onClick={parseXinferenceCommand}> - {t('launchModel.confirm')} - </Button> - </DialogActions> - </Dialog> - ) -} - -export default PasteDialog diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/progress.js b/xinference/ui/web/ui/src/scenes/launch_model/components/progress.js deleted file mode 100644 index 816dd6a14f..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/progress.js +++ /dev/null @@ -1,12 +0,0 @@ -import LinearProgress from '@mui/material/LinearProgress' -import React from 'react' - -const Progress = ({ progress }) => { - return ( - <div style={{ marginBottom: 10 }}> - <LinearProgress variant="determinate" value={progress * 100} /> - </div> - ) -} - -export default Progress diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/selectField.js b/xinference/ui/web/ui/src/scenes/launch_model/components/selectField.js deleted file mode 100644 index e8e237c2db..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/selectField.js +++ /dev/null @@ -1,112 +0,0 @@ -import { - Checkbox, - FormControl, - FormHelperText, - InputLabel, - ListItemText, - MenuItem, - Select, -} from '@mui/material' -import { useEffect, useRef, useState } from 'react' - -const SelectField = ({ - label, - labelId, - name, - value, - onChange, - options = [], - disabled = false, - required = false, - multiple = false, - error = false, - helperText = '', -}) => { - const wrapperRef = useRef(null) - const [menuWidth, setMenuWidth] = useState(0) - - const normalizedValue = multiple - ? Array.isArray(value) - ? value - : value - ? [value] - : [] - : value - - const optionLabelMap = new Map( - options.map((item) => [item.value ?? item, item.label ?? item]) - ) - - useEffect(() => { - if (wrapperRef.current) { - setMenuWidth(wrapperRef.current.offsetWidth) - } - }, []) - - return ( - <div ref={wrapperRef}> - <FormControl - variant="outlined" - margin="normal" - disabled={disabled} - required={required} - fullWidth - error={error} - > - <InputLabel id={labelId}>{label}</InputLabel> - <Select - labelId={labelId} - name={name} - multiple={multiple} - value={normalizedValue} - onChange={onChange} - label={label} - className="textHighlight" - renderValue={ - multiple - ? (selected) => - selected - .map((item) => optionLabelMap.get(item) ?? item) - .join(', ') - : undefined - } - MenuProps={{ - PaperProps: { - sx: { - width: menuWidth, - maxWidth: menuWidth, - }, - }, - }} - > - {options.map((item) => { - const itemValue = item.value ?? item - const itemLabel = item.label ?? item - return ( - <MenuItem - key={itemValue} - value={itemValue} - disabled={item.disabled} - sx={{ - whiteSpace: 'normal', - }} - > - {multiple ? ( - <> - <Checkbox checked={normalizedValue.includes(itemValue)} /> - <ListItemText primary={itemLabel} /> - </> - ) : ( - itemLabel - )} - </MenuItem> - ) - })} - </Select> - {helperText ? <FormHelperText>{helperText}</FormHelperText> : null} - </FormControl> - </div> - ) -} - -export default SelectField diff --git a/xinference/ui/web/ui/src/scenes/launch_model/components/virtualenvListDialog.js b/xinference/ui/web/ui/src/scenes/launch_model/components/virtualenvListDialog.js deleted file mode 100644 index ca3e2ba1dc..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/components/virtualenvListDialog.js +++ /dev/null @@ -1,242 +0,0 @@ -import { Close, Delete } from '@mui/icons-material' -import { - Box, - Dialog, - DialogContent, - DialogTitle, - IconButton, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TablePagination, - TableRow, - Tooltip, -} from '@mui/material' -import { styled } from '@mui/material/styles' -import React, { useContext, useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../../components/apiContext' -import CopyComponent from '../../../components/copyComponent' -import DeleteDialog from '../../../components/deleteDialog' -import fetchWrapper from '../../../components/fetchWrapper' - -const VirtualEnvListDialog = ({ open, onClose, onUpdate, modelData }) => { - const { t } = useTranslation() - const { setErrorMsg } = useContext(ApiContext) - const [virtualenvListArr, setVirtualenvListArr] = useState([]) - const [page, setPage] = useState(0) - const [isDeleteVirtualenv, setIsDeleteVirtualenv] = useState(false) - const [selectedVirtualEnv, setSelectedVirtualEnv] = useState(null) - - const StyledTableRow = styled(TableRow)(({ theme }) => ({ - '&:nth-of-type(odd)': { - backgroundColor: theme.palette.action.hover, - }, - })) - - const emptyRows = - page >= 0 ? Math.max(0, (1 + page) * 5 - virtualenvListArr.length) : 0 - - const getVirtualenvList = () => { - if (!modelData?.model_name) return - - fetchWrapper - .get(`/v1/virtualenvs?model_name=${modelData.model_name}`) - .then((data) => { - setVirtualenvListArr(data.list) - // Always reset to page 0 since we only show one model's virtual environment - setPage(0) - }) - .catch((error) => { - if (error.response.status !== 403) { - setErrorMsg(error.message) - } - }) - } - - const buildDeleteQuery = (virtualEnv) => { - const params = new URLSearchParams() - if (virtualEnv?.model_name) params.set('model_name', virtualEnv.model_name) - if (virtualEnv?.model_engine) - params.set('model_engine', virtualEnv.model_engine) - if (virtualEnv?.python_version) - params.set('python_version', virtualEnv.python_version) - if (virtualEnv?.actor_ip_address) - params.set('worker_ip', virtualEnv.actor_ip_address) - return params.toString() - } - - const handleDeleteVirtualenv = () => { - if (!selectedVirtualEnv?.model_name) { - setIsDeleteVirtualenv(false) - return - } - fetchWrapper - .delete(`/v1/virtualenvs?${buildDeleteQuery(selectedVirtualEnv)}`) - .then(() => { - getVirtualenvList() - setIsDeleteVirtualenv(false) - setSelectedVirtualEnv(null) - }) - .catch((error) => { - console.error(error) - if (!error.response || error.response.status !== 403) - setErrorMsg(error.message) - }) - } - - const handleChangePage = (_, newPage) => { - setPage(newPage) - } - - const handleOpenDeleteVirtualenvDialog = (virtualEnv) => { - setSelectedVirtualEnv(virtualEnv) - setIsDeleteVirtualenv(true) - } - - const handleCloseVirtualenvList = () => { - onClose() - onUpdate() - } - - useEffect(() => { - if (open) getVirtualenvList() - }, [open]) - - return ( - <> - <Dialog - open={open} - onClose={onClose} - maxWidth="xl" - aria-labelledby="virtualenv-dialog-title" - aria-describedby="virtualenv-dialog-description" - > - <DialogTitle sx={{ m: 0, p: 2 }} id="customized-dialog-title"> - {modelData?.model_name || t('launchModel.manageVirtualEnvironments')} - </DialogTitle> - <Box - sx={(theme) => ({ - position: 'absolute', - right: 8, - top: 8, - color: theme.palette.grey[500], - })} - > - <Close - style={{ cursor: 'pointer' }} - onClick={handleCloseVirtualenvList} - /> - </Box> - <DialogContent> - <TableContainer component={Paper}> - <Table - sx={{ minWidth: 700 }} - style={{ height: '500px', width: '100%' }} - stickyHeader - aria-label="virtualenv pagination table" - > - <TableHead> - <TableRow> - <TableCell align="left"> - {t('launchModel.modelName')} - </TableCell> - <TableCell align="left">{t('launchModel.envPath')}</TableCell> - <TableCell align="left" style={{ width: 46 }}></TableCell> - <TableCell align="left"> - {t('launchModel.pythonVersion')} - </TableCell> - <TableCell align="left"> - {t('launchModel.ipAddress')} - </TableCell> - <TableCell align="left"> - {t('launchModel.operation')} - </TableCell> - </TableRow> - </TableHead> - <TableBody style={{ position: 'relative' }}> - {virtualenvListArr.slice(page * 5, page * 5 + 5).map((row) => ( - <StyledTableRow - style={{ maxHeight: 90 }} - key={ - row.path || - `${row.model_name}-${row.model_engine || 'default'}-${ - row.python_version || 'unknown' - }` - } - > - <TableCell component="th" scope="row"> - <Tooltip title={row.model_name}> - <div className="pathBox" style={{ maxWidth: 150 }}> - {row.model_name} - </div> - </Tooltip> - </TableCell> - <TableCell> - <Tooltip title={row.path}> - <div className="pathBox" style={{ maxWidth: 200 }}> - {row.path} - </div> - </Tooltip> - </TableCell> - <TableCell> - <CopyComponent - tip={t('launchModel.copyEnvPath')} - text={row.path} - /> - </TableCell> - <TableCell>{row.python_version || '—'}</TableCell> - <TableCell>{row.actor_ip_address}</TableCell> - <TableCell align="center"> - <Tooltip title={t('launchModel.delete')}> - <IconButton - aria-label="delete" - size="large" - onClick={() => handleOpenDeleteVirtualenvDialog(row)} - > - <Delete /> - </IconButton> - </Tooltip> - </TableCell> - </StyledTableRow> - ))} - {emptyRows > 0 && ( - <TableRow style={{ height: 89.4 * emptyRows }}> - <TableCell /> - </TableRow> - )} - {virtualenvListArr.length === 0 && ( - <div className="empty"> - {t('launchModel.noVirtualEnvironmentsForNow')} - </div> - )} - </TableBody> - </Table> - </TableContainer> - <TablePagination - style={{ float: 'right' }} - rowsPerPageOptions={[5]} - count={virtualenvListArr.length} - rowsPerPage={5} - page={page} - onPageChange={handleChangePage} - /> - </DialogContent> - </Dialog> - - {/* Delete Confirmation Dialog */} - <DeleteDialog - text={t('launchModel.confirmDeleteVirtualEnv')} - isDelete={isDeleteVirtualenv} - onHandleIsDelete={() => setIsDeleteVirtualenv(false)} - onHandleDelete={handleDeleteVirtualenv} - /> - </> - ) -} - -export default VirtualEnvListDialog diff --git a/xinference/ui/web/ui/src/scenes/launch_model/data/data.js b/xinference/ui/web/ui/src/scenes/launch_model/data/data.js deleted file mode 100644 index 27bf00133a..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/data/data.js +++ /dev/null @@ -1,81 +0,0 @@ -export const llmAllDataKey = [ - 'model_uid', - 'model_name', - 'model_type', - 'model_engine', - 'model_format', - 'model_size_in_billions', - 'quantization', - 'n_worker', - 'n_gpu', - 'n_gpu_layers', - 'replica', - 'request_limits', - 'worker_ip', - 'gpu_idx', - 'download_hub', - 'model_path', - 'reasoning_content', - 'gguf_quantization', - 'gguf_model_path', - 'lightning_version', - 'lightning_model_path', - 'cpu_offload', - 'peft_model_config', - 'quantization_config', - 'enable_thinking', - 'multimodal_projector', - 'enable_virtual_env', - 'virtual_env_packages', - 'envs', -] - -export const additionalParameterTipList = { - 'transformers': ['torch_dtype', 'device', 'enable_flash_attn'], - 'llama.cpp': ['n_ctx', 'use_mmap', 'use_mlock'], - 'vllm': [ - 'block_size', - 'gpu_memory_utilization', - 'max_num_seqs', - 'max_model_len', - 'guided_decoding_backend', - 'scheduling_policy', - 'tensor_parallel_size', - 'pipeline_parallel_size', - 'enable_prefix_caching', - 'enable_chunked_prefill', - 'enable_expert_parallel', - 'enforce_eager', - 'cpu_offload_gb', - 'disable_custom_all_reduce', - 'limit_mm_per_prompt', - 'model_quantization', - 'mm_processor_kwargs', - 'min_pixels', - 'max_pixels', - ], - 'sglang': [ - 'mem_fraction_static', - 'attention_reduce_in_fp32', - 'tp_size', - 'dp_size', - 'chunked_prefill_size', - 'cpu_offload_gb', - 'enable_dp_attention', - 'enable_ep_moe', - ], - 'mlx': ['cache_limit_gb', 'max_kv_size'], -} - -export const quantizationParametersTipList = [ - 'load_in_8bit', - 'load_in_4bit', - 'llm_int8_threshold', - 'llm_int8_skip_modules', - 'llm_int8_enable_fp32_cpu_offload', - 'llm_int8_has_fp16_weight', - 'bnb_4bit_compute_dtype', - 'bnb_4bit_quant_type', - 'bnb_4bit_use_double_quant', - 'bnb_4bit_quant_storage', -] diff --git a/xinference/ui/web/ui/src/scenes/launch_model/index.js b/xinference/ui/web/ui/src/scenes/launch_model/index.js deleted file mode 100644 index fa52cf493b..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/index.js +++ /dev/null @@ -1,204 +0,0 @@ -import { LoadingButton, TabContext, TabList, TabPanel } from '@mui/lab' -import { Box, MenuItem, Select, Tab } from '@mui/material' -import React, { useContext, useEffect, useRef, useState } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import ErrorMessageSnackBar from '../../components/errorMessageSnackBar' -import fetchWrapper from '../../components/fetchWrapper' -import SuccessMessageSnackBar from '../../components/successMessageSnackBar' -import Title from '../../components/Title' -import { isValidBearerToken } from '../../components/utils' -import LaunchCustom from './launchCustom' -import LaunchModelComponent from './LaunchModel' - -const LaunchModel = () => { - const [value, setValue] = React.useState( - sessionStorage.getItem('modelType') - ? sessionStorage.getItem('modelType') - : '/launch_model/llm' - ) - const [gpuAvailable, setGPUAvailable] = useState(-1) - const [modelType, setModelType] = useState('llm') - const [loading, setLoading] = useState(false) - - const { setErrorMsg } = useContext(ApiContext) - const [cookie] = useCookies(['token']) - const navigate = useNavigate() - const { t } = useTranslation() - const LaunchModelRefs = useRef({}) - - const handleTabChange = (newValue) => { - setValue(newValue) - navigate(newValue) - sessionStorage.setItem('modelType', newValue) - newValue === '/launch_model/custom/llm' - ? sessionStorage.setItem('subType', newValue) - : '' - } - - useEffect(() => { - if ( - sessionStorage.getItem('auth') === 'true' && - !isValidBearerToken(sessionStorage.getItem('token')) && - !isValidBearerToken(cookie.token) - ) { - navigate('/login', { replace: true }) - } - - if (gpuAvailable === -1) { - fetchWrapper - .get('/v1/cluster/devices') - .then((data) => setGPUAvailable(parseInt(data, 10))) - .catch((error) => { - console.error('Error:', error) - if (error.response.status !== 403 && error.response.status !== 401) { - setErrorMsg(error.message) - } - }) - } - }, [cookie.token]) - - const updateList = (modelType) => { - LaunchModelRefs.current[modelType]?.update() - } - - const updateModels = () => { - setLoading(true) - fetchWrapper - .post('/v1/models/update_type', { model_type: modelType }) - .then(() => { - handleTabChange(`/launch_model/${modelType}`) - updateList(modelType) - }) - .catch((error) => { - console.error('Error:', error) - if (error.response.status !== 403 && error.response.status !== 401) { - setErrorMsg(error.message) - } - }) - .finally(() => { - setLoading(false) - }) - } - - return ( - <Box m="20px"> - <Title title={t('menu.launchModel')} /> - <ErrorMessageSnackBar /> - <SuccessMessageSnackBar /> - <TabContext value={value}> - <Box - sx={{ - borderBottom: 1, - borderColor: 'divider', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - }} - > - <TabList - value={value} - onChange={(_, value) => handleTabChange(value)} - aria-label="tabs" - > - <Tab label={t('model.languageModels')} value="/launch_model/llm" /> - <Tab - label={t('model.embeddingModels')} - value="/launch_model/embedding" - /> - <Tab label={t('model.rerankModels')} value="/launch_model/rerank" /> - <Tab label={t('model.imageModels')} value="/launch_model/image" /> - <Tab label={t('model.audioModels')} value="/launch_model/audio" /> - <Tab label={t('model.videoModels')} value="/launch_model/video" /> - <Tab - label={t('model.customModels')} - value="/launch_model/custom/llm" - /> - </TabList> - <Box sx={{ display: 'flex', gap: 0 }}> - <Select - value={modelType} - onChange={(e) => setModelType(e.target.value)} - size="small" - sx={{ - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - minWidth: 100, - }} - > - <MenuItem value="llm">LLM</MenuItem> - <MenuItem value="embedding">Embedding</MenuItem> - <MenuItem value="rerank">Rerank</MenuItem> - <MenuItem value="image">Image</MenuItem> - <MenuItem value="audio">Audio</MenuItem> - <MenuItem value="video">Video</MenuItem> - </Select> - - <LoadingButton - variant="contained" - onClick={updateModels} - loading={loading} - sx={{ - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - whiteSpace: 'nowrap', - }} - > - {t('launchModel.update')} - </LoadingButton> - </Box> - </Box> - <TabPanel value="/launch_model/llm" sx={{ padding: 0 }}> - <LaunchModelComponent - modelType={'LLM'} - gpuAvailable={gpuAvailable} - ref={(ref) => (LaunchModelRefs.current.llm = ref)} - /> - </TabPanel> - <TabPanel value="/launch_model/embedding" sx={{ padding: 0 }}> - <LaunchModelComponent - modelType={'embedding'} - gpuAvailable={gpuAvailable} - ref={(ref) => (LaunchModelRefs.current.embedding = ref)} - /> - </TabPanel> - <TabPanel value="/launch_model/rerank" sx={{ padding: 0 }}> - <LaunchModelComponent - modelType={'rerank'} - gpuAvailable={gpuAvailable} - ref={(ref) => (LaunchModelRefs.current.rerank = ref)} - /> - </TabPanel> - <TabPanel value="/launch_model/image" sx={{ padding: 0 }}> - <LaunchModelComponent - modelType={'image'} - gpuAvailable={gpuAvailable} - ref={(ref) => (LaunchModelRefs.current.image = ref)} - /> - </TabPanel> - <TabPanel value="/launch_model/audio" sx={{ padding: 0 }}> - <LaunchModelComponent - modelType={'audio'} - gpuAvailable={gpuAvailable} - ref={(ref) => (LaunchModelRefs.current.audio = ref)} - /> - </TabPanel> - <TabPanel value="/launch_model/video" sx={{ padding: 0 }}> - <LaunchModelComponent - modelType={'video'} - gpuAvailable={gpuAvailable} - ref={(ref) => (LaunchModelRefs.current.video = ref)} - /> - </TabPanel> - <TabPanel value="/launch_model/custom/llm" sx={{ padding: 0 }}> - <LaunchCustom gpuAvailable={gpuAvailable} /> - </TabPanel> - </TabContext> - </Box> - ) -} - -export default LaunchModel diff --git a/xinference/ui/web/ui/src/scenes/launch_model/launchCustom.js b/xinference/ui/web/ui/src/scenes/launch_model/launchCustom.js deleted file mode 100644 index 7197b8e076..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/launchCustom.js +++ /dev/null @@ -1,184 +0,0 @@ -import { TabContext, TabList, TabPanel } from '@mui/lab' -import { Box, FormControl, Tab } from '@mui/material' -import React, { useContext, useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import fetchWrapper from '../../components/fetchWrapper' -import HotkeyFocusTextField from '../../components/hotkeyFocusTextField' -import LaunchModelDrawer from './components/launchModelDrawer' -import ModelCard from './modelCard' - -const customType = ['llm', 'embedding', 'rerank', 'image', 'audio', 'flexible'] - -const LaunchCustom = ({ gpuAvailable }) => { - let endPoint = useContext(ApiContext).endPoint - const [registrationData, setRegistrationData] = useState([]) - const { isCallingApi, setIsCallingApi } = useContext(ApiContext) - const { isUpdatingModel } = useContext(ApiContext) - - // States used for filtering - const [searchTerm, setSearchTerm] = useState('') - const [value, setValue] = useState(sessionStorage.getItem('subType')) - const [selectedModel, setSelectedModel] = useState(null) - const [isOpenLaunchModelDrawer, setIsOpenLaunchModelDrawer] = useState(false) - const { t } = useTranslation() - - const navigate = useNavigate() - const handleTabChange = (_, newValue) => { - const type = - newValue.split('/')[3] === 'llm' ? 'LLM' : newValue.split('/')[3] - update(type) - setValue(newValue) - navigate(newValue) - sessionStorage.setItem('subType', newValue) - } - - const handleSearchChange = (event) => { - setSearchTerm(event.target.value) - } - - const filter = (registration) => { - if (!registration || typeof searchTerm !== 'string') return false - const modelName = registration.model_name - ? registration.model_name.toLowerCase() - : '' - return modelName.includes(searchTerm.toLowerCase()) - } - - useEffect(() => { - const type = sessionStorage.getItem('subType').split('/')[3] - update(type === 'llm' ? 'LLM' : type) - }, []) - - const update = async (type) => { - if (isCallingApi || isUpdatingModel) return - try { - setIsCallingApi(true) - - const data = await fetchWrapper.get(`/v1/model_registrations/${type}`) - const customRegistrations = data.filter((data) => !data.is_builtin) - - const newData = await Promise.all( - customRegistrations.map(async (registration) => { - const desc = await fetchWrapper.get( - `/v1/model_registrations/${type}/${registration.model_name}` - ) - - return { - ...desc, - is_builtin: registration.is_builtin, - } - }) - ) - setRegistrationData(newData) - } catch (error) { - console.error('Error:', error) - } finally { - setIsCallingApi(false) - } - } - - const style = { - display: 'grid', - gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))', - paddingLeft: '2rem', - paddingBottom: '2rem', - gridGap: '2rem 0rem', - } - - return ( - <Box m="20px"> - <TabContext value={value}> - <Box sx={{ borderBottom: 1, borderColor: 'divider' }}> - <TabList value={value} onChange={handleTabChange} aria-label="tabs"> - <Tab - label={t('model.languageModels')} - value="/launch_model/custom/llm" - /> - <Tab - label={t('model.embeddingModels')} - value="/launch_model/custom/embedding" - /> - <Tab - label={t('model.rerankModels')} - value="/launch_model/custom/rerank" - /> - <Tab - label={t('model.imageModels')} - value="/launch_model/custom/image" - /> - <Tab - label={t('model.audioModels')} - value="/launch_model/custom/audio" - /> - <Tab - label={t('model.flexibleModels')} - value="/launch_model/custom/flexible" - /> - </TabList> - </Box> - {customType.map((item) => ( - <TabPanel - key={item} - value={`/launch_model/custom/${item}`} - sx={{ padding: 0 }} - > - <div - style={{ - display: 'grid', - gridTemplateColumns: '1fr', - margin: '30px 2rem', - }} - > - <FormControl variant="outlined" margin="normal"> - <HotkeyFocusTextField - id="search" - type="search" - label={t('launchModel.search')} - value={searchTerm} - onChange={handleSearchChange} - size="small" - hotkey="Enter" - t={t} - /> - </FormControl> - </div> - <div style={style}> - {registrationData - .filter((registration) => filter(registration)) - .map((filteredRegistration) => ( - <ModelCard - key={filteredRegistration.model_name} - url={endPoint} - modelData={filteredRegistration} - gpuAvailable={gpuAvailable} - is_custom={true} - modelType={item === 'llm' ? 'LLM' : item} - onUpdate={update} - onClick={() => { - setSelectedModel(filteredRegistration) - setIsOpenLaunchModelDrawer(true) - }} - /> - ))} - </div> - {selectedModel && ( - <LaunchModelDrawer - key={selectedModel.model_name} - modelData={selectedModel} - modelType={item === 'llm' ? 'LLM' : item} - gpuAvailable={gpuAvailable} - open={isOpenLaunchModelDrawer} - onClose={() => setIsOpenLaunchModelDrawer(false)} - /> - )} - </TabPanel> - ))} - </TabContext> - </Box> - ) -} - -export default LaunchCustom diff --git a/xinference/ui/web/ui/src/scenes/launch_model/modelCard.js b/xinference/ui/web/ui/src/scenes/launch_model/modelCard.js deleted file mode 100644 index b1939240f5..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/modelCard.js +++ /dev/null @@ -1,562 +0,0 @@ -import './styles/modelCardStyle.css' - -import { - ChatOutlined, - Computer, - Delete, - EditNote, - EditNoteOutlined, - Grade, - HelpCenterOutlined, - StarBorder, -} from '@mui/icons-material' -import { - Box, - Button, - Chip, - IconButton, - Paper, - Stack, - Tooltip, - Typography, -} from '@mui/material' -import React, { useContext, useEffect, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import DeleteDialog from '../../components/deleteDialog' -import fetchWrapper from '../../components/fetchWrapper' -import TitleTypography from '../../components/titleTypography' -import CachedListDialog from './components/cachedListDialog' -import EditCustomModel from './components/editCustomModelDialog' -import VirtualEnvListDialog from './components/virtualenvListDialog' - -const modelAbilityIcons = { - chat: <ChatOutlined />, - generate: <EditNoteOutlined />, - default: <HelpCenterOutlined />, -} - -const ModelCard = ({ - modelData, - modelType, - is_custom = false, - onGetCollectionArr, - onUpdate, - onClick, - virtualEnvs = [], -}) => { - const navigate = useNavigate() - const { t } = useTranslation() - const { setErrorMsg } = useContext(ApiContext) - const [isHovered, setIsHovered] = useState(false) - const [isDeleteCustomModel, setIsDeleteCustomModel] = useState(false) - const [isJsonShow, setIsJsonShow] = useState(false) - const [isOpenCachedList, setIsOpenCachedList] = useState(false) - const [isOpenVirtualenvList, setIsOpenVirtualenvList] = useState(false) - const [hasVirtualEnv, setHasVirtualEnv] = useState(null) // null = not checked yet - - const descriptionContainerRef = useRef(null) - const descriptionTextRef = useRef(null) - const detailsButtonRef = useRef(null) - const [descClamp, setDescClamp] = useState(5) - - const measureClamp = () => { - const container = descriptionContainerRef.current - const textEl = descriptionTextRef.current - const btnEl = detailsButtonRef.current - if (!container || !textEl) return - const containerHeight = container.clientHeight - const btnHeight = btnEl ? btnEl.offsetHeight : 0 - const btnStyle = btnEl ? window.getComputedStyle(btnEl) : null - const btnMarginTop = btnStyle ? parseFloat(btnStyle.marginTop) || 0 : 0 - const btnMarginBottom = btnStyle - ? parseFloat(btnStyle.marginBottom) || 0 - : 0 - const computed = window.getComputedStyle(textEl) - const lineHeightPx = parseFloat(computed.lineHeight) - const textMarginTop = parseFloat(computed.marginTop) || 0 - const textMarginBottom = parseFloat(computed.marginBottom) || 0 - if (!lineHeightPx || !containerHeight) return - const availableHeight = Math.max( - 0, - containerHeight - - btnHeight - - btnMarginTop - - btnMarginBottom - - textMarginTop - - textMarginBottom - ) - const maxLines = Math.floor(availableHeight / lineHeightPx) - const clamped = Math.max(1, Math.min(5, maxLines - 1)) - setDescClamp(clamped) - } - - useEffect(() => { - measureClamp() - }, [modelData, isHovered, hasVirtualEnv]) - - useEffect(() => { - const el = descriptionContainerRef.current - if (!el) return - const ro = new ResizeObserver(() => measureClamp()) - ro.observe(el) - window.addEventListener('resize', measureClamp) - return () => { - ro.disconnect() - window.removeEventListener('resize', measureClamp) - } - }, []) - - const isCached = (spec) => { - if (Array.isArray(spec.cache_status)) { - return spec.cache_status.some((cs) => cs) - } else { - return spec.cache_status === true - } - } - - // Check if model has virtual environment using virtualEnvs data from parent - useEffect(() => { - if (modelData?.model_name) { - const hasEnv = virtualEnvs.some( - (env) => env.model_name === modelData.model_name - ) - setHasVirtualEnv(hasEnv) - } - }, [modelData?.model_name, virtualEnvs]) - - // Handle favorite feature - const handleCollection = (shouldAdd) => { - const collectionArr = - JSON.parse(localStorage.getItem('collectionArr')) || [] - const updatedCollection = shouldAdd - ? [...collectionArr, modelData.model_name] - : collectionArr.filter((item) => item !== modelData.model_name) - - localStorage.setItem('collectionArr', JSON.stringify(updatedCollection)) - onGetCollectionArr?.(updatedCollection) - } - - // Retrieve model language array - const getModelLanguages = () => { - // Check possible language field names - const lang = modelData?.model_lang || modelData?.language - - if (!lang) return [] - return Array.isArray(lang) ? lang : [lang] - } - - // Render generic chip component - const renderChips = ({ items, variant = 'default', onClick }) => { - if (!items || items.length === 0) return null - - return items.map((item) => ( - <Chip - key={item} - label={item} - size="small" - variant={variant} - onClick={(e) => { - e?.stopPropagation() - onClick?.(e) - }} - /> - )) - } - - const renderAbilityChips = () => { - const abilities = modelData?.model_ability - if (!abilities) return null - - const abilityArray = Array.isArray(abilities) ? abilities : [abilities] - return renderChips({ items: abilityArray }) - } - - const renderLanguageChips = () => { - const languages = getModelLanguages() - return renderChips({ - items: languages, - variant: 'outlined', - }) - } - - const renderCacheChip = () => { - const hasCachedSpecs = modelData?.model_specs?.some((spec) => - isCached(spec) - ) - if (!hasCachedSpecs) return null - - return ( - <Chip - label={t('launchModel.manageCachedModels')} - variant="outlined" - color="primary" - size="small" - deleteIcon={<EditNote />} - onDelete={handleOpenCachedList} - onClick={(e) => { - e?.stopPropagation() - handleOpenCachedList() - }} - /> - ) - } - - const renderVirtualEnvChip = () => { - // Only show if we've determined the model might have a virtual environment - if (!hasVirtualEnv) return null - - return ( - <Chip - label={t('launchModel.manageVirtualEnvironments')} - variant="outlined" - color="secondary" - size="small" - deleteIcon={<Computer />} - onDelete={() => setIsOpenVirtualenvList(true)} - onClick={(e) => { - e?.stopPropagation() - setIsOpenVirtualenvList(true) - }} - /> - ) - } - - // Check if already favorited - const isFavorite = () => { - const collectionArr = - JSON.parse(localStorage.getItem('collectionArr')) || [] - return collectionArr.includes(modelData.model_name) - } - - // Render favorite/unfavorite button - const renderFavoriteButton = () => { - const favorite = isFavorite() - const icon = favorite ? ( - <Grade style={{ color: 'rgb(255, 206, 0)' }} /> - ) : ( - <StarBorder /> - ) - - const tooltipTitle = favorite - ? t('launchModel.unfavorite') - : t('launchModel.favorite') - - return ( - <Tooltip title={tooltipTitle} placement="top"> - <IconButton - aria-label={favorite ? 'collection' : 'cancellation-of-collections'} - onClick={(e) => { - e?.stopPropagation() - handleCollection(!favorite) - }} - > - {icon} - </IconButton> - </Tooltip> - ) - } - - // Render custom model action buttons - const renderCustomModelActions = () => ( - <> - <Tooltip title={t('launchModel.edit')} placement="top"> - <IconButton - aria-label="show" - onClick={(e) => { - e?.stopPropagation() - setIsJsonShow(true) - }} - > - <EditNote /> - </IconButton> - </Tooltip> - <Tooltip title={t('launchModel.delete')} placement="top"> - <IconButton - aria-label="delete" - onClick={(e) => { - e?.stopPropagation() - setIsDeleteCustomModel(true) - }} - > - <Delete /> - </IconButton> - </Tooltip> - </> - ) - - const MetricItem = ({ value, label, icon }) => ( - <Box - sx={{ - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - minWidth: 80, - }} - > - {icon && React.cloneElement(icon, { sx: { fontSize: 20, mb: 0.5 } })} - {value && ( - <Typography variant="body2" sx={{ fontWeight: 600, fontSize: '1.2em' }}> - {value} - </Typography> - )} - <Typography - variant="caption" - color="text.secondary" - sx={{ fontWeight: 600, fontSize: '0.8em' }} - > - {label} - </Typography> - </Box> - ) - - // Delete custom model - const handeCustomDelete = (e) => { - e.stopPropagation() - - const subType = sessionStorage.getItem('subType').split('/') - if (subType) { - subType[3] - fetchWrapper - .delete( - `/v1/model_registrations/${ - subType[3] === 'llm' ? 'LLM' : subType[3] - }/${modelData.model_name}` - ) - .then(() => { - onUpdate(subType[3] === 'llm' ? 'LLM' : subType[3]) - setIsDeleteCustomModel(false) - }) - .catch((error) => { - console.error(error) - if (error.response.status !== 403) { - setErrorMsg(error.message) - } - }) - } - } - - const handleJsonDataPresentation = () => { - const arr = sessionStorage.getItem('subType').split('/') - sessionStorage.setItem( - 'registerModelType', - `/register_model/${arr[arr.length - 1]}` - ) - sessionStorage.setItem('customJsonData', JSON.stringify(modelData)) - navigate(`/register_model/${arr[arr.length - 1]}/${modelData.model_name}`) - } - - const handleOpenCachedList = () => { - setIsOpenCachedList(true) - } - - const detailUrl = `https://model.xinference.io/models/detail/${encodeURIComponent( - modelData?.model_name || '' - )}` - - const renderDetailsButton = () => { - if (is_custom) return null - return ( - <Button - ref={detailsButtonRef} - component="a" - href={detailUrl} - target="_blank" - rel="noopener noreferrer" - variant="text" - size="small" - sx={{ mt: 0.5 }} - onClick={(e) => { - e.stopPropagation() - }} - > - {t('launchModel.moreDetails')} - </Button> - ) - } - - return ( - <> - <Tooltip title={modelData.model_name} placement="top"> - <Paper - className="container" - onMouseEnter={() => setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - elevation={isHovered ? 24 : 4} - onClick={onClick} - > - <Box className="descriptionCard"> - <Box> - <Box className="cardTitle"> - <TitleTypography value={modelData.model_name} /> - <Box className="iconButtonBox"> - {is_custom - ? renderCustomModelActions() - : renderFavoriteButton()} - </Box> - </Box> - - <Stack - spacing={1} - direction="row" - useFlexGap - flexWrap="wrap" - sx={{ marginLeft: 1 }} - > - {renderAbilityChips()} - {renderLanguageChips()} - {renderCacheChip()} - {renderVirtualEnvChip()} - </Stack> - </Box> - - <Box - ref={descriptionContainerRef} - sx={{ - flex: 1, - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - color: 'text.secondary', - }} - > - {modelData.model_description ? ( - <> - <Box - component="p" - ref={descriptionTextRef} - sx={{ - m: 0, - mt: 0.5, - display: '-webkit-box', - WebkitLineClamp: descClamp, - WebkitBoxOrient: 'vertical', - overflow: 'hidden', - textOverflow: 'ellipsis', - fontSize: '14px', - lineHeight: '20px', - paddingInline: '10px', - }} - title={modelData.model_description} - > - {modelData.model_description} - </Box> - </> - ) : ( - <> - {isHovered && ( - <Box - component="p" - sx={{ - m: 0, - textAlign: 'center', - fontStyle: 'italic', - }} - > - {t('launchModel.clickToLaunchModel')} - </Box> - )} - </> - )} - {renderDetailsButton()} - </Box> - - {modelType === 'LLM' && ( - <Box - sx={{ - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - }} - > - <MetricItem - value={`${Math.floor(modelData.context_length / 1000)}K`} - label={t('launchModel.contextLength')} - /> - - <MetricItem - icon={ - modelData.model_ability?.includes('chat') - ? modelAbilityIcons.chat - : modelData.model_ability?.includes('generate') - ? modelAbilityIcons.generate - : modelAbilityIcons.default - } - label={ - modelData.model_ability?.includes('chat') - ? t('launchModel.chatModel') - : modelData.model_ability?.includes('generate') - ? t('launchModel.generateModel') - : t('launchModel.otherModel') - } - /> - </Box> - )} - - {(modelData.dimensions || modelData.max_tokens) && ( - <Box - sx={{ - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - }} - > - <Box> - {modelData.dimensions && ( - <MetricItem - value={modelData.dimensions} - label={t('launchModel.dimensions')} - /> - )} - </Box> - - <Box> - {modelData.max_tokens && ( - <MetricItem - value={modelData.max_tokens} - label={t('launchModel.maxTokens')} - /> - )} - </Box> - </Box> - )} - </Box> - </Paper> - </Tooltip> - - <DeleteDialog - text={t('launchModel.confirmDeleteCustomModel')} - isDelete={isDeleteCustomModel} - onHandleIsDelete={() => setIsDeleteCustomModel(false)} - onHandleDelete={handeCustomDelete} - /> - - <CachedListDialog - open={isOpenCachedList} - modelData={modelData} - modelType={modelType} - onClose={() => setIsOpenCachedList(false)} - onUpdate={onUpdate} - /> - - <VirtualEnvListDialog - open={isOpenVirtualenvList} - onClose={() => setIsOpenVirtualenvList(false)} - onUpdate={onUpdate} - modelData={modelData} - /> - - <EditCustomModel - open={isJsonShow} - modelData={modelData} - onClose={() => setIsJsonShow(false)} - handleJsonDataPresentation={handleJsonDataPresentation} - /> - </> - ) -} - -export default ModelCard diff --git a/xinference/ui/web/ui/src/scenes/launch_model/styles/modelCardStyle.css b/xinference/ui/web/ui/src/scenes/launch_model/styles/modelCardStyle.css deleted file mode 100644 index b46f06c8be..0000000000 --- a/xinference/ui/web/ui/src/scenes/launch_model/styles/modelCardStyle.css +++ /dev/null @@ -1,93 +0,0 @@ -.container { - display: block; - position: relative; - width: 300px; - height: 300px; - cursor: pointer; - border-radius: 20px !important; -} -.descriptionCard { - display: flex; - flex-direction: column; - justify-content: space-between; - position: relative; - top: -1px; - left: -1px; - width: 300px; - height: 300px; - padding: 20px; - border-radius: 20px; -} -.cardTitle { - display: flex; - justify-content: space-between; -} -.iconButtonBox { - display: flex; - align-items: center; -} -.drawerCard { - position: relative; - display: flex; - flex-direction: column; - padding: 20px 80px 100px; - min-height: 100%; - width: 60vw; - min-width: 350px; - overflow-y: scroll; -} -.pasteText { - font-size: 18px !important; - color: #1976d2; - cursor: pointer; - margin-inline: 10px; -} -.pasteText:hover { - color: #1976d2b3; -} -.copyToCommandLine { - font-size: 16px !important; - color: #1976d2; - cursor: pointer; -} -.copyToCommandLine:hover { - color: #1976d2b3; -} -.css-1be5mm1-MuiLinearProgress-root-MuiMobileStepper-progress { - width: 100% !important; -} -.css-r5rjnf-MuiLinearProgress-root-MuiMobileStepper-progress { - width: 100% !important; -} -.pathBox { - width: 160px; - cursor: pointer; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -.pathBox2 { - width: 300px; -} -.empty { - position: absolute; - left: 50%; - top: 30%; - font-size: 20px; - color: #555; - transform: translate(-50%, 0); -} -.deleteDialog { - display: flex; - align-items: center; -} -.warningIcon { - margin-right: 10px; - color: rgb(237, 108, 2); -} -.textHighlight .MuiSelect-select { - color: #1976d2; -} -.textHighlight .MuiInputBase-input { - color: #1976d2; -} diff --git a/xinference/ui/web/ui/src/scenes/login/header.js b/xinference/ui/web/ui/src/scenes/login/header.js deleted file mode 100644 index 65c01dec42..0000000000 --- a/xinference/ui/web/ui/src/scenes/login/header.js +++ /dev/null @@ -1,36 +0,0 @@ -import { AppBar, Box, Toolbar } from '@mui/material' -import Typography from '@mui/material/Typography' - -import icon from '../../media/icon.png' - -export default function Header() { - return ( - <AppBar - elevation={0} - color="transparent" - sx={{ - backdropFilter: 'blur(20px)', - borderBottom: 1, - borderColor: 'grey.300', - zIndex: (theme) => theme.zIndex.drawer + 1, - }} - > - <Toolbar sx={{ justifyContent: 'start' }}> - <Box - component="img" - alt="profile" - src={icon} - height="60px" - width="60px" - borderRadius="50%" - sx={{ objectFit: 'cover', mr: 1.5 }} - /> - <Box textAlign="left"> - <Typography fontWeight="bold" fontSize="1.7rem"> - {'Xinference'} - </Typography> - </Box> - </Toolbar> - </AppBar> - ) -} diff --git a/xinference/ui/web/ui/src/scenes/login/login.js b/xinference/ui/web/ui/src/scenes/login/login.js deleted file mode 100644 index 3aa3940052..0000000000 --- a/xinference/ui/web/ui/src/scenes/login/login.js +++ /dev/null @@ -1,151 +0,0 @@ -import { Box, Divider } from '@mui/material' -import Button from '@mui/material/Button' -import Container from '@mui/material/Container' -import TextField from '@mui/material/TextField' -import Typography from '@mui/material/Typography' -import * as React from 'react' -import { Fragment, useContext, useEffect, useState } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import ErrorMessageSnackBar from '../../components/errorMessageSnackBar' -import { getEndpoint } from '../../components/utils' -import Header from './header' - -function Login() { - const { t } = useTranslation() - const [, setCookie] = useCookies(['token']) - const navigate = useNavigate() - const [username, setUsername] = useState('') - const [password, setPassword] = useState('') - const [oidcEnabled, setOidcEnabled] = useState(false) - const { setErrorMsg } = useContext(ApiContext) - const endpoint = getEndpoint() - - useEffect(() => { - fetch(endpoint + '/v1/cluster/ui_config', { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - }).then((res) => { - if (res.ok) { - res.json().then((data) => { - setOidcEnabled(data.oidc_enabled || false) - }) - } - }) - }, []) - - const handleSubmit = () => { - fetch(endpoint + '/token', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - username: username, - password: password, - }), - }).then((res) => { - if (!res.ok) { - res.json().then((errorData) => { - setErrorMsg( - `Login failed: ${res.status} - ${ - errorData.detail || 'Unknown error' - }` - ) - }) - } else { - res.json().then((data) => { - setCookie('token', data['access_token'], { path: '/' }) - sessionStorage.setItem('token', data['access_token']) - if (data['refresh_token']) { - sessionStorage.setItem('refresh_token', data['refresh_token']) - } - if (data['must_change_password']) { - navigate('/change_password') - } else { - navigate('/launch_model/llm') - } - }) - } - }) - } - - return ( - <Fragment> - <Header /> - <Container component="main" maxWidth="xl" sx={{ marginTop: 20 }}> - <ErrorMessageSnackBar /> - <Box - sx={{ - marginTop: 8, - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - }} - > - <Typography component="h1" variant="h5"> - LOGIN - </Typography> - <Box component="main" noValidate sx={{ mt: 1 }}> - <TextField - margin="normal" - required - fullWidth - id="username" - label="Username" - name="username" - value={username} - onChange={(e) => { - setUsername(e.target.value) - }} - autoFocus - /> - <TextField - margin="normal" - required - fullWidth - name="password" - label="Password" - type="password" - id="password" - autoComplete="current-password" - value={password} - onChange={(e) => { - setPassword(e.target.value) - }} - /> - <Button - type="submit" - fullWidth - variant="contained" - sx={{ mt: 3, mb: 2 }} - onClick={handleSubmit} - > - Sign In - </Button> - {oidcEnabled && ( - <> - <Divider sx={{ my: 2 }}>{t('login.or')}</Divider> - <Button - fullWidth - variant="outlined" - sx={{ mb: 2 }} - onClick={() => { - window.location.href = endpoint + '/api/oidc/authorize' - }} - > - {t('login.sso')} - </Button> - </> - )} - </Box> - </Box> - </Container> - </Fragment> - ) -} - -export default Login diff --git a/xinference/ui/web/ui/src/scenes/logs/index.js b/xinference/ui/web/ui/src/scenes/logs/index.js deleted file mode 100644 index d8f3a2577e..0000000000 --- a/xinference/ui/web/ui/src/scenes/logs/index.js +++ /dev/null @@ -1,1522 +0,0 @@ -import 'dayjs/locale/ja' -import 'dayjs/locale/ko' -import 'dayjs/locale/zh-cn' - -import { - AccessTime, - AddCircleOutline, - ArticleOutlined, - CalendarToday, - Check as CheckIcon, - Close as CloseIcon, - ContentCopy as ContentCopyIcon, - ExpandMore as ExpandMoreIcon, - Refresh as RefreshIcon, - RemoveCircleOutline, - Search as SearchIcon, - Tag as TagIcon, - TextFields as TextFieldsIcon, -} from '@mui/icons-material' -import { - Box, - Button, - Chip, - CircularProgress, - Collapse, - Dialog, - DialogContent, - DialogTitle, - Divider, - FormControl, - IconButton, - InputAdornment, - Menu, - MenuItem, - MenuList, - Popover, - Select, - Tab, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - Tabs, - TextField, - Toolbar, - Tooltip, - Typography, -} from '@mui/material' -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' -import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker' -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider' -import React, { - useCallback, - useContext, - useEffect, - useRef, - useState, -} from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../components/apiContext' -import Title from '../../components/Title' - -const FONT_SIZE = '0.813rem' - -const DAYJS_LOCALE_MAP = { en: 'en', zh: 'zh-cn', ja: 'ja', ko: 'ko' } - -const LEVELS = ['ERROR', 'WARNING', 'INFO', 'DEBUG'] -const LOG_TYPES = ['worker', 'supervisor'] - -const TIME_RANGES = [ - { labelKey: 'monitoring.time.15m', from: 'now-15m', to: 'now' }, - { labelKey: 'monitoring.time.1h', from: 'now-1h', to: 'now' }, - { labelKey: 'monitoring.time.6h', from: 'now-6h', to: 'now' }, - { labelKey: 'monitoring.time.24h', from: 'now-24h', to: 'now' }, - { labelKey: 'monitoring.time.2d', from: 'now-2d', to: 'now' }, - { labelKey: 'monitoring.time.7d', from: 'now-7d', to: 'now' }, -] - -const PAGE_SIZE = 200 - -const REFRESH_OPTIONS = [ - { labelKey: 'monitoring.refresh.off', value: 0 }, - { labelKey: 'monitoring.refresh.10s', value: 10000 }, - { labelKey: 'monitoring.refresh.30s', value: 30000 }, - { labelKey: 'monitoring.refresh.1m', value: 60000 }, - { labelKey: 'monitoring.refresh.5m', value: 300000 }, -] - -const DATE_TIME_SLOT_PROPS = { - textField: { - size: 'small', - fullWidth: true, - sx: { - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - '& .MuiInputLabel-root': { fontSize: FONT_SIZE }, - }, - }, - popper: { - sx: { - '& .MuiDayCalendar-weekDayLabel': { fontSize: FONT_SIZE }, - '& .MuiPickersDay-root': { fontSize: FONT_SIZE }, - }, - }, -} - -const PICKER_LOCALE_TEXT = { - en: { okButtonLabel: 'OK', cancelButtonLabel: 'Cancel' }, - zh: { okButtonLabel: '确定', cancelButtonLabel: '取消' }, - ja: { okButtonLabel: '確定', cancelButtonLabel: 'キャンセル' }, - ko: { okButtonLabel: '확인', cancelButtonLabel: '취소' }, -} - -const LEVEL_COLORS = { - ERROR: 'error.main', - WARNING: 'warning.main', - DEBUG: 'text.disabled', -} - -function copyToClipboard(text) { - if (navigator.clipboard) { - return navigator.clipboard.writeText(text) - } - const textarea = document.createElement('textarea') - textarea.value = text - document.body.appendChild(textarea) - textarea.select() - document.execCommand('copy') - document.body.removeChild(textarea) - return Promise.resolve() -} - -function HighlightText({ text, keywords }) { - if (!text) return '' - const validKeywords = ( - Array.isArray(keywords) ? keywords : [keywords] - ).filter((k) => k && typeof k === 'string' && k.trim()) - if (!validKeywords.length) return text - const escaped = validKeywords - .sort((a, b) => b.length - a.length) - .map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')) - .join('|') - const parts = String(text).split(new RegExp(`(${escaped})`, 'gi')) - const lowerSet = new Set(validKeywords.map((k) => k.toLowerCase())) - return parts.map((part, i) => - lowerSet.has(part.toLowerCase()) ? ( - <mark key={i} style={{ background: '#ffe082', padding: 0 }}> - {part} - </mark> - ) : ( - part - ) - ) -} - -function FieldTypeIcon({ fieldKey, value }) { - if (fieldKey === '@timestamp') - return <CalendarToday sx={{ fontSize: 14, color: 'text.disabled' }} /> - if (typeof value === 'number') - return <TagIcon sx={{ fontSize: 14, color: 'text.disabled' }} /> - return <TextFieldsIcon sx={{ fontSize: 14, color: 'text.disabled' }} /> -} - -function formatFieldValue(value) { - if (value === null || value === undefined) return '-' - if (typeof value === 'object') return JSON.stringify(value) - return String(value) -} - -function DetailRow({ - row, - onFilter, - fieldFilters, - appliedSearch, - selectedLevels, - selectedLogType, - endPoint, - onViewContext, - nodeField, -}) { - const [tab, setTab] = useState(0) - const [copied, setCopied] = useState(false) - const copyTimerRef = useRef(null) - const { t } = useTranslation() - - useEffect(() => { - return () => { - if (copyTimerRef.current) clearTimeout(copyTimerRef.current) - } - }, []) - - const handleCopyJson = () => { - copyToClipboard(JSON.stringify(row, null, 2)).then(() => { - setCopied(true) - copyTimerRef.current = setTimeout(() => setCopied(false), 1500) - }) - } - - const fields = Object.entries(row).filter( - ([, v]) => v !== undefined && v !== null && v !== '' - ) - - const activeFilterMap = new Map() - if (fieldFilters) { - fieldFilters.forEach((f) => { - if (f.op === '+') { - if (!activeFilterMap.has(f.key)) activeFilterMap.set(f.key, new Set()) - activeFilterMap.get(f.key).add(f.value) - } - }) - } - if (selectedLevels && selectedLevels.length) { - if (!activeFilterMap.has('level')) activeFilterMap.set('level', new Set()) - selectedLevels.forEach((v) => activeFilterMap.get('level').add(v)) - } - if (selectedLogType) { - if (!activeFilterMap.has('log_type')) - activeFilterMap.set('log_type', new Set()) - activeFilterMap.get('log_type').add(selectedLogType) - } - - const [contextOpen, setContextOpen] = useState(false) - - const handleViewContext = (e) => { - e.stopPropagation() - if (onViewContext) { - onViewContext(row) - } else { - setContextOpen(true) - } - } - - return ( - <Box sx={{ px: 2, pb: 2 }}> - <Box - sx={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - }} - > - <Tabs - value={tab} - onChange={(_, v) => setTab(v)} - sx={{ - 'minHeight': 32, - '& .MuiTab-root': { - minHeight: 32, - fontSize: FONT_SIZE, - textTransform: 'none', - py: 0.5, - }, - }} - > - <Tab label={t('logs.detail.tableTab')} /> - <Tab label={t('logs.detail.jsonTab')} /> - </Tabs> - <Button - size="small" - startIcon={<ArticleOutlined sx={{ fontSize: 16 }} />} - onClick={handleViewContext} - sx={{ - fontSize: FONT_SIZE, - textTransform: 'none', - whiteSpace: 'nowrap', - }} - > - {t('logs.detail.viewContext')} - </Button> - </Box> - {tab === 0 ? ( - <Table size="small" sx={{ mt: 1 }}> - <TableHead> - <TableRow> - <TableCell - sx={{ fontSize: FONT_SIZE, width: 80, fontWeight: 600 }} - > - {t('logs.detail.action')} - </TableCell> - <TableCell - sx={{ fontSize: FONT_SIZE, width: 200, fontWeight: 600 }} - > - {t('logs.detail.field')} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE, fontWeight: 600 }}> - {t('logs.detail.value')} - </TableCell> - </TableRow> - </TableHead> - <TableBody> - {fields.map(([key, val]) => { - const isFilterMatch = - activeFilterMap.has(key) && - activeFilterMap.get(key).has(String(val)) - const valueKeywords = [] - if (appliedSearch) valueKeywords.push(appliedSearch) - if (isFilterMatch) valueKeywords.push(String(val)) - - return ( - <TableRow - key={key} - hover - sx={isFilterMatch ? { bgcolor: '#fff8e1' } : undefined} - > - <TableCell sx={{ fontSize: FONT_SIZE, p: 0.5 }}> - <Tooltip title={t('logs.detail.filterFor')}> - <IconButton - size="small" - onClick={(e) => { - e.stopPropagation() - if (onFilter) onFilter(key, val, '+') - }} - > - <AddCircleOutline sx={{ fontSize: 16 }} /> - </IconButton> - </Tooltip> - <Tooltip title={t('logs.detail.filterOut')}> - <IconButton - size="small" - onClick={(e) => { - e.stopPropagation() - if (onFilter) onFilter(key, val, '-') - }} - > - <RemoveCircleOutline sx={{ fontSize: 16 }} /> - </IconButton> - </Tooltip> - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <Box - sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }} - > - <FieldTypeIcon fieldKey={key} value={val} /> - <HighlightText - text={key} - keywords={appliedSearch ? [appliedSearch] : []} - /> - </Box> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - wordBreak: 'break-all', - fontFamily: 'monospace', - }} - > - <HighlightText - text={formatFieldValue(val)} - keywords={valueKeywords} - /> - </TableCell> - </TableRow> - ) - })} - </TableBody> - </Table> - ) : ( - <Box - sx={{ - mt: 1, - p: 1.5, - bgcolor: 'action.hover', - borderRadius: 1, - overflow: 'auto', - maxHeight: 400, - position: 'relative', - }} - > - <Tooltip - title={copied ? t('logs.detail.copied') : t('logs.detail.copyJson')} - > - <IconButton - size="small" - onClick={handleCopyJson} - sx={{ position: 'absolute', top: 4, right: 4 }} - > - {copied ? ( - <CheckIcon sx={{ fontSize: 16 }} /> - ) : ( - <ContentCopyIcon sx={{ fontSize: 16 }} /> - )} - </IconButton> - </Tooltip> - <pre - style={{ - margin: 0, - fontSize: FONT_SIZE, - fontFamily: 'monospace', - whiteSpace: 'pre-wrap', - wordBreak: 'break-all', - }} - > - {JSON.stringify(row, null, 2)} - </pre> - </Box> - )} - {!onViewContext && ( - <ContextDialog - open={contextOpen} - onClose={() => setContextOpen(false)} - anchorRow={row} - endPoint={endPoint} - nodeField={nodeField} - /> - )} - </Box> - ) -} - -function ContextDialog({ open, onClose, anchorRow, endPoint, nodeField }) { - const { t } = useTranslation() - const [currentAnchor, setCurrentAnchor] = useState(anchorRow) - const [olderSize, setOlderSize] = useState(5) - const [newerSize, setNewerSize] = useState(5) - const [olderLoadCount, setOlderLoadCount] = useState(5) - const [newerLoadCount, setNewerLoadCount] = useState(5) - const [older, setOlder] = useState([]) - const [newer, setNewer] = useState([]) - const [hasMoreOlder, setHasMoreOlder] = useState(false) - const [hasMoreNewer, setHasMoreNewer] = useState(false) - const [loading, setLoading] = useState(false) - const [error, setError] = useState(null) - const [expandedRow, setExpandedRow] = useState(null) - const [localFieldFilters, setLocalFieldFilters] = useState([]) - const anchorRef = useRef(null) - - useEffect(() => { - if (open && anchorRow) setCurrentAnchor(anchorRow) - }, [open, anchorRow]) - - const timestamp = currentAnchor ? currentAnchor['@timestamp'] : null - - useEffect(() => { - if (!open || !timestamp) return - setLoading(true) - setError(null) - - const params = new URLSearchParams() - params.set('timestamp', timestamp) - params.set('size', String(Math.max(olderSize, newerSize))) - if (currentAnchor.node) params.set('node', currentAnchor.node) - if (nodeField && nodeField !== 'node') params.set('node_field', nodeField) - - const token = sessionStorage.getItem('token') - const headers = { 'Content-Type': 'application/json' } - if (token) headers['Authorization'] = `Bearer ${token}` - - fetch(endPoint + '/v1/cluster/logs/context?' + params.toString(), { - headers, - }) - .then((res) => { - if (res.status === 404) { - setError('notFound') - return null - } - if (!res.ok) throw new Error(`HTTP ${res.status}`) - return res.json() - }) - .then((data) => { - if (!data) return - setOlder((data.older || []).slice(0, olderSize)) - setNewer((data.newer || []).slice(0, newerSize)) - setHasMoreOlder(data.has_more_older || false) - setHasMoreNewer(data.has_more_newer || false) - }) - .catch(() => setError('fetchError')) - .finally(() => setLoading(false)) - }, [open, timestamp, olderSize, newerSize, currentAnchor, endPoint]) - - useEffect(() => { - if (!loading && anchorRef.current) { - anchorRef.current.scrollIntoView({ block: 'center', behavior: 'smooth' }) - } - }, [loading, older, newer]) - - const resetState = () => { - setOlderSize(5) - setNewerSize(5) - setOlderLoadCount(5) - setNewerLoadCount(5) - setOlder([]) - setNewer([]) - setError(null) - setExpandedRow(null) - setLocalFieldFilters([]) - } - - const handleClose = () => { - resetState() - onClose() - } - - const handleSwitchAnchor = (row) => { - resetState() - setCurrentAnchor(row) - } - - const handleLocalFilter = useCallback((key, value, op) => { - const valStr = String(value) - setLocalFieldFilters((prev) => { - const exists = prev.find( - (f) => f.key === key && f.value === valStr && f.op === op - ) - if (exists) return prev.filter((f) => f !== exists) - return [...prev, { key, value: valStr, op }] - }) - }, []) - - const clampCount = (val) => Math.max(1, Math.min(500, Number(val) || 1)) - - const filterRows = (rows) => { - if (!localFieldFilters.length) return rows - const plusByKey = {} - const minusFilters = [] - localFieldFilters.forEach((f) => { - if (f.op === '+') { - if (!plusByKey[f.key]) plusByKey[f.key] = [] - plusByKey[f.key].push(f.value) - } else { - minusFilters.push(f) - } - }) - return rows.filter((row) => { - for (const [key, values] of Object.entries(plusByKey)) { - if (!values.includes(String(row[key]))) return false - } - for (const f of minusFilters) { - if (String(row[f.key]) === f.value) return false - } - return true - }) - } - - const formatTime = (ts) => { - if (!ts) return '' - const d = new Date(ts) - return d.toLocaleString([], { - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', - hour12: false, - }) - } - - const colSpan = 5 - - const renderLoadBar = (direction) => { - const isNewer = direction === 'newer' - const count = isNewer ? newerLoadCount : olderLoadCount - const setCount = isNewer ? setNewerLoadCount : setOlderLoadCount - const setSize = isNewer ? setNewerSize : setOlderSize - const hasMore = isNewer ? hasMoreNewer : hasMoreOlder - if (!hasMore) return null - return ( - <TableRow> - <TableCell colSpan={colSpan} sx={{ py: 0.5 }}> - <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}> - <Button - size="small" - onClick={() => setSize((s) => s + clampCount(count))} - sx={{ fontSize: FONT_SIZE, textTransform: 'none' }} - > - {t(isNewer ? 'logs.detail.loadNewer' : 'logs.detail.loadOlder')} - </Button> - <TextField - size="small" - type="number" - value={count} - onChange={(e) => setCount(clampCount(e.target.value))} - onBlur={(e) => setCount(clampCount(e.target.value))} - onKeyDown={(e) => { - if (e.key === 'Enter') setSize((s) => s + clampCount(count)) - }} - inputProps={{ - min: 1, - max: 500, - style: { - fontSize: FONT_SIZE, - width: 48, - textAlign: 'center', - padding: '2px 4px', - }, - }} - sx={{ '& .MuiOutlinedInput-root': { height: 28 } }} - /> - <Typography sx={{ fontSize: FONT_SIZE, color: 'text.secondary' }}> - {t(isNewer ? 'logs.detail.newerDocs' : 'logs.detail.olderDocs')} - </Typography> - </Box> - </TableCell> - </TableRow> - ) - } - - const renderContextRow = (row, rowKey, isAnchor) => { - const isExpanded = expandedRow === rowKey - return ( - <React.Fragment key={rowKey}> - <TableRow - ref={isAnchor ? anchorRef : undefined} - sx={{ - ...(isAnchor ? { bgcolor: '#e3f2fd' } : undefined), - 'cursor': 'pointer', - '& > *': { borderBottom: isExpanded ? 'none' : undefined }, - }} - hover={!isAnchor} - onClick={() => setExpandedRow(isExpanded ? null : rowKey)} - > - <TableCell sx={{ fontSize: FONT_SIZE, p: 0.5, width: 32 }}> - <ExpandMoreIcon - fontSize="small" - sx={{ - transform: isExpanded ? 'rotate(180deg)' : 'none', - transition: 'transform 0.2s', - }} - /> - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE, whiteSpace: 'nowrap' }}> - {formatTime(row['@timestamp'])} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <Typography - component="span" - sx={{ - fontSize: FONT_SIZE, - fontWeight: 600, - color: LEVEL_COLORS[row.level] || 'text.primary', - }} - > - {row.level} - </Typography> - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}>{row.node}</TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - maxWidth: 0, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }} - > - {row.message} - </TableCell> - </TableRow> - <TableRow> - <TableCell sx={{ p: 0 }} colSpan={colSpan}> - <Collapse in={isExpanded} timeout="auto" unmountOnExit> - <DetailRow - row={row} - onFilter={handleLocalFilter} - fieldFilters={localFieldFilters} - appliedSearch="" - selectedLevels={[]} - selectedLogType="" - endPoint={endPoint} - onViewContext={handleSwitchAnchor} - nodeField={nodeField} - /> - </Collapse> - </TableCell> - </TableRow> - </React.Fragment> - ) - } - - const newerDesc = filterRows([...newer].reverse()) - const filteredOlder = filterRows(older) - - return ( - <Dialog open={open} onClose={handleClose} fullWidth maxWidth="lg"> - <DialogTitle - sx={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - fontSize: FONT_SIZE, - py: 1.5, - }} - > - {t('logs.detail.contextTitle')} - <IconButton size="small" onClick={handleClose}> - <CloseIcon fontSize="small" /> - </IconButton> - </DialogTitle> - <DialogContent dividers sx={{ p: 0 }}> - {loading && ( - <Box sx={{ display: 'flex', justifyContent: 'center', py: 4 }}> - <CircularProgress size={28} /> - </Box> - )} - {error === 'notFound' && ( - <Box sx={{ py: 4, textAlign: 'center' }}> - <Typography color="text.secondary"> - {t('logs.detail.contextError')} - </Typography> - </Box> - )} - {error === 'fetchError' && ( - <Box sx={{ py: 4, textAlign: 'center' }}> - <Typography color="error"> - {t('logs.detail.contextFetchError')} - </Typography> - </Box> - )} - {!loading && !error && ( - <> - {localFieldFilters.length > 0 && ( - <Box - sx={{ - display: 'flex', - flexWrap: 'wrap', - gap: 0.5, - px: 2, - py: 0.5, - borderBottom: 1, - borderColor: 'divider', - alignItems: 'center', - }} - > - {localFieldFilters.map((f, i) => ( - <Chip - key={`${f.op}${f.key}:${f.value}-${i}`} - label={ - f.op === '-' - ? `NOT ${f.key}: ${f.value}` - : `${f.key}: ${f.value}` - } - size="small" - color={f.op === '-' ? 'error' : 'default'} - variant={f.op === '-' ? 'outlined' : 'filled'} - onDelete={() => - setLocalFieldFilters((prev) => - prev.filter((_, idx) => idx !== i) - ) - } - sx={{ fontSize: FONT_SIZE }} - /> - ))} - <Chip - label={t('logs.clearFilters', 'Clear all')} - size="small" - variant="outlined" - onClick={() => setLocalFieldFilters([])} - sx={{ fontSize: FONT_SIZE }} - /> - </Box> - )} - <TableContainer sx={{ maxHeight: '60vh' }}> - <Table size="small" stickyHeader> - <TableHead> - <TableRow> - <TableCell sx={{ width: 32, fontSize: FONT_SIZE }} /> - <TableCell sx={{ width: 150, fontSize: FONT_SIZE }}> - {t('logs.time')} - </TableCell> - <TableCell sx={{ width: 80, fontSize: FONT_SIZE }}> - {t('logs.level')} - </TableCell> - <TableCell sx={{ width: 160, fontSize: FONT_SIZE }}> - {t('logs.node')} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - {t('logs.message')} - </TableCell> - </TableRow> - </TableHead> - <TableBody> - {renderLoadBar('newer')} - {newerDesc.map((row, idx) => - renderContextRow(row, `newer-${idx}`, false) - )} - {currentAnchor && - renderContextRow(currentAnchor, 'anchor', true)} - {filteredOlder.map((row, idx) => - renderContextRow(row, `older-${idx}`, false) - )} - {renderLoadBar('older')} - </TableBody> - </Table> - </TableContainer> - </> - )} - </DialogContent> - </Dialog> - ) -} - -const Logs = () => { - const { endPoint } = useContext(ApiContext) - const { t, i18n } = useTranslation() - const dayjsLocale = - DAYJS_LOCALE_MAP[(i18n.language || 'en').split('-')[0]] || 'en' - - const [esEnabled, setEsEnabled] = useState(null) - const [logs, setLogs] = useState([]) - const [total, setTotal] = useState(0) - const [loading, setLoading] = useState(false) - - const [searchText, setSearchText] = useState('') - const [appliedSearch, setAppliedSearch] = useState('') - const [selectedLevels, setSelectedLevels] = useState([]) - const [selectedLogType, setSelectedLogType] = useState('') - const [selectedNode, setSelectedNode] = useState('') - const [nodes, setNodes] = useState([]) - const [nodeField, setNodeField] = useState('node') - const [pageFrom, setPageFrom] = useState(0) - const [expandedRow, setExpandedRow] = useState(null) - const [fieldFilters, setFieldFilters] = useState([]) - - const [timeRange, setTimeRange] = useState({ from: 'now-1h', to: 'now' }) - const [timeRangeLabel, setTimeRangeLabel] = useState('monitoring.time.1h') - const [customDisplay, setCustomDisplay] = useState('') - const [customFrom, setCustomFrom] = useState(null) - const [customTo, setCustomTo] = useState(null) - const [timeAnchor, setTimeAnchor] = useState(null) - - // Auto refresh - const [refreshInterval, setRefreshInterval] = useState(0) - const [refreshLabel, setRefreshLabel] = useState('monitoring.refresh.off') - const [refreshAnchor, setRefreshAnchor] = useState(null) - const refreshTimerRef = useRef(null) - - const debounceRef = useRef(null) - - useEffect(() => { - fetch(endPoint + '/v1/cluster/ui_config') - .then((res) => { - if (!res.ok) throw new Error('Network response was not ok') - return res.json() - }) - .then((data) => setEsEnabled(data.es_enabled || false)) - .catch(() => setEsEnabled(false)) - }, [endPoint]) - - useEffect(() => { - if (!esEnabled) return - const token = sessionStorage.getItem('token') - const headers = { 'Content-Type': 'application/json' } - if (token) headers['Authorization'] = `Bearer ${token}` - fetch(endPoint + '/v1/cluster/logs/nodes', { headers }) - .then((res) => res.json()) - .then((data) => { - setNodes(Array.isArray(data.nodes) ? data.nodes : []) - setNodeField(data.node_field || 'node') - }) - .catch(() => setNodes([])) - }, [endPoint, esEnabled]) - - const fetchLogs = useCallback(() => { - if (!esEnabled) return - setLoading(true) - const params = new URLSearchParams() - if (appliedSearch) params.set('q', appliedSearch) - if (selectedLevels.length) params.set('level', selectedLevels.join(',')) - if (selectedLogType) params.set('log_type', selectedLogType) - if (selectedNode) params.set('node', selectedNode) - if (nodeField !== 'node') params.set('node_field', nodeField) - params.set('time_from', timeRange.from) - params.set('time_to', timeRange.to) - params.set('size', String(PAGE_SIZE)) - params.set('page_from', String(pageFrom)) - fieldFilters.forEach((f) => { - params.append('filters', `${f.op}${f.key}:${String(f.value)}`) - }) - - const token = sessionStorage.getItem('token') - const headers = { 'Content-Type': 'application/json' } - if (token) headers['Authorization'] = `Bearer ${token}` - - fetch(endPoint + '/v1/cluster/logs?' + params.toString(), { headers }) - .then((res) => { - if (!res.ok) throw new Error(`HTTP ${res.status}`) - return res.json() - }) - .then((data) => { - setLogs(data.hits || []) - setTotal(data.total || 0) - }) - .catch((err) => { - console.error('Failed to fetch logs:', err) - setLogs([]) - setTotal(0) - }) - .finally(() => setLoading(false)) - }, [ - endPoint, - esEnabled, - appliedSearch, - selectedLevels, - selectedLogType, - selectedNode, - nodeField, - timeRange, - pageFrom, - fieldFilters, - ]) - - useEffect(() => { - fetchLogs() - }, [fetchLogs]) - - // Auto refresh timer - useEffect(() => { - if (refreshTimerRef.current) { - clearInterval(refreshTimerRef.current) - refreshTimerRef.current = null - } - if (refreshInterval > 0) { - refreshTimerRef.current = setInterval(() => fetchLogs(), refreshInterval) - } - return () => { - if (refreshTimerRef.current) clearInterval(refreshTimerRef.current) - } - }, [refreshInterval, fetchLogs]) - - const handleSearchChange = (e) => { - const val = e.target.value - setSearchText(val) - if (debounceRef.current) clearTimeout(debounceRef.current) - debounceRef.current = setTimeout(() => { - setAppliedSearch(val) - setPageFrom(0) - }, 500) - } - - const handleSearchKeyDown = (e) => { - if (e.key === 'Enter') { - if (debounceRef.current) clearTimeout(debounceRef.current) - setAppliedSearch(searchText) - setPageFrom(0) - } - } - - const toggleLevel = (level) => { - setSelectedLevels((prev) => - prev.includes(level) ? prev.filter((l) => l !== level) : [...prev, level] - ) - setPageFrom(0) - } - - const handleQuickRange = (item) => { - setTimeRange({ from: item.from, to: item.to }) - setTimeRangeLabel(item.labelKey) - setCustomDisplay('') - setTimeAnchor(null) - setPageFrom(0) - } - - const handleApplyAbsolute = () => { - if ( - customFrom && - customTo && - customFrom.isValid() && - customTo.isValid() && - customTo.isAfter(customFrom) - ) { - const fromMs = customFrom.valueOf() - const toMs = customTo.valueOf() - setTimeRange({ from: String(fromMs), to: String(toMs) }) - setTimeRangeLabel(null) - setCustomDisplay( - `${customFrom.format('YYYY-MM-DD HH:mm')} ~ ${customTo.format( - 'YYYY-MM-DD HH:mm' - )}` - ) - setTimeAnchor(null) - setPageFrom(0) - } - } - - const handleFieldFilter = useCallback((key, value, op) => { - const valStr = String(value) - setFieldFilters((prev) => { - const exists = prev.find( - (f) => f.key === key && f.value === valStr && f.op === op - ) - if (exists) return prev.filter((f) => f !== exists) - return [...prev, { key, value: valStr, op }] - }) - setPageFrom(0) - }, []) - - const totalPages = Math.ceil(total / PAGE_SIZE) - const currentPage = Math.floor(pageFrom / PAGE_SIZE) + 1 - - if (esEnabled === null) return null - - if (!esEnabled) { - return ( - <Box - sx={{ - width: '100%', - height: 'calc(100vh - 64px)', - padding: '20px 20px 0 20px', - display: 'flex', - flexDirection: 'column', - }} - > - <Title title={t('menu.logs')} /> - <Box - display="flex" - justifyContent="center" - alignItems="center" - sx={{ flex: 1 }} - > - <Typography variant="h6" color="text.secondary"> - {t('logs.notConfigured')} - </Typography> - </Box> - </Box> - ) - } - - const formatTime = (ts) => { - if (!ts) return '' - const d = new Date(ts) - return d.toLocaleString([], { - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit', - hour12: false, - }) - } - - return ( - <Box - sx={{ - width: '100%', - height: 'calc(100vh - 64px)', - padding: '20px 20px 0 20px', - display: 'flex', - flexDirection: 'column', - }} - > - <Title title={t('menu.logs')} /> - {/* Toolbar */} - <Toolbar - variant="dense" - sx={{ - minHeight: 48, - px: 2, - py: 1, - gap: 1, - borderBottom: 1, - borderColor: 'divider', - flexDirection: 'column', - alignItems: 'stretch', - }} - > - {/* Row 1: Node Select + Search + Time/Refresh */} - <Box - sx={{ - display: 'flex', - alignItems: 'center', - gap: 1, - width: '100%', - }} - > - {/* Node Select */} - {nodes.length > 0 && ( - <FormControl size="small" sx={{ minWidth: 200 }}> - <Select - value={selectedNode} - onChange={(e) => { - setSelectedNode(e.target.value) - setPageFrom(0) - }} - displayEmpty - sx={{ fontSize: FONT_SIZE }} - > - <MenuItem value="" sx={{ fontSize: FONT_SIZE }}> - {t('logs.allNodes')} - </MenuItem> - {nodes.map((n) => ( - <MenuItem key={n} value={n} sx={{ fontSize: FONT_SIZE }}> - {n} - </MenuItem> - ))} - </Select> - </FormControl> - )} - - {/* Search */} - <TextField - size="small" - placeholder={t('logs.searchPlaceholder')} - value={searchText} - onChange={handleSearchChange} - onKeyDown={handleSearchKeyDown} - sx={{ - 'width': 280, - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - }} - InputProps={{ - startAdornment: ( - <InputAdornment position="start"> - <SearchIcon fontSize="small" /> - </InputAdornment> - ), - }} - /> - - <Box sx={{ flex: 1 }} /> - - {/* Time Range */} - <Button - size="small" - color="inherit" - startIcon={<AccessTime fontSize="small" />} - onClick={(e) => setTimeAnchor(e.currentTarget)} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - > - {timeRangeLabel ? t(timeRangeLabel) : customDisplay} - </Button> - <Popover - anchorEl={timeAnchor} - open={Boolean(timeAnchor)} - onClose={() => setTimeAnchor(null)} - anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} - transformOrigin={{ vertical: 'top', horizontal: 'right' }} - > - <Box sx={{ display: 'flex', width: 480, maxHeight: 400 }}> - <Box - sx={{ - width: 240, - p: 2, - display: 'flex', - flexDirection: 'column', - gap: 1.5, - }} - > - <Typography - variant="subtitle2" - color="text.secondary" - sx={{ fontSize: FONT_SIZE }} - > - {t('monitoring.absoluteRange')} - </Typography> - <LocalizationProvider - dateAdapter={AdapterDayjs} - adapterLocale={dayjsLocale} - localeText={ - PICKER_LOCALE_TEXT[(i18n.language || 'en').split('-')[0]] || - PICKER_LOCALE_TEXT.en - } - > - <DateTimePicker - label={t('monitoring.from')} - value={customFrom} - onChange={(v) => setCustomFrom(v)} - ampm={false} - slotProps={DATE_TIME_SLOT_PROPS} - /> - <DateTimePicker - label={t('monitoring.to')} - value={customTo} - onChange={(v) => setCustomTo(v)} - ampm={false} - slotProps={DATE_TIME_SLOT_PROPS} - /> - </LocalizationProvider> - <Button - variant="contained" - size="small" - onClick={handleApplyAbsolute} - disabled={!customFrom || !customTo} - fullWidth - sx={{ fontSize: FONT_SIZE }} - > - {t('monitoring.applyTimeRange')} - </Button> - </Box> - <Divider orientation="vertical" flexItem /> - <Box sx={{ width: 240, overflow: 'auto' }}> - <MenuList dense disablePadding> - {TIME_RANGES.map((item) => ( - <MenuItem - key={item.labelKey} - selected={item.labelKey === timeRangeLabel} - onClick={() => handleQuickRange(item)} - sx={{ fontSize: FONT_SIZE }} - > - {t(item.labelKey)} - </MenuItem> - ))} - </MenuList> - </Box> - </Box> - </Popover> - - {/* Refresh */} - <Tooltip title={t('logs.refresh')}> - <IconButton size="small" color="inherit" onClick={fetchLogs}> - <RefreshIcon fontSize="small" /> - </IconButton> - </Tooltip> - - {/* Auto Refresh Interval */} - <Button - size="small" - color="inherit" - startIcon={<RefreshIcon fontSize="small" />} - onClick={(e) => setRefreshAnchor(e.currentTarget)} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - > - {t(refreshLabel)} - </Button> - <Menu - anchorEl={refreshAnchor} - open={Boolean(refreshAnchor)} - onClose={() => setRefreshAnchor(null)} - > - {REFRESH_OPTIONS.map((item) => ( - <MenuItem - key={item.labelKey} - selected={item.labelKey === refreshLabel} - onClick={() => { - setRefreshInterval(item.value) - setRefreshLabel(item.labelKey) - setRefreshAnchor(null) - }} - sx={{ fontSize: FONT_SIZE }} - > - {t(item.labelKey)} - </MenuItem> - ))} - </Menu> - </Box> - - {/* Row 2: Log Level */} - <Box - sx={{ - display: 'flex', - alignItems: 'center', - gap: 1, - width: '100%', - }} - > - <Typography - variant="body2" - color="text.secondary" - sx={{ fontSize: FONT_SIZE, minWidth: 64 }} - > - {t('logs.logLevel')} - </Typography> - <Box sx={{ display: 'flex', gap: 0.5 }}> - {LEVELS.map((level) => ( - <Chip - key={level} - label={level} - size="small" - variant={selectedLevels.includes(level) ? 'filled' : 'outlined'} - color={ - level === 'ERROR' - ? 'error' - : level === 'WARNING' - ? 'warning' - : 'default' - } - onClick={() => toggleLevel(level)} - sx={{ fontSize: FONT_SIZE }} - /> - ))} - </Box> - </Box> - - {/* Row 3: Node Type */} - <Box - sx={{ - display: 'flex', - alignItems: 'center', - gap: 1, - width: '100%', - }} - > - <Typography - variant="body2" - color="text.secondary" - sx={{ fontSize: FONT_SIZE, minWidth: 64 }} - > - {t('logs.nodeType')} - </Typography> - <Box sx={{ display: 'flex', gap: 0.5 }}> - {LOG_TYPES.map((lt) => ( - <Chip - key={lt} - label={lt} - size="small" - variant={selectedLogType === lt ? 'filled' : 'outlined'} - onClick={() => { - setSelectedLogType((prev) => (prev === lt ? '' : lt)) - setPageFrom(0) - }} - sx={{ fontSize: FONT_SIZE }} - /> - ))} - </Box> - </Box> - </Toolbar> - - {/* Active Field Filters */} - {fieldFilters.length > 0 && ( - <Box - sx={{ - display: 'flex', - flexWrap: 'wrap', - gap: 0.5, - px: 2, - py: 0.5, - borderBottom: 1, - borderColor: 'divider', - alignItems: 'center', - }} - > - {fieldFilters.map((f, i) => ( - <Chip - key={`${f.op}${f.key}:${f.value}-${i}`} - label={ - f.op === '-' - ? `NOT ${f.key}: ${f.value}` - : `${f.key}: ${f.value}` - } - size="small" - color={f.op === '-' ? 'error' : 'default'} - variant={f.op === '-' ? 'outlined' : 'filled'} - onDelete={() => - setFieldFilters((prev) => prev.filter((_, idx) => idx !== i)) - } - sx={{ fontSize: FONT_SIZE }} - /> - ))} - <Chip - label={t('logs.clearFilters', 'Clear all')} - size="small" - variant="outlined" - onClick={() => setFieldFilters([])} - sx={{ fontSize: FONT_SIZE }} - /> - </Box> - )} - - {/* Log Table */} - <TableContainer sx={{ flex: 1, overflow: 'auto' }}> - <Table size="small" stickyHeader> - <TableHead> - <TableRow> - <TableCell sx={{ width: 32, fontSize: FONT_SIZE }} /> - <TableCell sx={{ width: 150, fontSize: FONT_SIZE }}> - {t('logs.time')} - </TableCell> - <TableCell sx={{ width: 80, fontSize: FONT_SIZE }}> - {t('logs.level')} - </TableCell> - <TableCell sx={{ width: 160, fontSize: FONT_SIZE }}> - {t('logs.node')} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - {t('logs.message')} - </TableCell> - </TableRow> - </TableHead> - <TableBody> - {(() => { - const levelFilterValues = [ - ...fieldFilters - .filter((f) => f.op === '+' && f.key === 'level') - .map((f) => f.value), - ...selectedLevels, - ] - const nodeFilterValues = fieldFilters - .filter((f) => f.op === '+' && f.key === 'node') - .map((f) => f.value) - const messageFilterValues = fieldFilters - .filter((f) => f.op === '+' && f.key === 'message') - .map((f) => f.value) - - return logs.map((row, idx) => { - const isExpanded = expandedRow === idx - return ( - <React.Fragment key={idx}> - <TableRow - hover - sx={{ - 'cursor': 'pointer', - '& > *': { - borderBottom: isExpanded ? 'none' : undefined, - }, - }} - onClick={() => setExpandedRow(isExpanded ? null : idx)} - > - <TableCell sx={{ fontSize: FONT_SIZE, p: 0.5 }}> - <ExpandMoreIcon - fontSize="small" - sx={{ - transform: isExpanded ? 'rotate(180deg)' : 'none', - transition: 'transform 0.2s', - }} - /> - </TableCell> - <TableCell - sx={{ fontSize: FONT_SIZE, whiteSpace: 'nowrap' }} - > - {formatTime(row['@timestamp'])} - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <Typography - component="span" - sx={{ - fontSize: FONT_SIZE, - fontWeight: 600, - color: LEVEL_COLORS[row.level] || 'text.primary', - }} - > - <HighlightText - text={row.level} - keywords={levelFilterValues} - /> - </Typography> - </TableCell> - <TableCell sx={{ fontSize: FONT_SIZE }}> - <HighlightText - text={row.node} - keywords={nodeFilterValues} - /> - </TableCell> - <TableCell - sx={{ - fontSize: FONT_SIZE, - maxWidth: 0, - overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', - }} - > - <HighlightText - text={row.message} - keywords={[appliedSearch, ...messageFilterValues]} - /> - </TableCell> - </TableRow> - <TableRow> - <TableCell sx={{ p: 0 }} colSpan={5}> - <Collapse in={isExpanded} timeout="auto" unmountOnExit> - <DetailRow - row={row} - onFilter={handleFieldFilter} - fieldFilters={fieldFilters} - appliedSearch={appliedSearch} - selectedLevels={selectedLevels} - selectedLogType={selectedLogType} - endPoint={endPoint} - nodeField={nodeField} - /> - </Collapse> - </TableCell> - </TableRow> - </React.Fragment> - ) - }) - })()} - {!loading && logs.length === 0 && ( - <TableRow> - <TableCell colSpan={5} align="center" sx={{ py: 4 }}> - <Typography color="text.secondary"> - {t('logs.noLogs')} - </Typography> - </TableCell> - </TableRow> - )} - </TableBody> - </Table> - </TableContainer> - - {/* Pagination */} - <Toolbar - variant="dense" - sx={{ - minHeight: 40, - px: 2, - justifyContent: 'flex-end', - gap: 1, - borderTop: 1, - borderColor: 'divider', - }} - > - <Typography variant="body2" sx={{ fontSize: FONT_SIZE }}> - {t('logs.totalHits', { count: total })} - </Typography> - <Button - size="small" - disabled={pageFrom === 0} - onClick={() => setPageFrom(Math.max(0, pageFrom - PAGE_SIZE))} - sx={{ fontSize: FONT_SIZE, textTransform: 'none' }} - > - {t('logs.prevPage')} - </Button> - <Typography variant="body2" sx={{ fontSize: FONT_SIZE }}> - {currentPage} / {totalPages || 1} - </Typography> - <Button - size="small" - disabled={ - pageFrom + PAGE_SIZE >= total || pageFrom + PAGE_SIZE > 10000 - } - onClick={() => setPageFrom(pageFrom + PAGE_SIZE)} - sx={{ fontSize: FONT_SIZE, textTransform: 'none' }} - > - {t('logs.nextPage')} - </Button> - </Toolbar> - </Box> - ) -} - -export default Logs diff --git a/xinference/ui/web/ui/src/scenes/monitoring/MonitorConfigDialog.js b/xinference/ui/web/ui/src/scenes/monitoring/MonitorConfigDialog.js deleted file mode 100644 index 4314649300..0000000000 --- a/xinference/ui/web/ui/src/scenes/monitoring/MonitorConfigDialog.js +++ /dev/null @@ -1,367 +0,0 @@ -import { - CloudCircle as CloudCircleIcon, - ErrorOutline as AlertCircleIcon, - Storage as StorageIcon, -} from '@mui/icons-material' -import { - Box, - Button, - Chip, - CircularProgress, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - Divider, - Snackbar, - Stack, - TextField, - Typography, -} from '@mui/material' -import React, { useContext, useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../components/apiContext' - -const DASHBOARD_FIELDS = [ - { key: 'overview', labelKey: 'monitoring.config.dashboardOverview' }, - { key: 'model_load', labelKey: 'monitoring.config.dashboardModelLoad' }, - { key: 'llm_slo', labelKey: 'monitoring.config.dashboardLlmSlo' }, - { key: 'gpu', labelKey: 'monitoring.config.dashboardGpu' }, - { key: 'host', labelKey: 'monitoring.config.dashboardHost' }, - { key: 'security', labelKey: 'monitoring.config.dashboardSecurity' }, -] - -const SOURCE_ICONS = { - db: { - icon: StorageIcon, - color: 'success', - labelKey: 'monitoring.config.sourceDb', - }, - env: { - icon: CloudCircleIcon, - color: 'info', - labelKey: 'monitoring.config.sourceEnv', - }, - default: { - icon: AlertCircleIcon, - color: 'default', - labelKey: 'monitoring.config.sourceDefault', - }, -} - -const SourceChip = ({ source, t }) => { - const cfg = SOURCE_ICONS[source] || SOURCE_ICONS.default - const Icon = cfg.icon - return ( - <Chip - icon={<Icon fontSize="small" />} - label={t(cfg.labelKey)} - size="small" - color={cfg.color} - variant="outlined" - sx={{ ml: 1, height: 24, fontSize: '0.75rem' }} - /> - ) -} - -const MonitorConfigDialog = ({ open, onClose, onSaved }) => { - const { endPoint } = useContext(ApiContext) - const { t } = useTranslation() - - const [loading, setLoading] = useState(false) - const [saving, setSaving] = useState(false) - const [checking, setChecking] = useState(false) - - const [grafanaUrl, setGrafanaUrl] = useState('') - const [grafanaDatasource, setGrafanaDatasource] = useState('') - const [grafanaAlertDatasource, setGrafanaAlertDatasource] = useState('') - const [clusterName, setClusterName] = useState('') - const [dashboards, setDashboards] = useState({}) - const [sources, setSources] = useState({}) - - const [snackbar, setSnackbar] = useState({ - open: false, - message: '', - severity: 'info', - }) - - useEffect(() => { - if (!open) return - setLoading(true) - fetch(endPoint + '/v1/cluster/monitor_config', { - headers: { - Authorization: `Bearer ${sessionStorage.getItem('token') || ''}`, - }, - }) - .then((res) => res.json()) - .then((data) => { - setGrafanaUrl(data.grafana_url || '') - setGrafanaDatasource(data.grafana_datasource || '') - setGrafanaAlertDatasource(data.grafana_alert_datasource || '') - setClusterName(data.cluster_name || '') - setDashboards(data.grafana_dashboards || {}) - setSources(data.sources || {}) - }) - .catch(() => { - setSnackbar({ - open: true, - message: t('monitoring.config.loadFailed'), - severity: 'error', - }) - }) - .finally(() => setLoading(false)) - }, [open, endPoint, t]) - - const handleSave = async () => { - setSaving(true) - - // Check Grafana connectivity first - if (grafanaUrl) { - setChecking(true) - try { - const checkRes = await fetch( - endPoint + '/v1/cluster/monitor_config/check-grafana', - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${ - sessionStorage.getItem('token') || '' - }`, - }, - body: JSON.stringify({ grafana_url: grafanaUrl }), - } - ) - const checkData = await checkRes.json() - if (!checkData.ok) { - setSnackbar({ - open: true, - message: `${t('monitoring.config.healthCheckFailed')}: ${ - checkData.error - }`, - severity: 'warning', - }) - } - } catch (e) { - // Ignore check errors, proceed with save - } - setChecking(false) - } - - // Save config - try { - const body = { - grafana_url: grafanaUrl, - grafana_datasource: grafanaDatasource, - grafana_alert_datasource: grafanaAlertDatasource, - cluster_name: clusterName, - grafana_dashboards: dashboards, - } - const res = await fetch(endPoint + '/v1/cluster/monitor_config', { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${sessionStorage.getItem('token') || ''}`, - }, - body: JSON.stringify(body), - }) - if (res.ok) { - setSnackbar({ - open: true, - message: t('monitoring.config.saved'), - severity: 'success', - }) - onSaved() - } else { - setSnackbar({ - open: true, - message: t('monitoring.config.saveFailed'), - severity: 'error', - }) - } - } catch (e) { - setSnackbar({ - open: true, - message: t('monitoring.config.saveFailed'), - severity: 'error', - }) - } - setSaving(false) - } - - const handleReset = async () => { - try { - const res = await fetch(endPoint + '/v1/cluster/monitor_config/reset', { - method: 'POST', - headers: { - Authorization: `Bearer ${sessionStorage.getItem('token') || ''}`, - }, - }) - if (res.ok) { - setSnackbar({ - open: true, - message: t('monitoring.config.resetDone'), - severity: 'success', - }) - onSaved() - } - } catch (e) { - setSnackbar({ - open: true, - message: t('monitoring.config.saveFailed'), - severity: 'error', - }) - } - } - - const handleDashboardChange = (key, value) => { - setDashboards((prev) => ({ ...prev, [key]: value })) - } - - if (loading) { - return ( - <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth> - <DialogContent - sx={{ display: 'flex', justifyContent: 'center', py: 4 }} - > - <CircularProgress /> - </DialogContent> - </Dialog> - ) - } - - return ( - <> - <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth> - <DialogTitle>{t('monitoring.config.title')}</DialogTitle> - <DialogContent dividers> - <Stack spacing={2.5}> - {/* Grafana URL */} - <Box> - <Box display="flex" alignItems="center" mb={0.5}> - <Typography variant="subtitle2"> - {t('monitoring.config.grafanaUrl')} * - </Typography> - <SourceChip source={sources.grafana_url} t={t} /> - </Box> - <TextField - fullWidth - size="small" - value={grafanaUrl} - onChange={(e) => setGrafanaUrl(e.target.value)} - placeholder="https://grafana.example.com" - /> - </Box> - - {/* Datasource */} - <Box> - <Box display="flex" alignItems="center" mb={0.5}> - <Typography variant="subtitle2"> - {t('monitoring.config.datasource')} - </Typography> - <SourceChip source={sources.grafana_datasource} t={t} /> - </Box> - <TextField - fullWidth - size="small" - value={grafanaDatasource} - onChange={(e) => setGrafanaDatasource(e.target.value)} - placeholder="Prometheus" - /> - </Box> - - {/* Alert Datasource */} - <Box> - <Box display="flex" alignItems="center" mb={0.5}> - <Typography variant="subtitle2"> - {t('monitoring.config.alertDatasource')} - </Typography> - <SourceChip source={sources.grafana_alert_datasource} t={t} /> - </Box> - <TextField - fullWidth - size="small" - value={grafanaAlertDatasource} - onChange={(e) => setGrafanaAlertDatasource(e.target.value)} - placeholder={t('monitoring.config.alertDatasourceHint')} - /> - </Box> - - {/* Cluster Name */} - <Box> - <Box display="flex" alignItems="center" mb={0.5}> - <Typography variant="subtitle2"> - {t('monitoring.config.clusterName')} - </Typography> - <SourceChip source={sources.cluster_name} t={t} /> - </Box> - <TextField - fullWidth - size="small" - value={clusterName} - onChange={(e) => setClusterName(e.target.value)} - /> - </Box> - - <Divider /> - - {/* Dashboard UIDs */} - <Typography variant="subtitle2" color="text.secondary"> - {t('monitoring.config.dashboardUid')} - </Typography> - {DASHBOARD_FIELDS.map((field) => ( - <Box key={field.key}> - <Box display="flex" alignItems="center" mb={0.5}> - <Typography variant="body2" sx={{ fontSize: '0.85rem' }}> - {t(field.labelKey)} - </Typography> - <SourceChip - source={sources[`dashboard_${field.key}`]} - t={t} - /> - </Box> - <TextField - fullWidth - size="small" - value={dashboards[field.key] || ''} - onChange={(e) => - handleDashboardChange(field.key, e.target.value) - } - /> - </Box> - ))} - </Stack> - </DialogContent> - <DialogActions sx={{ px: 3, py: 2 }}> - <Button color="warning" onClick={handleReset}> - {t('monitoring.config.reset')} - </Button> - <Box sx={{ flex: 1 }} /> - <Button onClick={onClose}>{t('monitoring.config.cancel')}</Button> - <Button - variant="contained" - onClick={handleSave} - disabled={saving || checking} - > - {checking - ? t('monitoring.config.checking') - : saving - ? t('monitoring.config.saving') - : t('monitoring.config.save')} - </Button> - </DialogActions> - </Dialog> - - <Snackbar - open={snackbar.open} - autoHideDuration={4000} - onClose={() => setSnackbar((prev) => ({ ...prev, open: false }))} - message={snackbar.message} - severity={snackbar.severity} - /> - </> - ) -} - -export default MonitorConfigDialog diff --git a/xinference/ui/web/ui/src/scenes/monitoring/index.js b/xinference/ui/web/ui/src/scenes/monitoring/index.js deleted file mode 100644 index 4d251f69b6..0000000000 --- a/xinference/ui/web/ui/src/scenes/monitoring/index.js +++ /dev/null @@ -1,478 +0,0 @@ -import 'dayjs/locale/ja' -import 'dayjs/locale/ko' -import 'dayjs/locale/zh-cn' - -import { - AccessTime, - Refresh as RefreshIcon, - Settings as SettingsIcon, -} from '@mui/icons-material' -import { - Box, - Button, - Divider, - IconButton, - LinearProgress, - Menu, - MenuItem, - MenuList, - Popover, - Tab, - Tabs, - Toolbar, - Tooltip, - Typography, -} from '@mui/material' -import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs' -import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker' -import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider' -import React, { useContext, useEffect, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../components/apiContext' -import { buildGrafanaUrl } from '../../components/grafanaUtils' -import { useThemeContext } from '../../components/themeContext' -import Title from '../../components/Title' -import { isAdmin, parseTokenFromSession } from '../../utils/jwt' -import MonitorConfigDialog from './MonitorConfigDialog' - -const FONT_SIZE = '0.813rem' - -const DAYJS_LOCALE_MAP = { en: 'en', zh: 'zh-cn', ja: 'ja', ko: 'ko' } - -const DASHBOARD_TABS = [ - { key: 'overview', labelKey: 'monitoring.tab.overview' }, - { key: 'model_load', labelKey: 'monitoring.tab.modelLoad' }, - { key: 'llm_slo', labelKey: 'monitoring.tab.llmSlo' }, - { key: 'gpu', labelKey: 'monitoring.tab.gpu' }, - { key: 'host', labelKey: 'monitoring.tab.host' }, - { key: 'security', labelKey: 'monitoring.tab.security' }, -] - -const TIME_RANGES = [ - { labelKey: 'monitoring.time.5m', from: 'now-5m', to: 'now' }, - { labelKey: 'monitoring.time.15m', from: 'now-15m', to: 'now' }, - { labelKey: 'monitoring.time.30m', from: 'now-30m', to: 'now' }, - { labelKey: 'monitoring.time.1h', from: 'now-1h', to: 'now' }, - { labelKey: 'monitoring.time.3h', from: 'now-3h', to: 'now' }, - { labelKey: 'monitoring.time.6h', from: 'now-6h', to: 'now' }, - { labelKey: 'monitoring.time.12h', from: 'now-12h', to: 'now' }, - { labelKey: 'monitoring.time.24h', from: 'now-24h', to: 'now' }, - { labelKey: 'monitoring.time.2d', from: 'now-2d', to: 'now' }, - { labelKey: 'monitoring.time.7d', from: 'now-7d', to: 'now' }, -] - -const REFRESH_OPTIONS = [ - { labelKey: 'monitoring.refresh.off', value: 0, grafana: '' }, - { labelKey: 'monitoring.refresh.10s', value: 10000, grafana: '10s' }, - { labelKey: 'monitoring.refresh.30s', value: 30000, grafana: '30s' }, - { labelKey: 'monitoring.refresh.1m', value: 60000, grafana: '1m' }, - { labelKey: 'monitoring.refresh.5m', value: 300000, grafana: '5m' }, -] - -const DATE_TIME_SLOT_PROPS = { - textField: { - size: 'small', - fullWidth: true, - sx: { - '& .MuiInputBase-input': { fontSize: FONT_SIZE }, - '& .MuiInputLabel-root': { fontSize: FONT_SIZE }, - }, - }, - popper: { - sx: { - '& .MuiDayCalendar-weekDayLabel': { fontSize: FONT_SIZE }, - '& .MuiPickersDay-root': { fontSize: FONT_SIZE }, - }, - }, -} - -const PICKER_LOCALE_TEXT = { - en: { okButtonLabel: 'OK', cancelButtonLabel: 'Cancel' }, - zh: { okButtonLabel: '确定', cancelButtonLabel: '取消' }, - ja: { okButtonLabel: '確定', cancelButtonLabel: 'キャンセル' }, - ko: { okButtonLabel: '확인', cancelButtonLabel: '취소' }, -} - -const Monitoring = () => { - const { endPoint } = useContext(ApiContext) - const { themeMode } = useThemeContext() - const [config, setConfig] = useState(null) - const { t, i18n } = useTranslation() - // Config write is admin-only. The menu visibility already gates this - // page behind `monitor:view`, but configuration changes (Grafana URL, - // datasource) are gated by `admin` per the existing - // `update_monitor_config` route scope. - const canConfigure = isAdmin(parseTokenFromSession()?.scopes || []) - - const dayjsLocale = - DAYJS_LOCALE_MAP[(i18n.language || 'en').split('-')[0]] || 'en' - - const [dashboardKey, setDashboardKey] = useState(() => { - return sessionStorage.getItem('monitoring_dashboard_key') || 'overview' - }) - const [timeRange, setTimeRange] = useState({ from: 'now-1h', to: 'now' }) - const [timeRangeLabel, setTimeRangeLabel] = useState('monitoring.time.1h') - const [customDisplay, setCustomDisplay] = useState('') - const [customFrom, setCustomFrom] = useState(null) - const [customTo, setCustomTo] = useState(null) - const [refreshInterval, setRefreshInterval] = useState(() => { - const saved = sessionStorage.getItem('monitoring_refresh_interval') - return saved ? Number(saved) : 60000 - }) - const [refreshLabel, setRefreshLabel] = useState( - () => - sessionStorage.getItem('monitoring_refresh_label') || - 'monitoring.refresh.1m' - ) - const [grafanaRefresh, setGrafanaRefresh] = useState( - () => sessionStorage.getItem('monitoring_grafana_refresh') || '1m' - ) - const [refreshKey, setRefreshKey] = useState(0) - - const [timeAnchor, setTimeAnchor] = useState(null) - const [refreshAnchor, setRefreshAnchor] = useState(null) - const [configDialogOpen, setConfigDialogOpen] = useState(false) - const [iframeLoading, setIframeLoading] = useState(false) - - const timerRef = useRef(null) - - const isConfigured = config?.grafana_url - - useEffect(() => { - fetch(endPoint + '/v1/cluster/ui_config') - .then((res) => res.json()) - .then((data) => setConfig(data)) - .catch(() => setConfig(null)) - }, [endPoint]) - - // Auto refresh - useEffect(() => { - if (timerRef.current) { - clearInterval(timerRef.current) - timerRef.current = null - } - if (refreshInterval > 0) { - timerRef.current = setInterval( - () => setRefreshKey((k) => k + 1), - refreshInterval - ) - } - return () => { - if (timerRef.current) clearInterval(timerRef.current) - } - }, [refreshInterval]) - - const handleQuickRange = (item) => { - setTimeRange({ from: item.from, to: item.to }) - setTimeRangeLabel(item.labelKey) - setTimeAnchor(null) - setRefreshKey((k) => k + 1) - } - - const handleApplyAbsolute = () => { - if ( - customFrom && - customTo && - customFrom.isValid() && - customTo.isValid() && - customTo.isAfter(customFrom) - ) { - const fromMs = customFrom.valueOf() - const toMs = customTo.valueOf() - setTimeRange({ from: String(fromMs), to: String(toMs) }) - setTimeRangeLabel(null) - setCustomDisplay( - `${customFrom.format('YYYY-MM-DD HH:mm')} ~ ${customTo.format( - 'YYYY-MM-DD HH:mm' - )}` - ) - setTimeAnchor(null) - setRefreshKey((k) => k + 1) - } - } - - const handleTabChange = (_, newKey) => { - setDashboardKey(newKey) - sessionStorage.setItem('monitoring_dashboard_key', newKey) - setIframeLoading(true) - setRefreshKey((k) => k + 1) - } - - const handleConfigSaved = () => { - setConfigDialogOpen(false) - fetch(endPoint + '/v1/cluster/ui_config') - .then((res) => res.json()) - .then((data) => setConfig(data)) - .catch(() => {}) - setRefreshKey((k) => k + 1) - } - - const src = isConfigured - ? buildGrafanaUrl( - config, - dashboardKey, - themeMode, - timeRange.from, - timeRange.to, - grafanaRefresh - ) + `&_t=${refreshKey}` - : null - - return ( - <Box - sx={{ - width: '100%', - height: 'calc(100vh - 64px)', - padding: '20px 20px 0 20px', - display: 'flex', - flexDirection: 'column', - }} - > - <Title title={t('menu.monitoring')} /> - - {/* Tabs */} - <Tabs - value={dashboardKey} - onChange={handleTabChange} - variant="scrollable" - scrollButtons="auto" - sx={{ borderBottom: 1, borderColor: 'divider', mb: 1 }} - > - {DASHBOARD_TABS.map((tab) => ( - <Tab - key={tab.key} - value={tab.key} - label={t(tab.labelKey)} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - /> - ))} - </Tabs> - - {/* Toolbar */} - <Toolbar - variant="dense" - sx={{ - minHeight: 40, - px: 2, - justifyContent: 'flex-end', - gap: 1, - borderBottom: 1, - borderColor: 'divider', - }} - > - {/* Time Range */} - <Button - size="small" - color="inherit" - startIcon={<AccessTime fontSize="small" />} - onClick={(e) => setTimeAnchor(e.currentTarget)} - disabled={!isConfigured} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - > - {timeRangeLabel ? t(timeRangeLabel) : customDisplay} - </Button> - <Popover - anchorEl={timeAnchor} - open={Boolean(timeAnchor)} - onClose={() => setTimeAnchor(null)} - anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} - transformOrigin={{ vertical: 'top', horizontal: 'right' }} - > - <Box sx={{ display: 'flex', width: 480, maxHeight: 400 }}> - {/* Left: Absolute time range */} - <Box - sx={{ - width: 240, - p: 2, - display: 'flex', - flexDirection: 'column', - gap: 1.5, - }} - > - <Typography - variant="subtitle2" - color="text.secondary" - sx={{ fontSize: FONT_SIZE }} - > - {t('monitoring.absoluteRange')} - </Typography> - <LocalizationProvider - dateAdapter={AdapterDayjs} - adapterLocale={dayjsLocale} - localeText={ - PICKER_LOCALE_TEXT[(i18n.language || 'en').split('-')[0]] || - PICKER_LOCALE_TEXT.en - } - > - <DateTimePicker - label={t('monitoring.from')} - value={customFrom} - onChange={(v) => setCustomFrom(v)} - ampm={false} - slotProps={DATE_TIME_SLOT_PROPS} - /> - <DateTimePicker - label={t('monitoring.to')} - value={customTo} - onChange={(v) => setCustomTo(v)} - ampm={false} - slotProps={DATE_TIME_SLOT_PROPS} - /> - </LocalizationProvider> - <Button - variant="contained" - size="small" - onClick={handleApplyAbsolute} - disabled={!customFrom || !customTo} - fullWidth - sx={{ fontSize: FONT_SIZE }} - > - {t('monitoring.applyTimeRange')} - </Button> - </Box> - - <Divider orientation="vertical" flexItem /> - - {/* Right: Quick ranges */} - <Box sx={{ width: 240, overflow: 'auto' }}> - <MenuList dense disablePadding> - {TIME_RANGES.map((item) => ( - <MenuItem - key={item.labelKey} - selected={item.labelKey === timeRangeLabel} - onClick={() => handleQuickRange(item)} - sx={{ fontSize: FONT_SIZE }} - > - {t(item.labelKey)} - </MenuItem> - ))} - </MenuList> - </Box> - </Box> - </Popover> - - {/* Manual Refresh */} - <Tooltip title={t('monitoring.manualRefresh')}> - <IconButton - size="small" - color="inherit" - onClick={() => setRefreshKey((k) => k + 1)} - disabled={!isConfigured} - > - <RefreshIcon fontSize="small" /> - </IconButton> - </Tooltip> - - {/* Refresh Interval */} - <Button - size="small" - color="inherit" - startIcon={<RefreshIcon fontSize="small" />} - onClick={(e) => setRefreshAnchor(e.currentTarget)} - disabled={!isConfigured} - sx={{ textTransform: 'none', fontSize: FONT_SIZE }} - > - {t(refreshLabel)} - </Button> - <Menu - anchorEl={refreshAnchor} - open={Boolean(refreshAnchor)} - onClose={() => setRefreshAnchor(null)} - > - {REFRESH_OPTIONS.map((item) => ( - <MenuItem - key={item.labelKey} - selected={item.labelKey === refreshLabel} - onClick={() => { - setRefreshInterval(item.value) - setRefreshLabel(item.labelKey) - setGrafanaRefresh(item.grafana) - sessionStorage.setItem( - 'monitoring_refresh_interval', - item.value - ) - sessionStorage.setItem( - 'monitoring_refresh_label', - item.labelKey - ) - sessionStorage.setItem( - 'monitoring_grafana_refresh', - item.grafana - ) - setRefreshAnchor(null) - }} - > - {t(item.labelKey)} - </MenuItem> - ))} - </Menu> - - {/* Settings */} - {canConfigure && ( - <Tooltip title={t('monitoring.config.title')}> - <IconButton - size="small" - color="inherit" - onClick={() => setConfigDialogOpen(true)} - > - <SettingsIcon fontSize="small" /> - </IconButton> - </Tooltip> - )} - </Toolbar> - - {/* Loading indicator */} - {iframeLoading && <LinearProgress sx={{ height: 2 }} />} - - {/* Content area */} - <Box sx={{ flex: 1, position: 'relative' }}> - {isConfigured && src ? ( - <iframe - src={src} - width="100%" - height="100%" - frameBorder="0" - title="Xinference Monitoring" - style={{ border: 'none' }} - onLoad={() => setIframeLoading(false)} - /> - ) : ( - <Box - display="flex" - flexDirection="column" - justifyContent="center" - alignItems="center" - sx={{ height: '100%', gap: 2 }} - > - <SettingsIcon sx={{ fontSize: 48, color: 'text.secondary' }} /> - <Typography variant="h6" color="text.secondary"> - {t('monitoring.notConfigured')} - </Typography> - <Typography variant="body2" color="text.secondary"> - {t('monitoring.configHint')} - </Typography> - {canConfigure && ( - <Button - variant="contained" - startIcon={<SettingsIcon />} - onClick={() => setConfigDialogOpen(true)} - > - {t('monitoring.config.openConfig')} - </Button> - )} - </Box> - )} - </Box> - - {/* Config Dialog */} - <MonitorConfigDialog - open={configDialogOpen} - onClose={() => setConfigDialogOpen(false)} - onSaved={handleConfigSaved} - /> - </Box> - ) -} - -export default Monitoring diff --git a/xinference/ui/web/ui/src/scenes/register_model/components/addControlnet.js b/xinference/ui/web/ui/src/scenes/register_model/components/addControlnet.js deleted file mode 100644 index c4509d2fe7..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/components/addControlnet.js +++ /dev/null @@ -1,181 +0,0 @@ -import AddIcon from '@mui/icons-material/Add' -import DeleteIcon from '@mui/icons-material/Delete' -import { - Box, - Button, - FormControlLabel, - Radio, - RadioGroup, - TextField, - Tooltip, -} from '@mui/material' -import React, { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -const AddControlnet = ({ - controlnetDataArr, - onGetControlnetArr, - scrollRef, -}) => { - const [count, setCount] = useState(0) - const [controlnetArr, setControlnetArr] = useState([]) - const [isAdd, setIsAdd] = useState(false) - const { t } = useTranslation() - - useEffect(() => { - if (controlnetDataArr && controlnetDataArr.length) { - const dataArr = controlnetDataArr.map((item) => { - setCount(count + 1) - item.id = count - return item - }) - setControlnetArr(dataArr) - } - }, []) - - useEffect(() => { - const arr = controlnetArr.map((item) => { - const { model_name: name, model_uri: uri, model_family } = item - return { - model_name: name, - model_uri: uri, - model_family, - } - }) - onGetControlnetArr(arr) - isAdd && handleScrollBottom() - setIsAdd(false) - }, [controlnetArr]) - - const handleAddControlnet = () => { - setCount(count + 1) - const item = { - id: count, - model_name: 'custom-controlnet', - model_uri: '/path/to/controlnet-model', - model_family: 'controlnet', - } - setControlnetArr([...controlnetArr, item]) - setIsAdd(true) - } - - const handleUpdateSpecsArr = (index, type, newValue) => { - setControlnetArr( - controlnetArr.map((item, subIndex) => { - if (subIndex === index) { - return { ...item, [type]: newValue } - } - return item - }) - ) - } - - const handleDeleteControlnet = (index) => { - setControlnetArr(controlnetArr.filter((_, subIndex) => index !== subIndex)) - } - - const handleScrollBottom = () => { - scrollRef.current.scrollTo({ - top: scrollRef.current.scrollHeight, - behavior: 'smooth', - }) - } - - return ( - <> - <div> - <label style={{ marginBottom: '20px' }}> - {t('registerModel.controlnet')} - </label> - <Button - variant="contained" - size="small" - endIcon={<AddIcon />} - className="addBtn" - onClick={handleAddControlnet} - > - {t('registerModel.more')} - </Button> - </div> - <div className="specs_container"> - {controlnetArr.map((item, index) => ( - <div className="item" key={item.id}> - <TextField - error={item.model_name !== '' ? false : true} - style={{ minWidth: '60%', marginTop: '10px' }} - label="Model Name" - size="small" - value={item.model_name} - onChange={(e) => { - handleUpdateSpecsArr(index, 'model_name', e.target.value) - }} - /> - <Box padding="15px"></Box> - - <TextField - error={item.model_uri !== '' ? false : true} - style={{ minWidth: '60%' }} - label="Model Path" - size="small" - value={item.model_uri} - onChange={(e) => { - handleUpdateSpecsArr(index, 'model_uri', e.target.value) - }} - /> - <Box padding="15px"></Box> - - <label - style={{ - paddingLeft: 5, - }} - > - {t('registerModel.modelFormat')} - </label> - <RadioGroup - value={item.model_format} - onChange={(e) => { - handleUpdateSpecsArr(index, 'model_format', e.target.value) - }} - > - <Box sx={styles.checkboxWrapper}> - <Box key={item} sx={{ marginLeft: '10px' }}> - <FormControlLabel - value="controlnet" - checked - control={<Radio />} - label="controlnet" - /> - </Box> - </Box> - </RadioGroup> - - <Tooltip title={t('registerModel.delete')} placement="top"> - <div - className="deleteBtn" - onClick={() => handleDeleteControlnet(index)} - > - <DeleteIcon className="deleteIcon" /> - </div> - </Tooltip> - </div> - ))} - </div> - </> - ) -} - -export default AddControlnet - -const styles = { - baseFormControl: { - width: '100%', - margin: 'normal', - size: 'small', - }, - checkboxWrapper: { - display: 'flex', - flexWrap: 'wrap', - alignItems: 'center', - width: '100%', - }, -} diff --git a/xinference/ui/web/ui/src/scenes/register_model/components/addModelSpecs.js b/xinference/ui/web/ui/src/scenes/register_model/components/addModelSpecs.js deleted file mode 100644 index c53e2de8e0..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/components/addModelSpecs.js +++ /dev/null @@ -1,454 +0,0 @@ -import AddIcon from '@mui/icons-material/Add' -import DeleteIcon from '@mui/icons-material/Delete' -import { - Alert, - Box, - Button, - FormControlLabel, - Radio, - RadioGroup, - TextField, - Tooltip, -} from '@mui/material' -import React, { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -const modelFormatData = [ - { - type: 'LLM', - options: [ - { value: 'pytorch', label: 'PyTorch' }, - { value: 'ggufv2', label: 'GGUF' }, - { value: 'gptq', label: 'GPTQ' }, - { value: 'awq', label: 'AWQ' }, - { value: 'fp8', label: 'FP8' }, - { value: 'mlx', label: 'MLX' }, - ], - }, - { - type: 'embedding', - options: [ - { value: 'pytorch', label: 'PyTorch' }, - { value: 'ggufv2', label: 'GGUF' }, - ], - }, - { - type: 'rerank', - options: [ - { value: 'pytorch', label: 'PyTorch' }, - { value: 'ggufv2', label: 'GGUF' }, - ], - }, -] - -const modelUriDefault = { - LLM: '/path/to/llama', - embedding: '/path/to/embedding', - rerank: '/path/to/rerank', -} - -const AddModelSpecs = ({ - isJump, - formData, - specsDataArr, - onGetArr, - scrollRef, - modelType, -}) => { - const [count, setCount] = useState(0) - const [specsArr, setSpecsArr] = useState([]) - const [pathArr, setPathArr] = useState([]) - const [modelSizeAlertId, setModelSizeAlertId] = useState([]) - const [quantizationAlertId, setQuantizationAlertId] = useState([]) - const [isError, setIsError] = useState(false) - const [isAdd, setIsAdd] = useState(false) - const { t } = useTranslation() - - useEffect(() => { - if (isJump) { - const dataArr = specsDataArr.map((item, index) => { - const { - model_uri, - model_size_in_billions, - model_format, - quantization, - model_file_name_template, - } = item - let size = model_size_in_billions - if (typeof size !== 'number') size = size?.split('_').join('.') - - return { - id: index, - model_uri, - model_size_in_billions: size, - model_format, - quantization, - model_file_name_template, - } - }) - setCount(dataArr.length) - setSpecsArr(dataArr) - - const subPathArr = [] - specsDataArr.forEach((item) => { - if (item.model_format !== 'ggufv2') { - subPathArr.push(item.model_uri) - } else { - subPathArr.push(item.model_uri + '/' + item.model_file_name_template) - } - }) - setPathArr(subPathArr) - } else { - setSpecsArr([ - { - id: count, - ...formData, - }, - ]) - setCount(count + 1) - setPathArr([formData.model_uri]) - } - }, [specsDataArr]) - - useEffect(() => { - const arr = specsArr.map((item) => { - const { - model_uri: uri, - model_size_in_billions: size, - model_format: modelFormat, - quantization, - model_file_name_template, - } = item - - let handleSize - if (modelType === 'LLM') { - handleSize = - parseInt(size) === parseFloat(size) - ? Number(size) - : size.split('.').join('_') - } - - let handleQuantization = quantization - if (modelFormat === 'pytorch') { - handleQuantization = 'none' - } else if (handleQuantization === '' && modelFormat === 'ggufv2') { - handleQuantization = 'default' - } - - return { - model_uri: uri, - ...(modelType === 'LLM' && { - model_size_in_billions: handleSize, - }), - model_format: modelFormat, - quantization: handleQuantization, - model_file_name_template, - } - }) - setIsError(true) - if (modelSizeAlertId.length === 0 && quantizationAlertId.length === 0) { - setIsError(false) - } - onGetArr(arr, isError) - isAdd && handleScrollBottom() - setIsAdd(false) - }, [specsArr, isError]) - - const handleAddSpecs = () => { - setCount(count + 1) - const item = { - id: count, - model_uri: modelUriDefault[modelType], - model_size_in_billions: 7, - model_format: 'pytorch', - quantization: '', - } - setSpecsArr([...specsArr, item]) - setIsAdd(true) - setPathArr([...pathArr, modelUriDefault[modelType]]) - } - - const handleUpdateSpecsArr = (index, type, newValue) => { - if (type === 'model_format') { - const subPathArr = [...pathArr] - if (specsArr[index].model_format !== 'ggufv2') { - pathArr[index] = specsArr[index].model_uri - } else { - pathArr[index] = - specsArr[index].model_uri + - '/' + - specsArr[index].model_file_name_template - } - setPathArr(subPathArr) - } - - setSpecsArr( - specsArr.map((item, subIndex) => { - if (subIndex === index) { - if (type === '') { - return { ...item, [type]: [newValue] } - } else if (type === 'model_format') { - if (newValue === 'ggufv2') { - const { baseDir, filename } = getPathComponents(pathArr[index]) - const obj = { - ...item, - model_format: newValue, - quantization: '', - model_uri: baseDir, - model_file_name_template: filename, - } - return obj - } else { - const { id, model_size_in_billions, model_format } = item - return { - id, - model_uri: pathArr[index], - model_size_in_billions, - model_format, - [type]: newValue, - quantization: '', - } - } - } else if (type === 'model_uri') { - const subPathArr = [...pathArr] - subPathArr[index] = newValue - setPathArr(subPathArr) - if (item.model_format === 'ggufv2') { - const { baseDir, filename } = getPathComponents(newValue) - const obj = { - ...item, - model_uri: baseDir, - model_file_name_template: filename, - } - return obj - } else { - return { ...item, [type]: newValue } - } - } else { - return { ...item, [type]: newValue } - } - } - return item - }) - ) - } - - const handleDeleteSpecs = (index) => { - setSpecsArr(specsArr.filter((_, subIndex) => index !== subIndex)) - } - - const getPathComponents = (path) => { - const normalizedPath = path.replace(/\\/g, '/') - const baseDir = normalizedPath.substring(0, normalizedPath.lastIndexOf('/')) - const filename = normalizedPath.substring( - normalizedPath.lastIndexOf('/') + 1 - ) - return { baseDir, filename } - } - - const handleModelSize = (index, value, id) => { - setModelSizeAlertId(modelSizeAlertId.filter((item) => item !== id)) - handleUpdateSpecsArr(index, 'model_size_in_billions', value) - if (value !== '' && (!Number(value) || Number(value) <= 0)) { - const modelSizeAlertIdArr = Array.from(new Set([...modelSizeAlertId, id])) - setModelSizeAlertId(modelSizeAlertIdArr) - } - } - - const handleQuantization = (model_format, index, value, id) => { - setQuantizationAlertId(quantizationAlertId.filter((item) => item !== id)) - handleUpdateSpecsArr(index, 'quantization', value) - if ( - (model_format === 'gptq' || - model_format === 'awq' || - model_format === 'fp8' || - model_format === 'mlx') && - value === '' - ) { - const quantizationAlertIdArr = Array.from( - new Set([...quantizationAlertId, id]) - ) - setQuantizationAlertId(quantizationAlertIdArr) - } - } - - const handleScrollBottom = () => { - scrollRef.current.scrollTo({ - top: scrollRef.current.scrollHeight, - behavior: 'smooth', - }) - } - - return ( - <> - <div style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}> - <label style={{ width: '100px' }}> - {t('registerModel.modelSpecs')} - </label> - <Button - variant="contained" - size="small" - endIcon={<AddIcon />} - className="addBtn" - onClick={handleAddSpecs} - > - {t('registerModel.more')} - </Button> - </div> - <div className="specs_container"> - {specsArr.map((item, index) => ( - <div className="item" key={item.id}> - <label - style={{ - paddingLeft: 5, - }} - > - {t('registerModel.modelFormat')} - </label> - <RadioGroup - value={item.model_format} - onChange={(e) => { - handleUpdateSpecsArr(index, 'model_format', e.target.value) - if ( - e.target.value === 'gptq' || - e.target.value === 'awq' || - e.target.value === 'fp8' || - e.target.value === 'mlx' - ) { - const quantizationAlertIdArr = Array.from( - new Set([...quantizationAlertId, item.id]) - ) - setQuantizationAlertId(quantizationAlertIdArr) - } else { - setQuantizationAlertId([]) - } - }} - > - <Box sx={styles.checkboxWrapper}> - {modelFormatData - .find((item) => item.type === modelType) - .options.map((item) => ( - <Box key={item.value} sx={{ marginLeft: '10px' }}> - <FormControlLabel - value={item.value} - control={<Radio />} - label={item.label} - /> - </Box> - ))} - </Box> - </RadioGroup> - <Box padding="15px"></Box> - - <TextField - error={item.model_uri !== '' ? false : true} - style={{ minWidth: '60%' }} - label={t('registerModel.modelPath')} - size="small" - value={ - item.model_format !== 'ggufv2' - ? item.model_uri - : item.model_uri + '/' + item.model_file_name_template - } - onChange={(e) => { - handleUpdateSpecsArr(index, 'model_uri', e.target.value) - }} - helperText={t('registerModel.provideModelDirectoryOrFilePath')} - /> - <Box padding="15px"></Box> - - {modelType === 'LLM' && ( - <> - <TextField - error={Number(item.model_size_in_billions) > 0 ? false : true} - label={t('registerModel.modelSizeBillions')} - size="small" - value={item.model_size_in_billions} - onChange={(e) => { - handleModelSize(index, e.target.value, item.id) - }} - /> - {modelSizeAlertId.includes(item.id) && ( - <Alert severity="error"> - {t('registerModel.enterNumberGreaterThanZero')} - </Alert> - )} - <Box padding="15px"></Box> - </> - )} - - {item.model_format !== 'pytorch' && ( - <> - <TextField - style={{ minWidth: '60%' }} - label={ - item.model_format === 'gptq' || - item.model_format === 'awq' || - item.model_format === 'fp8' || - item.model_format === 'mlx' - ? t('registerModel.quantization') - : t('registerModel.quantizationOptional') - } - size="small" - value={item.quantization} - onChange={(e) => { - handleQuantization( - item.model_format, - index, - e.target.value, - item.id - ) - }} - helperText={ - item.model_format === 'gptq' || - item.model_format === 'awq' || - item.model_format === 'fp8' || - item.model_format === 'mlx' - ? t( - 'registerModel.carefulQuantizationForModelRegistration' - ) - : '' - } - /> - {item.model_format !== 'ggufv2' && - quantizationAlertId.includes(item.id) && - item.quantization == '' && ( - <Alert severity="error"> - {t('registerModel.quantizationCannotBeEmpty')} - </Alert> - )} - </> - )} - - {specsArr.length > 1 && ( - <Tooltip title={t('registerModel.delete')} placement="top"> - <div - className="deleteBtn" - onClick={() => handleDeleteSpecs(index)} - > - <DeleteIcon className="deleteIcon" /> - </div> - </Tooltip> - )} - </div> - ))} - </div> - </> - ) -} - -export default AddModelSpecs - -const styles = { - baseFormControl: { - width: '100%', - margin: 'normal', - size: 'small', - }, - checkboxWrapper: { - display: 'flex', - flexWrap: 'wrap', - alignItems: 'center', - width: '100%', - }, -} diff --git a/xinference/ui/web/ui/src/scenes/register_model/components/addStop.js b/xinference/ui/web/ui/src/scenes/register_model/components/addStop.js deleted file mode 100644 index c295cfdde5..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/components/addStop.js +++ /dev/null @@ -1,109 +0,0 @@ -import AddIcon from '@mui/icons-material/Add' -import DeleteIcon from '@mui/icons-material/Delete' -import { Alert, Button, TextField } from '@mui/material' -import React from 'react' -import { useTranslation } from 'react-i18next' - -const regex = /^-?[0-9]\d*$/ - -const AddStop = ({ - label, - onGetData, - arrItemType, - formData, - onGetError, - helperText, -}) => { - const { t } = useTranslation() - const handleChange = (value, index) => { - const arr = [...formData] - arr[index] = value - if (arrItemType === 'number') { - const newDataArr = arr.map((item) => { - if (item && regex.test(item)) { - arr.push('true') - return Number(item) - } - if (item && !regex.test(item)) arr.push('false') - return item - }) - onGetError(arr) - onGetData(newDataArr) - } else { - onGetData([...arr]) - } - } - - const handleAdd = () => { - if (formData[formData.length - 1]) { - onGetData([...formData, '']) - } - } - - const handleDelete = (index) => { - onGetData(formData.filter((_, subIndex) => index !== subIndex)) - } - - const handleShowAlert = (item) => { - return item !== '' && !regex.test(item) && arrItemType === 'number' - } - - return ( - <> - <div> - <div - style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }} - > - <label style={{ width: '100px' }}>{label}</label> - <Button - variant="contained" - size="small" - endIcon={<AddIcon />} - className="addBtn" - onClick={handleAdd} - > - {t('registerModel.more')} - </Button> - </div> - <div - style={{ - display: 'flex', - flexDirection: 'column', - gap: 10, - marginInline: 50, - padding: 20, - borderRadius: 10, - }} - > - {(formData?.length ? formData : ['']).map((item, index) => ( - <div key={index}> - <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}> - <TextField - value={item} - onChange={(e) => handleChange(e.target.value, index)} - label={helperText} - size="small" - style={{ width: '100%' }} - /> - {formData?.length > 1 && ( - <DeleteIcon - onClick={() => handleDelete(index)} - style={{ cursor: 'pointer', color: '#1976d2' }} - /> - )} - </div> - - {handleShowAlert(item) && ( - <Alert severity="error"> - {t('registerModel.enterInteger')} - </Alert> - )} - </div> - ))} - </div> - </div> - </> - ) -} - -export default AddStop diff --git a/xinference/ui/web/ui/src/scenes/register_model/components/addVirtualenv.js b/xinference/ui/web/ui/src/scenes/register_model/components/addVirtualenv.js deleted file mode 100644 index b25db09919..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/components/addVirtualenv.js +++ /dev/null @@ -1,89 +0,0 @@ -import AddIcon from '@mui/icons-material/Add' -import DeleteIcon from '@mui/icons-material/Delete' -import { Button, TextField } from '@mui/material' -import React, { useEffect, useRef, useState } from 'react' -import { useTranslation } from 'react-i18next' - -const AddVirtualenv = ({ virtualenv, onChangeVirtualenv, scrollRef }) => { - const { t } = useTranslation() - - const [packageKeys, setPackageKeys] = useState(() => - virtualenv.packages.map(() => `${Date.now()}-${Math.random()}`) - ) - - const prevPackagesLenRef = useRef(virtualenv.packages.length) - - useEffect(() => { - const newLen = virtualenv.packages.length - if (newLen > prevPackagesLenRef.current) { - scrollRef.current.scrollTo({ - top: scrollRef.current.scrollHeight, - behavior: 'smooth', - }) - } - prevPackagesLenRef.current = newLen - - setPackageKeys((prevKeys) => { - const lengthDiff = virtualenv.packages.length - prevKeys.length - - if (lengthDiff > 0) { - return [ - ...prevKeys, - ...new Array(lengthDiff) - .fill(0) - .map(() => `${Date.now()}-${Math.random()}`), - ] - } else if (lengthDiff < 0) { - return prevKeys.slice(0, virtualenv.packages.length) - } - - return prevKeys - }) - }, [virtualenv.packages]) - - return ( - <div> - <label style={{ marginBottom: '20px', marginRight: '20px' }}> - {t('registerModel.packages')} - </label> - <Button - variant="contained" - size="small" - endIcon={<AddIcon />} - onClick={() => onChangeVirtualenv('add')} - > - {t('registerModel.more')} - </Button> - - <div> - {virtualenv.packages.map((item, index) => ( - <div - key={packageKeys[index]} - style={{ - display: 'flex', - alignItems: 'center', - gap: 5, - marginTop: '10px', - marginLeft: 50, - }} - > - <TextField - style={{ width: '100%' }} - size="small" - value={item} - onChange={(e) => { - onChangeVirtualenv('change', index, e.target.value) - }} - /> - <DeleteIcon - onClick={() => onChangeVirtualenv('delete', index)} - style={{ cursor: 'pointer', color: '#1976d2' }} - /> - </div> - ))} - </div> - </div> - ) -} - -export default AddVirtualenv diff --git a/xinference/ui/web/ui/src/scenes/register_model/data/languages.js b/xinference/ui/web/ui/src/scenes/register_model/data/languages.js deleted file mode 100644 index a765da20c2..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/data/languages.js +++ /dev/null @@ -1,192 +0,0 @@ -const languagesArr = [ - { code: 'ab', language: 'Abkhazian' }, - { code: 'aa', language: 'Afar' }, - { code: 'af', language: 'Afrikaans' }, - { code: 'ak', language: 'Akan' }, - { code: 'sq', language: 'Albanian' }, - { code: 'am', language: 'Amharic' }, - { code: 'ar', language: 'Arabic' }, - { code: 'an', language: 'Aragonese' }, - { code: 'hy', language: 'Armenian' }, - { code: 'as', language: 'Assamese' }, - { code: 'av', language: 'Avaric' }, - { code: 'ae', language: 'Avestan' }, - { code: 'ay', language: 'Aymara' }, - { code: 'az', language: 'Azerbaijani' }, - { code: 'bm', language: 'Bambara' }, - { code: 'ba', language: 'Bashkir' }, - { code: 'eu', language: 'Basque' }, - { code: 'be', language: 'Belarusian' }, - { code: 'bn', language: 'Bengali' }, - { code: 'bh', language: 'Bihari' }, - { code: 'bi', language: 'Bislama' }, - { code: 'bs', language: 'Bosnian' }, - { code: 'br', language: 'Breton' }, - { code: 'bg', language: 'Bulgarian' }, - { code: 'my', language: 'Burmese' }, - { code: 'ca', language: 'Catalan, Valencian' }, - { code: 'ch', language: 'Chamorro' }, - { code: 'ce', language: 'Chechen' }, - { code: 'ny', language: 'Chichewa, Chewa, Nyanja' }, - // { code: 'zh', language: 'Chinese' }, - { code: 'cv', language: 'Chuvash' }, - { code: 'kw', language: 'Cornish' }, - { code: 'co', language: 'Corsican' }, - { code: 'cr', language: 'Cree' }, - { code: 'hr', language: 'Croatian' }, - { code: 'cs', language: 'Czech' }, - { code: 'da', language: 'Danish' }, - { code: 'dv', language: 'Divehi, Dhivehi, Maldivian' }, - { code: 'nl', language: 'Dutch, Flemish' }, - { code: 'dz', language: 'Dzongkha' }, - // { code: 'en', language: 'English' }, - { code: 'eo', language: 'Esperanto' }, - { code: 'et', language: 'Estonian' }, - { code: 'ee', language: 'Ewe' }, - { code: 'fo', language: 'Faroese' }, - { code: 'fj', language: 'Fijian' }, - { code: 'fi', language: 'Finnish' }, - { code: 'fr', language: 'French' }, - { code: 'ff', language: 'Fulah' }, - { code: 'gl', language: 'Galician' }, - { code: 'ka', language: 'Georgian' }, - { code: 'de', language: 'German' }, - { code: 'el', language: 'Greek' }, - { code: 'gn', language: 'Guarani' }, - { code: 'gu', language: 'Gujarati' }, - { code: 'ht', language: 'Haitian, Haitian Creole' }, - { code: 'ha', language: 'Hausa' }, - { code: 'he', language: 'Hebrew' }, - { code: 'hz', language: 'Herero' }, - { code: 'hi', language: 'Hindi' }, - { code: 'ho', language: 'Hiri Motu' }, - { code: 'hu', language: 'Hungarian' }, - { code: 'ia', language: 'Interlingua' }, - { code: 'id', language: 'Indonesian' }, - { code: 'ie', language: 'Interlingue, Occidental' }, - { code: 'ga', language: 'Irish' }, - { code: 'ig', language: 'Igbo' }, - { code: 'ik', language: 'Inupiaq' }, - { code: 'io', language: 'Ido' }, - { code: 'is', language: 'Icelandic' }, - { code: 'it', language: 'Italian' }, - { code: 'iu', language: 'Inuktitut' }, - { code: 'ja', language: 'Japanese' }, - { code: 'jv', language: 'Javanese' }, - { code: 'kl', language: 'Kalaallisut, Greenlandic' }, - { code: 'kn', language: 'Kannada' }, - { code: 'kr', language: 'Kanuri' }, - { code: 'ks', language: 'Kashmiri' }, - { code: 'kk', language: 'Kazakh' }, - { code: 'km', language: 'Central Khmer' }, - { code: 'ki', language: 'Kikuyu, Gikuyu' }, - { code: 'rw', language: 'Kinyarwanda' }, - { code: 'ky', language: 'Kirghiz, Kyrgyz' }, - { code: 'kv', language: 'Komi' }, - { code: 'kg', language: 'Kongo' }, - { code: 'ko', language: 'Korean' }, - { code: 'ku', language: 'Kurdish' }, - { code: 'kj', language: 'Kuanyama, Kwanyama' }, - { code: 'la', language: 'Latin' }, - { code: 'lb', language: 'Luxembourgish, Letzeburgesch' }, - { code: 'lg', language: 'Ganda' }, - { code: 'li', language: 'Limburgan, Limburger, Limburgish' }, - { code: 'ln', language: 'Lingala' }, - { code: 'lo', language: 'Lao' }, - { code: 'lt', language: 'Lithuanian' }, - { code: 'lu', language: 'Luba-Katanga' }, - { code: 'lv', language: 'Latvian' }, - { code: 'gv', language: 'Manx' }, - { code: 'mk', language: 'Macedonian' }, - { code: 'mg', language: 'Malagasy' }, - { code: 'ms', language: 'Malay' }, - { code: 'ml', language: 'Malayalam' }, - { code: 'mt', language: 'Maltese' }, - { code: 'mi', language: 'Maori' }, - { code: 'mr', language: 'Marathi' }, - { code: 'mh', language: 'Marshallese' }, - { code: 'mn', language: 'Mongolian' }, - { code: 'na', language: 'Nauru' }, - { code: 'nv', language: 'Navajo, Navaho' }, - { code: 'nd', language: 'North Ndebele' }, - { code: 'ne', language: 'Nepali' }, - { code: 'ng', language: 'Ndonga' }, - { code: 'nb', language: 'Norwegian Bokmål' }, - { code: 'nn', language: 'Norwegian Nynorsk' }, - { code: 'no', language: 'Norwegian' }, - { code: 'ii', language: 'Sichuan Yi, Nuosu' }, - { code: 'nr', language: 'South Ndebele' }, - { code: 'oc', language: 'Occitan' }, - { code: 'oj', language: 'Ojibwa' }, - { - code: 'cu', - language: - 'Church Slavic, Old Slavonic, Church Slavonic, Old Bulgarian, Old Church Slavonic', - }, - { code: 'om', language: 'Oromo' }, - { code: 'or', language: 'Oriya' }, - { code: 'os', language: 'Ossetian, Ossetic' }, - { code: 'pa', language: 'Punjabi, Panjabi' }, - { code: 'pi', language: 'Pali' }, - { code: 'fa', language: 'Persian' }, - { code: 'pl', language: 'Polish' }, - { code: 'ps', language: 'Pashto, Pushto' }, - { code: 'pt', language: 'Portuguese' }, - { code: 'qu', language: 'Quechua' }, - { code: 'rm', language: 'Romansh' }, - { code: 'rn', language: 'Rundi' }, - { code: 'ro', language: 'Romanian, Moldavian, Moldovan' }, - { code: 'ru', language: 'Russian' }, - { code: 'sa', language: 'Sanskrit' }, - { code: 'sc', language: 'Sardinian' }, - { code: 'sd', language: 'Sindhi' }, - { code: 'se', language: 'Northern Sami' }, - { code: 'sm', language: 'Samoan' }, - { code: 'sg', language: 'Sango' }, - { code: 'sr', language: 'Serbian' }, - { code: 'gd', language: 'Gaelic, Scottish Gaelic' }, - { code: 'sn', language: 'Shona' }, - { code: 'si', language: 'Sinhala, Sinhalese' }, - { code: 'sk', language: 'Slovak' }, - { code: 'sl', language: 'Slovenian' }, - { code: 'so', language: 'Somali' }, - { code: 'st', language: 'Southern Sotho' }, - { code: 'es', language: 'Spanish, Castilian' }, - { code: 'su', language: 'Sundanese' }, - { code: 'sw', language: 'Swahili' }, - { code: 'ss', language: 'Swati' }, - { code: 'sv', language: 'Swedish' }, - { code: 'ta', language: 'Tamil' }, - { code: 'te', language: 'Telugu' }, - { code: 'tg', language: 'Tajik' }, - { code: 'th', language: 'Thai' }, - { code: 'ti', language: 'Tigrinya' }, - { code: 'bo', language: 'Tibetan' }, - { code: 'tk', language: 'Turkmen' }, - { code: 'tl', language: 'Tagalog' }, - { code: 'tn', language: 'Tswana' }, - { code: 'to', language: 'Tonga' }, - { code: 'tr', language: 'Turkish' }, - { code: 'ts', language: 'Tsonga' }, - { code: 'tt', language: 'Tatar' }, - { code: 'tw', language: 'Twi' }, - { code: 'ty', language: 'Tahitian' }, - { code: 'ug', language: 'Uighur, Uyghur' }, - { code: 'uk', language: 'Ukrainian' }, - { code: 'ur', language: 'Urdu' }, - { code: 'uz', language: 'Uzbek' }, - { code: 've', language: 'Venda' }, - { code: 'vi', language: 'Vietnamese' }, - { code: 'vo', language: 'Volapük' }, - { code: 'wa', language: 'Walloon' }, - { code: 'cy', language: 'Welsh' }, - { code: 'wo', language: 'Wolof' }, - { code: 'fy', language: 'West Frisian' }, - { code: 'xh', language: 'Xhosa' }, - { code: 'yi', language: 'Yiddish' }, - { code: 'yo', language: 'Yoruba' }, - { code: 'za', language: 'Zhuang, Chuang' }, - { code: 'zu', language: 'Zulu' }, -] - -export default languagesArr diff --git a/xinference/ui/web/ui/src/scenes/register_model/index.js b/xinference/ui/web/ui/src/scenes/register_model/index.js deleted file mode 100644 index cd97b2e094..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/index.js +++ /dev/null @@ -1,191 +0,0 @@ -import { TabContext, TabList, TabPanel } from '@mui/lab' -import { Box, Tab } from '@mui/material' -import React, { useEffect } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate } from 'react-router-dom' - -import ErrorMessageSnackBar from '../../components/errorMessageSnackBar' -import Title from '../../components/Title' -import { isValidBearerToken } from '../../components/utils' -import RegisterModelComponent from './registerModel' - -const RegisterModel = () => { - const [tabValue, setTabValue] = React.useState( - sessionStorage.getItem('registerModelType') - ? sessionStorage.getItem('registerModelType') - : '/register_model/llm' - ) - const [cookie] = useCookies(['token']) - const navigate = useNavigate() - const { t } = useTranslation() - - useEffect(() => { - if ( - sessionStorage.getItem('auth') === 'true' && - !isValidBearerToken(sessionStorage.getItem('token')) && - !isValidBearerToken(cookie.token) - ) { - navigate('/login', { replace: true }) - } - }, [cookie.token]) - - const handleTabChange = (_, newValue) => { - setTabValue(newValue) - navigate(newValue) - sessionStorage.setItem('registerModelType', newValue) - } - - return ( - <Box m="20px" style={{ overflow: 'hidden' }}> - <Title title={t('menu.registerModel')} /> - <ErrorMessageSnackBar /> - <TabContext value={tabValue}> - <Box sx={{ borderBottom: 1, borderColor: 'divider' }}> - <TabList - value={tabValue} - onChange={handleTabChange} - aria-label="tabs" - > - <Tab - label={t('model.languageModels')} - value="/register_model/llm" - /> - <Tab - label={t('model.embeddingModels')} - value="/register_model/embedding" - /> - <Tab - label={t('model.rerankModels')} - value="/register_model/rerank" - /> - <Tab label={t('model.imageModels')} value="/register_model/image" /> - <Tab label={t('model.audioModels')} value="/register_model/audio" /> - <Tab - label={t('model.flexibleModels')} - value="/register_model/flexible" - /> - </TabList> - </Box> - <TabPanel value="/register_model/llm" sx={{ padding: 0 }}> - <RegisterModelComponent - modelType="LLM" - customData={{ - version: 2, - model_name: 'custom-llm', - model_description: 'This is a custom model description.', - context_length: 2048, - model_lang: ['en'], - model_ability: ['generate'], - model_specs: [ - { - model_uri: '/path/to/llama-1', - model_size_in_billions: 7, - model_format: 'pytorch', - quantization: 'none', - }, - ], - model_family: 'your_custom_model', - virtualenv: { - packages: [], - }, - }} - /> - </TabPanel> - <TabPanel value="/register_model/embedding" sx={{ padding: 0 }}> - <RegisterModelComponent - modelType="embedding" - customData={{ - version: 2, - model_name: 'custom-embedding', - dimensions: 768, - max_tokens: 512, - language: ['en'], - model_specs: [ - { - model_uri: '/path/to/embedding-1', - model_format: 'pytorch', - quantization: 'none', - }, - ], - virtualenv: { - packages: [], - }, - }} - /> - </TabPanel> - <TabPanel value="/register_model/rerank" sx={{ padding: 0 }}> - <RegisterModelComponent - modelType="rerank" - customData={{ - version: 2, - model_name: 'custom-rerank', - language: ['en'], - max_tokens: 512, - model_specs: [ - { - model_uri: '/path/to/rerank-1', - model_format: 'pytorch', - quantization: 'none', - }, - ], - virtualenv: { - packages: [], - }, - }} - /> - </TabPanel> - <TabPanel value="/register_model/image" sx={{ padding: 0 }}> - <RegisterModelComponent - modelType="image" - customData={{ - version: 2, - model_name: 'custom-image', - model_uri: '/path/to/image-model', - model_ability: [], - model_family: 'stable_diffusion', - controlnet: [], - virtualenv: { - packages: [], - }, - }} - /> - </TabPanel> - <TabPanel value="/register_model/audio" sx={{ padding: 0 }}> - <RegisterModelComponent - modelType="audio" - customData={{ - version: 2, - model_name: 'custom-audio', - model_uri: '/path/to/audio-model', - multilingual: false, - model_family: 'whisper', - model_ability: ['text2audio'], - virtualenv: { - packages: [], - }, - }} - /> - </TabPanel> - <TabPanel value="/register_model/flexible" sx={{ padding: 0 }}> - <RegisterModelComponent - modelType="flexible" - customData={{ - version: 2, - model_name: 'flexible-model', - model_description: 'This is a model description.', - model_uri: '/path/to/model', - launcher: 'xinference.model.flexible.launchers.transformers', - launcher_args: '{}', - virtualenv: { - packages: [], - }, - }} - /> - </TabPanel> - </TabContext> - </Box> - ) -} - -export default RegisterModel diff --git a/xinference/ui/web/ui/src/scenes/register_model/registerModel.js b/xinference/ui/web/ui/src/scenes/register_model/registerModel.js deleted file mode 100644 index dbe1558803..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/registerModel.js +++ /dev/null @@ -1,1890 +0,0 @@ -import './styles/registerModelStyle.css' - -import { - AutoFixHigh, - Cancel, - CheckCircle, - KeyboardDoubleArrowRight, - Notes, - OpenInFull, -} from '@mui/icons-material' -import { - Alert, - Autocomplete, - Box, - Button, - Checkbox, - Chip, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - FormControl, - FormControlLabel, - InputLabel, - MenuItem, - Radio, - RadioGroup, - Select, - Stack, - Switch, - TextField, - Tooltip, -} from '@mui/material' -import nunjucks from 'nunjucks' -import React, { useContext, useEffect, useMemo, useRef, useState } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useNavigate, useParams } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import CopyComponent from '../../components/copyComponent' -import fetchWrapper from '../../components/fetchWrapper' -import { isValidBearerToken } from '../../components/utils' -import AddControlnet from './components/addControlnet' -import AddModelSpecs from './components/addModelSpecs' -import AddStop from './components/addStop' -import AddVirtualenv from './components/addVirtualenv' -import languages from './data/languages' -const SUPPORTED_LANGUAGES_DICT = { en: 'English', zh: 'Chinese' } -const model_ability_options = [ - { - type: 'LLM', - options: [ - 'Generate', - 'Chat', - 'Vision', - 'Tools', - 'Reasoning', - 'Audio', - 'Omni', - 'Hybrid', - ], - }, - { - type: 'image', - options: ['text2image', 'image2image', 'inpainting'], - }, - { - type: 'audio', - options: ['text2audio', 'audio2text'], - }, -] -const messages = [ - { - role: 'assistant', - content: 'This is the message content replied by the assistant previously', - }, - { - role: 'user', - content: 'This is the message content sent by the user currently', - }, -] -const model_family_options = [ - { - type: 'image', - options: ['stable_diffusion'], - }, - { - type: 'audio', - options: [ - 'whisper', - 'ChatTTS', - 'CosyVoice', - 'F5-TTS', - 'F5-TTS-MLX', - 'FishAudio', - 'Kokoro', - 'MegaTTS', - 'MeloTTS', - 'funasr', - ], - }, -] - -// Convert dictionary of supported languages into list -const SUPPORTED_LANGUAGES = Object.keys(SUPPORTED_LANGUAGES_DICT) - -const RegisterModelComponent = ({ modelType, customData }) => { - const endPoint = useContext(ApiContext).endPoint - const { setErrorMsg } = useContext(ApiContext) - const [formData, setFormData] = useState(customData) - const [promptStyles, setPromptStyles] = useState([]) - const [family, setFamily] = useState({}) - const [languagesArr, setLanguagesArr] = useState([]) - const [isContextLengthAlert, setIsContextLengthAlert] = useState(false) - const [isDimensionsAlert, setIsDimensionsAlert] = useState(false) - const [isMaxTokensAlert, setIsMaxTokensAlert] = useState(false) - const [jsonData, setJsonData] = useState('') - const [isSpecsArrError, setIsSpecsArrError] = useState(false) - const [isValidLauncherArgsAlert, setIsValidLauncherArgsAlert] = - useState(false) - const scrollRef = useRef(null) - const [cookie] = useCookies(['token']) - const navigate = useNavigate() - - const { registerModelType, model_name } = useParams() - const [isShow, setIsShow] = useState(model_name ? true : false) - const [specsArr, setSpecsArr] = useState( - model_name - ? JSON.parse(sessionStorage.getItem('customJsonData')).model_specs - : [] - ) - const [controlnetArr, setControlnetArr] = useState( - model_name - ? JSON.parse(sessionStorage.getItem('customJsonData')).controlnet - : [] - ) - const [contrastObj, setContrastObj] = useState({}) - const [isEqual, setIsEqual] = useState(true) - const [testRes, setTestRes] = useState('') - const [isOpenMessages, setIsOpenMessages] = useState(false) - const [testErrorInfo, setTestErrorInfo] = useState('') - const [isStopTokenIdsAlert, setIsStopTokenIdsAlert] = useState(false) - const [familyOptions, setFamilyOptions] = useState([]) - const [isEditableFamily, setIsEditableFamily] = useState(true) - const [openAutoFillDialog, setOpenAutoFillDialog] = useState(false) - const [autoFillModelPath, setAutoFillModelPath] = useState('') - const [autoFillModelFamily, setAutoFillModelFamily] = useState('') - const { t } = useTranslation() - - const allFamilies = useMemo(() => { - return [ - ...new Set( - Object.values(family || {}).reduce( - (acc, cur) => acc.concat(cur || []), - [] - ) - ), - ] - }, [family]) - - useEffect(() => { - if (model_name) { - const data = JSON.parse(sessionStorage.getItem('customJsonData')) - - if (modelType === 'LLM') { - const lagArr = data.model_lang.filter( - (item) => item !== 'en' && item !== 'zh' - ) - setLanguagesArr(lagArr) - - const { - version, - model_name, - model_description, - context_length, - model_lang, - model_ability, - model_family, - model_specs, - chat_template, - stop_token_ids, - stop, - reasoning_start_tag = '', - reasoning_end_tag = '', - } = data - const virtualenv = data.virtualenv ?? { packages: [] } - const specsDataArr = model_specs.map((item) => { - const { - model_uri, - model_size_in_billions, - model_format, - quantizations, - model_file_name_template, - } = item - return { - model_uri, - model_size_in_billions, - model_format, - quantizations, - model_file_name_template, - } - }) - const llmData = { - version, - model_name, - model_description, - context_length, - model_lang, - model_ability, - model_family, - model_specs: specsDataArr, - chat_template, - stop_token_ids, - stop, - ...(model_ability.includes('reasoning') && { - reasoning_start_tag, - reasoning_end_tag, - }), - virtualenv, - } - setFormData(llmData) - setContrastObj(llmData) - setSpecsArr(specsDataArr) - } else { - if (modelType === 'embedding') { - const lagArr = data.language.filter( - (item) => item !== 'en' && item !== 'zh' - ) - setLanguagesArr(lagArr) - - const { - version, - model_name, - dimensions, - max_tokens, - model_uri, - language, - } = data - const model_specs = data.model_specs ?? [ - { - model_uri: model_uri, - model_format: 'pytorch', - quantization: 'none', - }, - ] - const virtualenv = data.virtualenv ?? { packages: [] } - const embeddingData = { - version, - model_name, - dimensions, - max_tokens, - language, - model_specs, - virtualenv, - } - setFormData(embeddingData) - setContrastObj(embeddingData) - } else if (modelType === 'rerank') { - const lagArr = data.language.filter( - (item) => item !== 'en' && item !== 'zh' - ) - setLanguagesArr(lagArr) - - const { - version, - model_name, - max_tokens = 512, - model_uri, - language, - } = data - const model_specs = data.model_specs ?? [ - { - model_uri: model_uri, - model_format: 'pytorch', - quantization: 'none', - }, - ] - const virtualenv = data.virtualenv ?? { packages: [] } - const rerankData = { - version, - model_name, - max_tokens, - language, - model_specs, - virtualenv, - } - setFormData(rerankData) - setContrastObj(rerankData) - } else if (modelType === 'image') { - const { - version, - model_name, - model_uri, - model_family, - model_ability = [], - controlnet, - } = data - const virtualenv = data.virtualenv ?? { packages: [] } - const controlnetArr = controlnet.map((item) => { - const { model_name, model_uri, model_family } = item - return { - model_name, - model_uri, - model_family, - } - }) - const imageData = { - version, - model_name, - model_uri, - model_family, - model_ability, - controlnet: controlnetArr, - virtualenv, - } - setFormData(imageData) - setContrastObj(imageData) - setControlnetArr(controlnetArr) - } else if (modelType === 'audio') { - const { - version, - model_name, - model_uri, - multilingual, - model_ability = [], - model_family, - } = data - const virtualenv = data.virtualenv ?? { packages: [] } - const audioData = { - version, - model_name, - model_uri, - multilingual, - model_ability, - model_family, - virtualenv, - } - setFormData(audioData) - setContrastObj(audioData) - } else if (modelType === 'flexible') { - const { - version, - model_name, - model_uri, - model_description, - launcher, - launcher_args, - } = data - const virtualenv = data.virtualenv ?? { packages: [] } - const flexibleData = { - version, - model_name, - model_uri, - model_description, - launcher, - launcher_args, - virtualenv, - } - setFormData(flexibleData) - setContrastObj(flexibleData) - } - } - } - }, [model_name]) - - useEffect(() => { - if ( - sessionStorage.getItem('auth') === 'true' && - !isValidBearerToken(sessionStorage.getItem('token')) && - !isValidBearerToken(cookie.token) - ) { - navigate('/login', { replace: true }) - return - } - - const getBuiltinFamilies = async () => { - const response = await fetch(endPoint + '/v1/models/families', { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }) - if (!response.ok) { - const errorData = await response.json() // Assuming the server returns error details in JSON format - setErrorMsg( - `Server error: ${response.status} - ${ - errorData.detail || 'Unknown error' - }` - ) - } else { - const data = await response.json() - for (let key in data) { - data[key] = data[key].sort(function (a, b) { - let lowerA = a.toLowerCase() - let lowerB = b.toLowerCase() - - if (lowerA < lowerB) { - return -1 - } - if (lowerA > lowerB) { - return 1 - } - return 0 - }) - } - setFamily(data) - } - } - - const getBuiltInPromptStyles = async () => { - const response = await fetch(endPoint + '/v1/models/prompts', { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }) - if (!response.ok) { - const errorData = await response.json() // Assuming the server returns error details in JSON format - setErrorMsg( - `Server error: ${response.status} - ${ - errorData.detail || 'Unknown error' - }` - ) - } else { - const data = await response.json() - let res = [] - for (const key in data) { - let v = data[key] - v['name'] = key - res.push(v) - } - setPromptStyles(res) - } - } - - if ( - Object.prototype.hasOwnProperty.call(customData, 'model_ability') && - Object.prototype.hasOwnProperty.call(customData, 'model_family') - ) { - if (promptStyles.length === 0) { - getBuiltInPromptStyles().catch((error) => { - setErrorMsg( - error.message || - 'An unexpected error occurred when getting builtin prompt styles.' - ) - console.error('Error: ', error) - }) - } - if (family?.chat === undefined) { - getBuiltinFamilies().catch((error) => { - setErrorMsg( - error.message || - 'An unexpected error occurred when getting builtin prompt styles.' - ) - console.error('Error: ', error) - }) - } - } - }, [cookie.token]) - - useEffect(() => { - setJsonData(JSON.stringify(formData, customReplacer, 4)) - if (contrastObj.model_name) { - deepEqual(contrastObj, formData) ? setIsEqual(true) : setIsEqual(false) - } - if (family?.chat?.length) handleFamilyOptions(formData.model_ability) - }, [formData]) - - useEffect(() => { - if (family?.chat?.length) handleFamilyOptions(formData.model_ability) - }, [family]) - - const customReplacer = (key, value) => { - if (key === 'chat_template' && value) { - return value.replace(/\\n/g, '\n') - } - return value - } - - const handleClick = async () => { - for (let key in formData) { - const type = Object.prototype.toString.call(formData[key]).slice(8, -1) - if ( - key !== 'model_description' && - ((type === 'Array' && - key !== 'controlnet' && - key !== 'stop_token_ids' && - key !== 'stop' && - formData[key].length === 0) || - (type === 'String' && formData[key] === '') || - (type === 'Number' && formData[key] <= 0)) - ) { - setErrorMsg('Please fill in valid value for all fields') - return - } - } - - if ( - isSpecsArrError || - isContextLengthAlert || - isDimensionsAlert || - isMaxTokensAlert - ) { - setErrorMsg('Please fill in valid value for all fields') - return - } - - try { - fetchWrapper - .post(`/v1/model_registrations/${modelType}`, { - model: JSON.stringify(formData, customReplacer), - persist: true, - }) - .then(() => { - navigate(`/launch_model/custom/${modelType.toLowerCase()}`) - sessionStorage.setItem('modelType', '/launch_model/custom/llm') - sessionStorage.setItem( - 'subType', - `/launch_model/custom/${modelType.toLowerCase()}` - ) - }) - .catch((error) => { - console.error('Error:', error) - if (error.response.status !== 403 && error.response.status !== 401) { - setErrorMsg(error.message) - } - }) - } catch (error) { - console.error('There was a problem with the fetch operation:', error) - setErrorMsg(error.message || 'An unexpected error occurred.') - } - } - - const handleNumber = (value, parameterName) => { - setIsContextLengthAlert(false) - setIsDimensionsAlert(false) - setIsMaxTokensAlert(false) - setFormData({ ...formData, [parameterName]: value }) - - if ( - value !== '' && - (!Number(value) || - Number(value) <= 0 || - parseInt(value) !== parseFloat(value)) - ) { - parameterName === 'context_length' ? setIsContextLengthAlert(true) : '' - parameterName === 'dimensions' ? setIsDimensionsAlert(true) : '' - parameterName === 'max_tokens' ? setIsMaxTokensAlert(true) : '' - } else if (value !== '') { - setFormData({ ...formData, [parameterName]: Number(value) }) - } - } - - const toggleLanguage = (lang) => { - if (modelType === 'LLM') { - if (formData.model_lang.includes(lang)) { - setFormData({ - ...formData, - model_lang: formData.model_lang.filter((l) => l !== lang), - }) - } else { - setFormData({ - ...formData, - model_lang: [...formData.model_lang, lang], - }) - } - } else { - if (formData.language.includes(lang)) { - setFormData({ - ...formData, - language: formData.language.filter((l) => l !== lang), - }) - } else { - setFormData({ - ...formData, - language: [...formData.language, lang], - }) - } - } - } - - const toggleAbility = (ability) => { - const obj = JSON.parse(JSON.stringify(formData)) - const fieldsToDelete = [ - 'chat_template', - 'stop_token_ids', - 'stop', - 'reasoning_start_tag', - 'reasoning_end_tag', - 'tool_parser', - ] - fieldsToDelete.forEach((key) => delete obj[key]) - - const currentAbilities = formData.model_ability - const isRemoving = currentAbilities.includes(ability) - const chatRelatedAbilities = [ - 'chat', - 'vision', - 'tools', - 'reasoning', - 'audio', - 'omni', - 'hybrid', - ] - const isChatRelated = chatRelatedAbilities.includes(ability) - const mutuallyExclusive = { vision: 'tools', tools: 'vision' } - - if (currentAbilities.includes('chat') && ability !== 'chat') { - obj.chat_template = '' - obj.stop_token_ids = [] - obj.stop = [] - } - - if ( - currentAbilities.includes('reasoning') && - ability !== 'reasoning' && - ability !== 'chat' - ) { - obj.reasoning_start_tag = '' - obj.reasoning_end_tag = '' - } - - if ( - currentAbilities.includes('tools') && - ability !== 'tools' && - ability !== 'chat' - ) { - delete obj.tool_parser - } - - if (isRemoving) { - const updatedAbilities = - ability === 'chat' - ? currentAbilities.filter( - (item) => !chatRelatedAbilities.includes(item) - ) - : currentAbilities.filter((item) => item !== ability) - - if (ability === 'tools') { - delete obj.tool_parser - } - - setFormData({ - ...obj, - model_family: '', - model_ability: updatedAbilities, - }) - return - } - - let model_ability = [...currentAbilities] - - if (ability === 'reasoning') { - obj.reasoning_start_tag = '' - obj.reasoning_end_tag = '' - } - - if (ability === 'tools') { - obj.tool_parser = '' - } - - if ( - ability === 'chat' || - (isChatRelated && !currentAbilities.includes('chat')) - ) { - obj.chat_template = '' - obj.stop_token_ids = [] - obj.stop = [] - - if (ability !== 'chat' && !model_ability.includes('chat')) { - model_ability.push('chat') - } - model_ability.push(ability) - } else { - const conflict = mutuallyExclusive[ability] - if (conflict && model_ability.includes(conflict)) { - model_ability = model_ability.filter((item) => item !== conflict) - } - model_ability.push(ability) - } - - setFormData({ - ...obj, - model_family: '', - model_ability, - }) - } - - const toggleImageAbility = (ability) => { - const currentAbilities = formData.model_ability || [] - const isRemoving = currentAbilities.includes(ability) - const updated = isRemoving - ? currentAbilities.filter((item) => item !== ability) - : [...currentAbilities, ability] - - setFormData({ - ...formData, - model_ability: updated, - }) - } - - const handleFamily = (value) => { - if (formData.model_ability.includes('chat')) { - if (family?.chat?.includes(value)) { - const data = promptStyles.find((item) => { - return item.name === value - }) - - const form_data = { - ...formData, - model_family: value, - chat_template: data?.chat_template || null, - stop_token_ids: data?.stop_token_ids || [], - stop: data?.stop || [], - } - - if (formData.model_ability.includes('tools')) { - form_data.tool_parser = data?.tool_parser || '' - } - - if (formData.model_ability.includes('reasoning')) { - form_data.reasoning_start_tag = data?.reasoning_start_tag || '' - form_data.reasoning_end_tag = data?.reasoning_end_tag || '' - } - - setFormData(form_data) - } else { - setFormData({ - ...formData, - model_family: value, - chat_template: '', - stop_token_ids: [], - stop: [], - }) - } - } else { - if (modelType === 'image') { - setFormData({ - ...formData, - model_family: value, - }) - } else { - setFormData({ - ...formData, - model_family: value, - }) - } - } - } - - const handleSelectLanguages = (value) => { - const arr = [...languagesArr, value] - setLanguagesArr(arr) - if (modelType === 'LLM') { - setFormData({ - ...formData, - model_lang: Array.from(new Set([...formData.model_lang, ...arr])), - }) - } else { - setFormData({ - ...formData, - language: Array.from(new Set([...formData.language, ...arr])), - }) - } - } - - const handleDeleteLanguages = (item) => { - const arr = languagesArr.filter((subItem) => subItem !== item) - setLanguagesArr(arr) - if (modelType === 'LLM') { - setFormData({ - ...formData, - model_lang: formData.model_lang.filter((subItem) => subItem !== item), - }) - } else { - setFormData({ - ...formData, - language: formData.language.filter((subItem) => subItem !== item), - }) - } - } - - const getSpecsArr = (arr, isSpecsArrError) => { - setFormData({ ...formData, model_specs: arr }) - setIsSpecsArrError(isSpecsArrError) - } - - const getControlnetArr = (arr) => { - setFormData({ ...formData, controlnet: arr }) - } - - const handleCancel = () => { - navigate(`/launch_model/custom/${registerModelType}`) - } - - const handleEdit = () => { - fetchWrapper - .delete( - `/v1/model_registrations/${ - registerModelType === 'llm' ? 'LLM' : registerModelType - }/${model_name}` - ) - .then(() => handleClick()) - .catch((error) => { - console.error('Error:', error) - if (error.response.status !== 403 && error.response.status !== 401) { - setErrorMsg(error.message) - } - }) - } - - const deepEqual = (obj1, obj2) => { - if (obj1 === obj2) return true - if ( - typeof obj1 !== 'object' || - typeof obj2 !== 'object' || - obj1 == null || - obj2 == null - ) { - return false - } - - let keysA = Object.keys(obj1) - let keysB = Object.keys(obj2) - if (keysA.length !== keysB.length) return false - for (let key of keysA) { - if (!keysB.includes(key) || !deepEqual(obj1[key], obj2[key])) { - return false - } - } - return true - } - - const handleTest = () => { - setTestRes('') - if (formData.chat_template) { - try { - nunjucks.configure({ autoescape: false }) - const test_res = nunjucks.renderString(formData.chat_template, { - messages: messages, - }) - if (test_res === '') { - setTestRes(test_res) - setTestErrorInfo('error') - } else { - setTestRes(test_res) - setTestErrorInfo('') - } - } catch (error) { - setTestErrorInfo(`${error}`) - } - } - } - - const getStopTokenIds = (value) => { - if (value.length === 1 && value[0] === '') { - setFormData({ - ...formData, - stop_token_ids: [], - }) - } else { - setFormData({ - ...formData, - stop_token_ids: value, - }) - } - } - - const getStop = (value) => { - if (value.length === 1 && value[0] === '') { - setFormData({ - ...formData, - stop: [], - }) - } else { - setFormData({ - ...formData, - stop: value, - }) - } - } - - const handleFamilyAlert = () => { - if ( - formData.model_ability?.includes('vision') && - !family?.vision?.includes(formData.model_family) - ) { - return true - } else if ( - formData.model_ability?.includes('tools') && - !family?.tools?.includes(formData.model_family) - ) { - return true - } - return false - } - - const handleChatTemplateAlert = () => { - if ( - familyOptions?.filter((item) => item.id === formData.model_family) - .length === 0 && - !formData.chat_template - ) { - return true - } - return false - } - - const handleFamilyOptions = (model_ability) => { - const abilityMap = { - reasoning: { editable: false, source: family?.reasoning }, - audio: { editable: false, source: family?.audio }, - omni: { editable: false, source: family?.omni }, - hybrid: { editable: false, source: family?.hybrid }, - vision: { editable: false, source: family?.vision }, - tools: { editable: false, source: family?.tools }, - chat: { editable: true, source: family?.chat }, - generate: { editable: true, source: family?.generate }, - } - - const nonEditableGroup = [ - 'reasoning', - 'audio', - 'omni', - 'hybrid', - 'vision', - 'tools', - ] - - const matchedAbilities = Object.keys(abilityMap).filter((key) => - model_ability.includes(key) - ) - - const matchedNonEditable = matchedAbilities.filter((key) => - nonEditableGroup.includes(key) - ) - - if (matchedNonEditable.length > 1) { - const baseSource = abilityMap[matchedNonEditable[0]]?.source || [] - let intersection = new Set(baseSource) - - for (let i = 1; i < matchedNonEditable.length; i++) { - const currentSource = new Set( - abilityMap[matchedNonEditable[i]]?.source || [] - ) - intersection = new Set( - [...intersection].filter((item) => currentSource.has(item)) - ) - } - - setIsEditableFamily(false) - setFamilyOptions( - Array.from(intersection).map((item) => ({ - id: item, - label: item, - })) - ) - return - } - - const matched = matchedAbilities[0] - if (matched) { - const { editable, source } = abilityMap[matched] - setIsEditableFamily(editable) - setFamilyOptions( - (source || []).map((item) => ({ id: item, label: item })) - ) - } else { - setIsEditableFamily(true) - setFamilyOptions([]) - } - } - - const changeVirtualenv = (type, index, value) => { - if (type === 'add') { - setFormData((prev) => { - return { - ...prev, - virtualenv: { - ...prev.virtualenv, - packages: [...prev.virtualenv.packages, ''], - }, - } - }) - } else if (type === 'delete') { - setFormData((prev) => { - const newPackages = [...prev.virtualenv.packages] - newPackages.splice(index, 1) - - return { - ...prev, - virtualenv: { - ...prev.virtualenv, - packages: newPackages, - }, - } - }) - } else if (type === 'change') { - setFormData((prev) => { - const newPackages = [...prev.virtualenv.packages] - newPackages[index] = value - - return { - ...prev, - virtualenv: { - ...prev.virtualenv, - packages: newPackages, - }, - } - }) - } - } - - const autoFillForm = async () => { - if (!autoFillModelPath || !autoFillModelFamily) { - setErrorMsg( - t( - !autoFillModelPath - ? 'registerModel.fillInModelPathFirst' - : 'registerModel.fillInModelFamilyFirst' - ) - ) - return - } - try { - const res = await fetchWrapper.post('/v1/models/llm/auto-register', { - model_path: autoFillModelPath, - model_family: autoFillModelFamily, - }) - setFormData((prev) => ({ ...prev, ...res })) - setContrastObj(res) - setSpecsArr(res.model_specs) - - setOpenAutoFillDialog(false) - } catch (error) { - console.error('Error:', error) - if (error?.response?.status !== 403 && error?.response?.status !== 401) { - setErrorMsg(error.message) - } - } - } - - return ( - <Box style={{ display: 'flex', overFlow: 'hidden', maxWidth: '100%' }}> - <div className="show-json"> - <p>{t('registerModel.showCustomJsonConfig')}</p> - {isShow ? ( - <Tooltip title={t('registerModel.packUp')} placement="top"> - <KeyboardDoubleArrowRight - className="icon arrow" - onClick={() => setIsShow(!isShow)} - /> - </Tooltip> - ) : ( - <Tooltip title={t('registerModel.unfold')} placement="top"> - <Notes className="icon notes" onClick={() => setIsShow(!isShow)} /> - </Tooltip> - )} - </div> - <div ref={scrollRef} className={isShow ? 'formBox' : 'formBox broaden'}> - {modelType === 'LLM' && ( - <> - <Button - variant="contained" - color="primary" - startIcon={<AutoFixHigh />} - onClick={() => setOpenAutoFillDialog(true)} - > - {t('registerModel.autoFill')} - </Button> - <Box padding="15px"></Box> - </> - )} - - {/* Base Information */} - <FormControl style={{ width: '100%' }}> - {/* name */} - {customData.model_name && ( - <> - <TextField - label={t('registerModel.modelName')} - error={formData.model_name ? false : true} - value={formData.model_name} - size="small" - helperText={t( - 'registerModel.alphanumericWithHyphensUnderscores' - )} - onChange={(event) => - setFormData({ ...formData, model_name: event.target.value }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* description */} - {customData.model_description && ( - <> - <TextField - label={t('registerModel.modelDescription')} - value={formData.model_description} - size="small" - onChange={(event) => - setFormData({ - ...formData, - model_description: event.target.value, - }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* Context Length */} - {customData.context_length && ( - <> - <TextField - error={Number(formData.context_length) > 0 ? false : true} - label={t('registerModel.contextLength')} - value={formData.context_length} - size="small" - onChange={(event) => { - handleNumber(event.target.value, 'context_length') - }} - /> - {isContextLengthAlert && ( - <Alert severity="error"> - {t('registerModel.enterIntegerGreaterThanZero')} - </Alert> - )} - <Box padding="15px"></Box> - </> - )} - - {/* dimensions */} - {customData.dimensions && ( - <> - <TextField - label={t('registerModel.dimensions')} - error={Number(formData.dimensions) > 0 ? false : true} - value={formData.dimensions} - size="small" - onChange={(event) => { - handleNumber(event.target.value, 'dimensions') - }} - /> - {isDimensionsAlert && ( - <Alert severity="error"> - {t('registerModel.enterIntegerGreaterThanZero')} - </Alert> - )} - <Box padding="15px"></Box> - </> - )} - - {/* Max Tokens */} - {customData.max_tokens && ( - <> - <TextField - label={t('registerModel.maxTokens')} - error={Number(formData.max_tokens) > 0 ? false : true} - value={formData.max_tokens} - size="small" - onChange={(event) => { - handleNumber(event.target.value, 'max_tokens') - }} - /> - {isMaxTokensAlert && ( - <Alert severity="error"> - {t('registerModel.enterIntegerGreaterThanZero')} - </Alert> - )} - <Box padding="15px"></Box> - </> - )} - - {/* path */} - {customData.model_uri && ( - <> - <TextField - label={t('registerModel.modelPath')} - error={formData.model_uri ? false : true} - value={formData.model_uri} - size="small" - helperText={t('registerModel.provideModelDirectoryPath')} - onChange={(event) => - setFormData({ ...formData, model_uri: event.target.value }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* model_lang */} - {(customData.model_lang || customData.language) && ( - <> - <label - style={{ - paddingLeft: 5, - color: - modelType === 'LLM' - ? formData.model_lang.length === 0 - ? '#d32f2f' - : 'inherit' - : formData.language.length === 0 - ? '#d32f2f' - : 'inherit', - }} - > - {t('registerModel.modelLanguages')} - </label> - <Box className="checkboxWrapper"> - {SUPPORTED_LANGUAGES.map((lang) => ( - <Box key={lang} sx={{ marginRight: '10px' }}> - <FormControlLabel - control={ - <Checkbox - checked={ - modelType === 'LLM' - ? formData.model_lang.includes(lang) - : formData.language.includes(lang) - } - onChange={() => toggleLanguage(lang)} - name={lang} - /> - } - label={SUPPORTED_LANGUAGES_DICT[lang]} - style={{ - paddingLeft: 10, - }} - /> - </Box> - ))} - <FormControl sx={{ m: 1, minWidth: 120 }} size="small"> - <InputLabel>{t('registerModel.languages')}</InputLabel> - <Select - value={''} - label={t('registerModel.languages')} - onChange={(e) => handleSelectLanguages(e.target.value)} - MenuProps={{ - PaperProps: { - style: { maxHeight: '20vh' }, - }, - }} - > - {languages - .filter((item) => !languagesArr.includes(item.code)) - .map((item) => ( - <MenuItem key={item.code} value={item.code}> - {item.code} - </MenuItem> - ))} - </Select> - </FormControl> - </Box> - <Stack direction="row" spacing={1} style={{ marginLeft: '10px' }}> - {languagesArr.map((item) => ( - <Chip - key={item} - label={item} - variant="outlined" - size="small" - color="primary" - onDelete={() => handleDeleteLanguages(item)} - /> - ))} - </Stack> - <Box padding="15px"></Box> - </> - )} - - {/* multilingual */} - {'multilingual' in customData && ( - <> - <label - style={{ - paddingLeft: 5, - }} - > - {t('registerModel.multilingual')} - </label> - <FormControlLabel - style={{ marginLeft: 0, width: 50 }} - control={<Switch checked={formData.multilingual} />} - onChange={(e) => - setFormData({ ...formData, multilingual: e.target.checked }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* abilities */} - {customData.model_ability && ( - <> - <label - style={{ - paddingLeft: 5, - color: - formData.model_ability.length == 0 ? '#d32f2f' : 'inherit', - }} - > - {t('registerModel.modelAbilities')} - </label> - <Box className="checkboxWrapper"> - {modelType === 'LLM' ? ( - <> - {model_ability_options - .find((item) => item.type === modelType) - .options.map((ability) => ( - <Box key={ability} sx={{ marginRight: '10px' }}> - <FormControlLabel - control={ - <Checkbox - checked={formData.model_ability.includes( - ability.toLowerCase() - )} - onChange={() => - toggleAbility(ability.toLowerCase()) - } - name={ability} - /> - } - label={ability} - style={{ - paddingLeft: 10, - }} - /> - </Box> - ))} - </> - ) : modelType === 'image' ? ( - <Box className="checkboxWrapper"> - {model_ability_options - .find((item) => item.type === modelType) - .options.map((ability) => { - return ( - <Box key={ability} sx={{ marginRight: '10px' }}> - <FormControlLabel - control={ - <Checkbox - checked={formData.model_ability.includes( - ability - )} - onChange={() => toggleImageAbility(ability)} - name={ability} - /> - } - label={ability} - style={{ - paddingLeft: 10, - }} - /> - </Box> - ) - })} - </Box> - ) : ( - <RadioGroup - value={formData.model_ability} - style={{ display: 'flex' }} - onChange={(e) => { - setFormData({ - ...formData, - model_ability: [e.target.value], - }) - }} - > - <Box - className="checkboxWrapper" - sx={{ paddingLeft: '10px' }} - > - {model_ability_options - .find((item) => item.type === modelType) - .options.map((subItem) => ( - <FormControlLabel - key={subItem} - value={subItem} - control={<Radio />} - label={subItem} - /> - ))} - </Box> - </RadioGroup> - )} - </Box> - <Box padding="15px"></Box> - </> - )} - - {/* family */} - {(customData.model_family === '' || customData.model_family) && ( - <> - {modelType === 'LLM' && ( - <> - <Autocomplete - id="free-solo-demo" - freeSolo={isEditableFamily} - options={familyOptions || []} - size="small" - renderInput={(params) => ( - <TextField - {...params} - helperText={ - isEditableFamily - ? t('registerModel.chooseBuiltInOrCustomModel') - : t('registerModel.chooseOnlyBuiltInModel') - } - InputProps={{ - ...params.InputProps, - disabled: !isEditableFamily, - }} - label={t('registerModel.modelFamily')} - /> - )} - value={formData.model_family} - onChange={(_, newValue) => { - handleFamily(newValue?.id) - }} - onInputChange={(_, newInputValue) => { - if (isEditableFamily) { - handleFamily(newInputValue) - } - }} - /> - <Box padding="15px"></Box> - </> - )} - {(modelType === 'image' || modelType === 'audio') && ( - <> - <FormControl> - <label - style={{ - paddingLeft: 5, - color: 'inherit', - }} - > - {t('registerModel.modelFamily')} - </label> - <RadioGroup - value={formData.model_family} - style={{ display: 'flex' }} - onChange={(e) => { - setFormData({ - ...formData, - model_family: e.target.value, - }) - }} - > - <Box - className="checkboxWrapper" - sx={{ paddingLeft: '10px' }} - > - {model_family_options - .find((item) => item.type === modelType) - .options.map((subItem) => ( - <FormControlLabel - key={subItem} - value={subItem} - control={<Radio />} - label={subItem} - /> - ))} - </Box> - </RadioGroup> - </FormControl> - <Box padding="15px"></Box> - </> - )} - </> - )} - - {/* chat_template */} - {formData.model_ability?.includes('chat') && ( - <> - <div className="chat_template_box"> - <TextField - label={t('registerModel.chatTemplate')} - error={handleChatTemplateAlert()} - value={formData.chat_template || ''} - size="small" - helperText={t('registerModel.ensureChatTemplatePassesTest')} - multiline - rows={6} - onChange={(event) => - setFormData({ - ...formData, - chat_template: event.target.value, - }) - } - style={{ flex: 1 }} - /> - <Button - variant="contained" - onClick={handleTest} - style={{ marginTop: 50 }} - > - {t('registerModel.test')} - </Button> - <div className="chat_template_test"> - <div className="chat_template_test_mainBox"> - <div - style={{ display: 'flex', alignItems: 'center', gap: 5 }} - > - <span style={{ fontSize: 16 }}> - {t('registerModel.messagesExample')} - </span> - <OpenInFull - onClick={() => setIsOpenMessages(true)} - style={{ - fontSize: 14, - color: '#666', - cursor: 'pointer', - }} - /> - </div> - <div> - <span - style={{ - display: 'flex', - alignItems: 'center', - gap: 10, - fontSize: 16, - }} - > - {t('registerModel.testResult')} - {testErrorInfo ? ( - <Cancel style={{ color: 'red' }} /> - ) : testRes ? ( - <CheckCircle style={{ color: 'rgb(46, 125, 50)' }} /> - ) : ( - '' - )} - </span> - <div - className="test_res_box" - style={{ - borderColor: - testErrorInfo === '' - ? testRes - ? 'rgb(46, 125, 50)' - : '#ddd' - : 'rgb(46, 125, 50)', - }} - > - {testErrorInfo !== '' - ? testErrorInfo - : testRes - ? testRes - : t('registerModel.noTestResults')} - </div> - </div> - </div> - <div - className="chat_template_test_tip" - style={{ color: testErrorInfo === '' ? '' : '#d32f2f' }} - > - {t('registerModel.testFailurePreventsChatWorking')} - </div> - </div> - </div> - <Box padding="15px"></Box> - </> - )} - - {/* stop_token_ids */} - {formData.model_ability?.includes('chat') && ( - <> - <AddStop - label={t('registerModel.stopTokenIds')} - arrItemType="number" - formData={formData.stop_token_ids} - onGetData={getStopTokenIds} - onGetError={(value) => { - if (value.includes('false')) { - setIsStopTokenIdsAlert(true) - } else { - setIsStopTokenIdsAlert(false) - } - }} - helperText={t('registerModel.stopControlForChatModels')} - /> - <Box padding="15px"></Box> - </> - )} - - {/* stop */} - {formData.model_ability?.includes('chat') && ( - <> - <AddStop - label={t('registerModel.stop')} - arrItemType="string" - formData={formData.stop} - onGetData={getStop} - helperText={t('registerModel.stopControlStringForChatModels')} - /> - <Box padding="15px"></Box> - </> - )} - - {/* reasoning_start_tag */} - {formData.model_ability?.includes('reasoning') && ( - <> - <TextField - label={t('registerModel.reasoningStartTag')} - value={formData.reasoning_start_tag} - size="small" - onChange={(event) => - setFormData({ - ...formData, - reasoning_start_tag: event.target.value, - }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* reasoning_end_tag */} - {formData.model_ability?.includes('reasoning') && ( - <> - <TextField - label={t('registerModel.reasoningEndTag')} - value={formData.reasoning_end_tag} - size="small" - onChange={(event) => - setFormData({ - ...formData, - reasoning_end_tag: event.target.value, - }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* tool_parser */} - {formData.model_ability?.includes('tools') && ( - <> - <TextField - label={t('registerModel.toolParser')} - value={formData.tool_parser} - size="small" - onChange={(event) => - setFormData({ - ...formData, - tool_parser: event.target.value, - }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* specs */} - {customData.model_specs && ( - <> - <AddModelSpecs - isJump={ - (model_name ? true : false) || - (specsArr && specsArr.length > 0) - } - formData={ - (formData?.model_specs && formData.model_specs[0]) || - customData.model_specs[0] - } - specsDataArr={specsArr} - onGetArr={getSpecsArr} - scrollRef={scrollRef} - modelType={modelType} - /> - <Box padding="15px"></Box> - </> - )} - - {/* controlnet */} - {customData.controlnet && ( - <> - <AddControlnet - controlnetDataArr={controlnetArr} - onGetControlnetArr={getControlnetArr} - scrollRef={scrollRef} - /> - <Box padding="15px"></Box> - </> - )} - - {/* launcher */} - {customData.launcher && ( - <> - <TextField - label={t('registerModel.launcher')} - error={formData.launcher ? false : true} - value={formData.launcher} - size="small" - helperText={t('registerModel.provideModelLauncher')} - onChange={(event) => - setFormData({ ...formData, launcher: event.target.value }) - } - /> - <Box padding="15px"></Box> - </> - )} - - {/* launcher_args */} - {customData.launcher_args && ( - <> - <TextField - label={t('registerModel.launcherArguments')} - value={formData.launcher_args} - size="small" - helperText={t('registerModel.jsonArgumentsForLauncher')} - onChange={(event) => { - try { - JSON.parse(event.target.value) - setIsValidLauncherArgsAlert(false) - } catch { - setIsValidLauncherArgsAlert(true) - } - return setFormData({ - ...formData, - launcher_args: event.target.value, - }) - }} - multiline - rows={4} - /> - {isValidLauncherArgsAlert && ( - <Alert severity="error"> - {t('registerModel.enterJsonFormattedDictionary')} - </Alert> - )} - <Box padding="15px"></Box> - </> - )} - - {/* virtualenv */} - {customData.virtualenv && ( - <> - <AddVirtualenv - virtualenv={formData.virtualenv} - onChangeVirtualenv={changeVirtualenv} - scrollRef={scrollRef} - /> - <Box padding="15px"></Box> - </> - )} - </FormControl> - - {model_name ? ( - <> - <Button - variant="contained" - color="primary" - type="submit" - onClick={handleEdit} - disabled={isEqual} - > - {t('registerModel.edit')} - </Button> - <Button - style={{ marginLeft: 30 }} - variant="outlined" - color="primary" - type="submit" - onClick={handleCancel} - > - {t('registerModel.cancel')} - </Button> - </> - ) : ( - <Box width={'100%'}> - <Button - variant="contained" - color="primary" - type="submit" - onClick={handleClick} - disabled={ - isContextLengthAlert || - isDimensionsAlert || - isMaxTokensAlert || - formData.model_lang?.length === 0 || - formData.language?.length === 0 || - formData.model_ability?.length === 0 || - (modelType === 'LLM' && !formData.model_family) || - isStopTokenIdsAlert || - handleFamilyAlert() - } - > - {t('registerModel.registerModel')} - </Button> - </Box> - )} - </div> - - <Dialog - open={isOpenMessages} - onClose={() => setIsOpenMessages(false)} - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - > - <DialogTitle id="alert-dialog-title"> - {t('registerModel.messagesExample')} - </DialogTitle> - <DialogContent style={{ width: 600 }}> - <TextField - multiline - fullWidth - rows={10} - disabled - defaultValue={JSON.stringify(messages, null, 4)} - /> - </DialogContent> - <DialogActions> - <Button - variant="contained" - onClick={() => setIsOpenMessages(false)} - style={{ marginRight: 15, marginBottom: 15 }} - > - OK - </Button> - </DialogActions> - </Dialog> - - <Dialog - open={openAutoFillDialog} - onClose={() => setOpenAutoFillDialog(false)} - aria-labelledby="alert-dialog-title" - aria-describedby="alert-dialog-description" - > - <DialogTitle id="alert-dialog-title"> - {t('registerModel.autoFill')} - </DialogTitle> - <DialogContent style={{ width: 600, padding: 20 }}> - <TextField - label={t('registerModel.modelPath')} - value={autoFillModelPath} - size="small" - fullWidth - onChange={(e) => setAutoFillModelPath(e.target.value)} - /> - <Box padding="15px"></Box> - - <FormControl fullWidth size="small"> - <InputLabel>{t('registerModel.modelFamily')}</InputLabel> - <Select - value={autoFillModelFamily} - label={t('registerModel.modelFamily')} - onChange={(e) => setAutoFillModelFamily(e.target.value)} - MenuProps={{ - PaperProps: { - style: { - maxHeight: 300, - }, - }, - }} - > - {(allFamilies || []).map((subItem) => ( - <MenuItem key={subItem} value={subItem}> - {subItem} - </MenuItem> - ))} - </Select> - </FormControl> - </DialogContent> - <DialogActions> - <Button - variant="contained" - onClick={autoFillForm} - style={{ marginRight: 15, marginBottom: 15 }} - > - {t('registerModel.autoFill')} - </Button> - </DialogActions> - </Dialog> - - {/* JSON */} - <div className={isShow ? 'jsonBox' : 'jsonBox hide'}> - <div className="jsonBox-header"> - <div className="jsonBox-title">{t('registerModel.JSONFormat')}</div> - <CopyComponent tip={t('registerModel.copyAll')} text={jsonData} /> - </div> - <textarea readOnly className="textarea" value={jsonData} /> - </div> - </Box> - ) -} - -export default RegisterModelComponent diff --git a/xinference/ui/web/ui/src/scenes/register_model/styles/registerModelStyle.css b/xinference/ui/web/ui/src/scenes/register_model/styles/registerModelStyle.css deleted file mode 100644 index 235521018e..0000000000 --- a/xinference/ui/web/ui/src/scenes/register_model/styles/registerModelStyle.css +++ /dev/null @@ -1,157 +0,0 @@ -.formBox { - position: relative; - max-width: 50vw; - min-width: 50vw; - max-height: 80vh; - overflow: auto; - padding: 40px 20px 0 0; - transition: all 0.4s ease-in-out; -} - -.broaden { - max-width: 100%; - min-width: 100%; - padding-right: 0; -} - -.show-json { - display: flex; - align-items: center; - position: absolute; - top: 90px; - right: 60px; -} - -.icon { - position: absolute; - right: -40px; - cursor: pointer; - margin-left: 20px; -} - -.icon:hover { - color: #1976d2; -} - -.arrow { - font-size: 24px !important; -} - -.jsonBox { - position: relative; - min-height: 80vh; - width: 100%; - transition: all 0.4s ease-in-out; -} - -.hide { - width: 0; - transform: translate(30vw, 0); - overflow: hidden; -} - -.checkboxWrapper { - display: flex; - flex-wrap: wrap; - align-items: center; - width: 100%; -} - -.jsonBox-header { - display: flex; - justify-content: space-between; - align-items: center; -} - -.jsonBox-title { - line-height: 40px; - font-weight: 700; -} - -.textarea { - width: 100%; - height: calc(100% - 40px); - padding: 5px 10px; - border: 1px solid #ddd; - border-radius: 5px; - resize: none; - color: #666; - background-color: transparent; -} - -.addBtn { - margin-left: 20px !important; -} - -.item { - position: relative; - border: 1px solid #ddd; - margin: 10px 50px 0; - padding: 20px; - border-radius: 10px; - overflow: hidden; -} - -.item:hover .deleteBtn { - transform: translateX(-50px); -} - -.deleteBtn { - position: absolute; - right: 20px; - top: calc(50% - 25px); - width: 50px; - height: 50px; - transform: translateX(80px); - text-align: center; - line-height: 70px; - border-radius: 25px; - background-color: #1976d2; - transition: all 0.3s ease-in-out; -} - -.deleteBtn:hover { - cursor: pointer; - box-shadow: 0 0 10px #aaa; -} - -.deleteIcon { - font-size: 28px !important; - color: #fff; -} - -.chat_template_box { - display: flex; - align-items: start; - gap: 10px; -} - -.chat_template_test { - width: 30%; -} - -.chat_template_test_mainBox { - height: 137px; - padding: 10px; - border: 1px solid #ccc; - border-radius: 4px; - overflow: scroll; -} - -.chat_template_test_tip { - font-size: 10px; - margin: 4px 14px 0; - color: rgba(0, 0, 0, 0.6); -} - -.test_res_box { - border: 1px solid #ddd; - min-height: 55px; - padding: 10px; - margin-top: 5px; - border-radius: 4px; -} - -.css-19qh8xo-MuiInputBase-input-MuiOutlinedInput-input.Mui-disabled { - -webkit-text-fill-color: #000 !important; -} diff --git a/xinference/ui/web/ui/src/scenes/running_models/index.js b/xinference/ui/web/ui/src/scenes/running_models/index.js deleted file mode 100644 index 37ecd33b6d..0000000000 --- a/xinference/ui/web/ui/src/scenes/running_models/index.js +++ /dev/null @@ -1,1392 +0,0 @@ -import ContentCopyOutlinedIcon from '@mui/icons-material/ContentCopyOutlined' -import DeleteOutlineOutlinedIcon from '@mui/icons-material/DeleteOutlineOutlined' -import OpenInBrowserOutlinedIcon from '@mui/icons-material/OpenInBrowserOutlined' -import PowerSettingsNewOutlinedIcon from '@mui/icons-material/PowerSettingsNewOutlined' -import { TabContext, TabList, TabPanel } from '@mui/lab' -import { - Badge, - Box, - Button, - Chip, - CircularProgress, - Dialog, - DialogActions, - DialogContent, - DialogContentText, - DialogTitle, - IconButton, - Paper, - Stack, - Tab, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - Tooltip, - Typography, -} from '@mui/material' -import { DataGrid } from '@mui/x-data-grid' -import React, { useContext, useEffect, useState } from 'react' -import { useCookies } from 'react-cookie' -import { useTranslation } from 'react-i18next' -import { useLocation, useNavigate } from 'react-router-dom' - -import { ApiContext } from '../../components/apiContext' -import ErrorMessageSnackBar from '../../components/errorMessageSnackBar' -import fetcher from '../../components/fetcher' -import fetchWrapper from '../../components/fetchWrapper' -import Title from '../../components/Title' -import { isValidBearerToken } from '../../components/utils' - -const tabArr = [ - { - label: 'model.languageModels', - value: '/running_models/LLM', - showPrompt: false, - }, - { - label: 'model.embeddingModels', - value: '/running_models/embedding', - showPrompt: false, - }, - { - label: 'model.rerankModels', - value: '/running_models/rerank', - showPrompt: false, - }, - { - label: 'model.imageModels', - value: '/running_models/image', - showPrompt: false, - }, - { - label: 'model.audioModels', - value: '/running_models/audio', - showPrompt: false, - }, - { - label: 'model.videoModels', - value: '/running_models/video', - showPrompt: false, - }, - { - label: 'model.flexibleModels', - value: '/running_models/flexible', - showPrompt: false, - }, -] - -const getAutostartModelUids = (summary = {}) => { - return (summary.models || []) - .filter((item) => item.enabled !== false) - .map( - (item) => - item.model_uid || item.launch?.model_uid || item.launch?.model_name - ) - .filter(Boolean) -} - -const RunningModels = () => { - const [tabValue, setTabValue] = React.useState( - sessionStorage.getItem('runningModelType') - ) - const [tabList, setTabList] = useState(tabArr) - const [llmData, setLlmData] = useState([]) - const [embeddingModelData, setEmbeddingModelData] = useState([]) - const [imageModelData, setImageModelData] = useState([]) - const [audioModelData, setAudioModelData] = useState([]) - const [videoModelData, setVideoModelData] = useState([]) - const [rerankModelData, setRerankModelData] = useState([]) - const [flexibleModelData, setFlexibleModelData] = useState([]) - const [replicaDialogOpen, setReplicaDialogOpen] = useState(false) - const [selectedModelReplicas, setSelectedModelReplicas] = useState([]) - const [selectedModelUid, setSelectedModelUid] = useState('') - const [removingReplicaId, setRemovingReplicaId] = useState(null) - const [terminatingModelUids, setTerminatingModelUids] = useState([]) - const [autostartModelUids, setAutostartModelUids] = useState([]) - const [autostartBusyUids, setAutostartBusyUids] = useState([]) - const [terminateDialog, setTerminateDialog] = useState({ - open: false, - row: null, - }) - const { isCallingApi, setIsCallingApi } = useContext(ApiContext) - const { isUpdatingModel, setIsUpdatingModel } = useContext(ApiContext) - const { setErrorMsg, setSuccessMsg } = useContext(ApiContext) - const [cookie] = useCookies(['token']) - const navigate = useNavigate() - const endPoint = useContext(ApiContext).endPoint - const { t } = useTranslation() - const location = useLocation() - - const handleTabChange = (event, newValue) => { - setTabValue(newValue) - navigate(newValue) - sessionStorage.setItem('runningModelType', newValue) - } - - const update = (isCallingApi) => { - if ( - sessionStorage.getItem('auth') === 'true' && - !isValidBearerToken(sessionStorage.getItem('token')) && - !isValidBearerToken(cookie.token) - ) { - navigate('/login', { replace: true }) - return - } - if (isCallingApi) { - setLlmData([{ id: 'Loading, do not refresh page...', url: 'IS_LOADING' }]) - setEmbeddingModelData([ - { id: 'Loading, do not refresh page...', url: 'IS_LOADING' }, - ]) - setAudioModelData([ - { id: 'Loading, do not refresh page...', url: 'IS_LOADING' }, - ]) - setVideoModelData([ - { id: 'Loading, do not refresh page...', url: 'IS_LOADING' }, - ]) - setImageModelData([ - { id: 'Loading, do not refresh page...', url: 'IS_LOADING' }, - ]) - setRerankModelData([ - { id: 'Loading, do not refresh page...', url: 'IS_LOADING' }, - ]) - setFlexibleModelData([ - { id: 'Loading, do not refresh page...', url: 'IS_LOADING' }, - ]) - } else { - setIsUpdatingModel(true) - - Promise.all([ - fetchWrapper.get('/v1/models'), - fetchWrapper.get('/v1/autostart/models/summary').catch((error) => { - console.error('Error fetching autostart models:', error) - return { models: [] } - }), - ]) - .then(([response, autostartSummary]) => { - const modelMap = { - LLM: [], - embedding: [], - image: [], - audio: [], - video: [], - rerank: [], - flexible: [], - } - - response.data.forEach((model) => { - const newValue = { - ...model, - id: model.id, - url: model.id, - } - if (modelMap[newValue.model_type]) { - modelMap[newValue.model_type].push(newValue) - } - }) - - setAutostartModelUids(getAutostartModelUids(autostartSummary)) - setLlmData(modelMap.LLM) - setEmbeddingModelData(modelMap.embedding) - setImageModelData(modelMap.image) - setAudioModelData(modelMap.audio) - setVideoModelData(modelMap.video) - setRerankModelData(modelMap.rerank) - setFlexibleModelData(modelMap.flexible) - - if (location.pathname.endsWith('/LLM')) { - const modelOrder = [ - 'LLM', - 'embedding', - 'image', - 'audio', - 'video', - 'rerank', - 'flexible', - ] - for (const type of modelOrder) { - if (modelMap[type] && modelMap[type].length > 0) { - navigate(`/running_models/${type}`) - setTabValue(`/running_models/${type}`) - break - } - } - } - - setIsUpdatingModel(false) - }) - .catch((error) => { - console.error('Error:', error) - setIsUpdatingModel(false) - if (error.response.status !== 403 && error.response.status !== 401) { - setErrorMsg(error.message) - } - }) - } - } - - const pollUntilModelRemoved = async (modelUid) => { - const delays = [2000, 4000, 8000] - const maxAttempts = 48 - for (let attempt = 0; attempt < maxAttempts; attempt++) { - try { - const response = await fetchWrapper.get('/v1/models') - const exists = response.data.some((m) => m.id === modelUid) - if (!exists) return - } catch (e) { - console.error(e) - break - } - const ms = delays[Math.min(attempt, delays.length - 1)] - await new Promise((resolve) => setTimeout(resolve, ms)) - } - } - - const handleTerminateClick = (row) => { - if (isUpdatingModel || row.url === 'IS_LOADING') return - if (terminatingModelUids.includes(row.id)) return - setTerminateDialog({ open: true, row }) - } - - const handleCloseTerminateDialog = () => { - setTerminateDialog({ open: false, row: null }) - } - - const handleConfirmTerminate = async () => { - const row = terminateDialog.row - if (!row) return - handleCloseTerminateDialog() - const modelUid = row.id - const closeUrl = `${endPoint}/v1/models/${modelUid}` - setTerminatingModelUids((prev) => - prev.includes(modelUid) ? prev : [...prev, modelUid] - ) - try { - const res = await fetcher(closeUrl, { method: 'DELETE' }) - if (!res.ok) { - const errText = await res.text().catch(() => '') - throw new Error(errText || res.statusText || String(res.status)) - } - await res.json().catch(() => ({})) - await pollUntilModelRemoved(modelUid) - } catch (e) { - console.error(e) - setErrorMsg(t('runningModels.terminateErrorHint')) - } finally { - setTerminatingModelUids((prev) => prev.filter((id) => id !== modelUid)) - update(false) - } - } - - const handleRemoveAutostart = async (modelUid) => { - if (autostartBusyUids.includes(modelUid)) return - setAutostartBusyUids((prev) => - prev.includes(modelUid) ? prev : [...prev, modelUid] - ) - - try { - const summary = await fetchWrapper.delete( - `/v1/autostart/models/${encodeURIComponent(modelUid)}` - ) - setAutostartModelUids(getAutostartModelUids(summary)) - setSuccessMsg(t('runningModels.removeAutostartSuccess', { modelUid })) - } catch (error) { - console.error('Error removing autostart model:', error) - setErrorMsg(t('runningModels.removeAutostartFailed')) - } finally { - setAutostartBusyUids((prev) => prev.filter((id) => id !== modelUid)) - } - } - - const renderAutostartButton = (row) => { - if (!autostartModelUids.includes(row.id)) { - return null - } - - const busy = autostartBusyUids.includes(row.id) - return ( - <IconButton - title={t('runningModels.autostartEnabled')} - disabled={busy || isUpdatingModel || row.url === 'IS_LOADING'} - style={{ - borderWidth: '0px', - backgroundColor: 'transparent', - paddingLeft: '0px', - paddingRight: '10px', - }} - onClick={(event) => { - event.stopPropagation() - handleRemoveAutostart(row.id) - }} - > - <Box - width="40px" - m="0 auto" - p="5px" - display="flex" - justifyContent="center" - alignItems="center" - borderRadius="4px" - style={{ - border: '1px solid #e5e7eb', - borderWidth: '1px', - borderColor: '#e5e7eb', - color: '#2563eb', - minHeight: 32, - }} - > - {busy ? ( - <CircularProgress size={18} thickness={5} /> - ) : ( - <PowerSettingsNewOutlinedIcon /> - )} - </Box> - </IconButton> - ) - } - - const renderTerminateButton = (row) => { - const busy = terminatingModelUids.includes(row.id) - return ( - <IconButton - title={ - busy - ? t('runningModels.terminateInProgress') - : t('runningModels.terminateModel') - } - disabled={busy || isUpdatingModel || row.url === 'IS_LOADING'} - style={{ - borderWidth: '0px', - backgroundColor: 'transparent', - paddingLeft: '0px', - paddingRight: '10px', - }} - onClick={() => handleTerminateClick(row)} - > - <Box - width="40px" - m="0 auto" - p="5px" - display="flex" - justifyContent="center" - alignItems="center" - borderRadius="4px" - style={{ - border: '1px solid #e5e7eb', - borderWidth: '1px', - borderColor: '#e5e7eb', - minHeight: 32, - }} - > - {busy ? ( - <CircularProgress size={18} thickness={5} /> - ) : ( - <DeleteOutlineOutlinedIcon /> - )} - </Box> - </IconButton> - ) - } - - const loadReplicaDetails = async (modelUid) => { - const replicas = await fetchWrapper.get(`/v1/models/${modelUid}/replicas`) - setSelectedModelReplicas(replicas) - return replicas - } - - const handleViewReplicas = async (modelUid) => { - try { - await loadReplicaDetails(modelUid) - setSelectedModelUid(modelUid) - setReplicaDialogOpen(true) - } catch (error) { - console.error('Error fetching replica details:', error) - setErrorMsg('Failed to load replica details: ' + error.message) - } - } - - const handleRemoveReplica = async (replica) => { - const confirmed = window.confirm( - t('modelReplicaDetails.removeConfirm', { - replicaId: replica.replica_id, - modelUid: selectedModelUid, - }) - ) - if (!confirmed) { - return - } - - try { - setRemovingReplicaId(replica.replica_id) - const response = await fetchWrapper.delete( - `/v1/models/${selectedModelUid}/replicas/${replica.replica_id}` - ) - - if (response.remaining_replicas > 0) { - await loadReplicaDetails(selectedModelUid) - } else { - setSelectedModelReplicas([]) - setReplicaDialogOpen(false) - } - - update(false) - } catch (error) { - console.error('Error removing replica:', error) - setErrorMsg('Failed to remove replica: ' + error.message) - } finally { - setRemovingReplicaId(null) - } - } - - useEffect(() => { - update(isCallingApi) - // eslint-disable-next-line - }, [isCallingApi, cookie.token]) - - const replicaColumn = { - field: 'replica', - headerName: t('runningModels.replica'), - flex: 1, - renderCell: ({ row }) => { - return ( - <Box - sx={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - width: '100%', - paddingRight: 2, - }} - > - <span>{row.replica}</span> - <Button - size="small" - variant="text" - onClick={(e) => { - e.stopPropagation() - handleViewReplicas(row.id) - }} - sx={{ minWidth: 'auto', padding: '4px 8px' }} - > - {t('runningModels.viewDetails')} - </Button> - </Box> - ) - }, - } - - const llmColumns = [ - { - field: 'id', - headerName: 'ID', - flex: 1, - minWidth: 250, - renderCell: ({ row }) => { - return renderWithCopy(row.id) - }, - }, - { - field: 'model_name', - headerName: t('runningModels.name'), - flex: 1, - renderCell: ({ row }) => { - return renderWithCopy(row.model_name) - }, - }, - { - field: 'address', - headerName: t('runningModels.address'), - flex: 1, - }, - { - field: 'accelerators', - headerName: t('runningModels.gpuIndexes'), - flex: 1, - }, - { - field: 'model_size_in_billions', - headerName: t('runningModels.size'), - flex: 1, - }, - { - field: 'quantization', - headerName: t('runningModels.quantization'), - flex: 1, - }, - replicaColumn, - { - field: 'url', - headerName: t('runningModels.actions'), - flex: 1, - minWidth: 200, - sortable: false, - filterable: false, - disableColumnMenu: true, - renderCell: ({ row }) => { - const url = row.url - const openUrl = `${endPoint}/` + url - const gradioUrl = `${endPoint}/v1/ui/` + url - - if (url === 'IS_LOADING') { - return <div></div> - } - - return ( - <Box - style={{ - width: '100%', - display: 'flex', - justifyContent: 'left', - alignItems: 'left', - }} - > - <IconButton - title="Launch Web UI" - style={{ - borderWidth: '0px', - backgroundColor: 'transparent', - paddingLeft: '0px', - paddingRight: '10px', - }} - onClick={() => { - if (isCallingApi || isUpdatingModel) { - // Make sure no ongoing call - return - } - - setIsCallingApi(true) - - fetcher(openUrl, { - method: 'HEAD', - }) - .then((response) => { - if (response.status === 404) { - // If web UI doesn't exist (404 Not Found) - console.log('UI does not exist, creating new...') - return fetcher(gradioUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model_type: row.model_type, - model_name: row.model_family, - model_size_in_billions: row.model_size_in_billions, - model_format: row.model_format, - quantization: row.quantization, - context_length: row.context_length, - model_ability: row.model_ability, - model_description: row.model_description, - model_lang: row.model_lang, - }), - }) - .then((response) => response.json()) - .then(() => - window.open(openUrl, '_blank', 'noopener noreferrer') - ) - .finally(() => setIsCallingApi(false)) - } else if (response.ok) { - // If web UI does exist - console.log('UI exists, opening...') - window.open(openUrl, '_blank', 'noopener noreferrer') - setIsCallingApi(false) - } else { - // Other HTTP errors - console.error( - `Unexpected response status: ${response.status}` - ) - setIsCallingApi(false) - } - }) - .catch((error) => { - console.error('Error:', error) - setIsCallingApi(false) - }) - }} - > - <Box - width="40px" - m="0 auto" - p="5px" - display="flex" - justifyContent="center" - borderRadius="4px" - style={{ - border: '1px solid #e5e7eb', - borderWidth: '1px', - borderColor: '#e5e7eb', - }} - > - <OpenInBrowserOutlinedIcon /> - </Box> - </IconButton> - {renderAutostartButton(row)} - {renderTerminateButton(row)} - </Box> - ) - }, - }, - ] - const embeddingModelColumns = [ - { - field: 'id', - headerName: 'ID', - flex: 1, - minWidth: 250, - renderCell: ({ row }) => { - return renderWithCopy(row.id) - }, - }, - { - field: 'model_name', - headerName: t('runningModels.name'), - flex: 1, - renderCell: ({ row }) => { - return renderWithCopy(row.model_name) - }, - }, - { - field: 'address', - headerName: t('runningModels.address'), - flex: 1, - }, - { - field: 'accelerators', - headerName: t('runningModels.gpuIndexes'), - flex: 1, - }, - replicaColumn, - { - field: 'url', - headerName: t('runningModels.actions'), - flex: 1, - minWidth: 200, - sortable: false, - filterable: false, - disableColumnMenu: true, - renderCell: ({ row }) => { - const url = row.url - const openUrl = `${endPoint}/` + url - - if (url === 'IS_LOADING') { - return <div></div> - } - - // ``embeddingModelColumns`` is reused for rerank / flexible tabs - // (see ``rerankModelColumns`` / ``flexibleModelColumns`` aliases - // below), so the Gradio launcher must only render for embedding - // rows. Posting a rerank / flexible ``model_uid`` to - // ``/v1/ui/embeddings/{model_uid}`` would otherwise 400 on the - // backend ``model_type`` check. - if (row.model_type !== 'embedding') { - return ( - <Box - style={{ - width: '100%', - display: 'flex', - justifyContent: 'left', - alignItems: 'left', - }} - > - {renderAutostartButton(row)} - {renderTerminateButton(row)} - </Box> - ) - } - - const gradioUrl = `${endPoint}/v1/ui/embeddings/` + url - - return ( - <Box - style={{ - width: '100%', - display: 'flex', - justifyContent: 'left', - alignItems: 'left', - }} - > - <IconButton - title="Launch Web UI" - style={{ - borderWidth: '0px', - backgroundColor: 'transparent', - paddingLeft: '0px', - paddingRight: '10px', - }} - onClick={() => { - if (isCallingApi || isUpdatingModel) { - return - } - - setIsCallingApi(true) - - fetcher(openUrl, { - method: 'HEAD', - }) - .then((response) => { - if (response.status === 404) { - console.log('UI does not exist, creating new...') - return fetcher(gradioUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model_type: row.model_type, - model_family: row.model_family, - model_id: row.id, - model_revision: row.model_revision, - model_name: row.model_name, - model_ability: row.model_ability, - }), - }) - .then((response) => response.json()) - .then(() => - window.open(openUrl, '_blank', 'noopener noreferrer') - ) - .finally(() => setIsCallingApi(false)) - } else if (response.ok) { - console.log('UI exists, opening...') - window.open(openUrl, '_blank', 'noopener noreferrer') - setIsCallingApi(false) - } else { - console.error( - `Unexpected response status: ${response.status}` - ) - setIsCallingApi(false) - } - }) - .catch((error) => { - console.error('Error:', error) - setIsCallingApi(false) - }) - }} - > - <Box - width="40px" - m="0 auto" - p="5px" - display="flex" - justifyContent="center" - borderRadius="4px" - style={{ - border: '1px solid #e5e7eb', - borderWidth: '1px', - borderColor: '#e5e7eb', - }} - > - <OpenInBrowserOutlinedIcon /> - </Box> - </IconButton> - {renderAutostartButton(row)} - {renderTerminateButton(row)} - </Box> - ) - }, - }, - ] - const imageModelColumns = [ - { - field: 'id', - headerName: 'ID', - flex: 1, - minWidth: 250, - renderCell: ({ row }) => { - return renderWithCopy(row.id) - }, - }, - { - field: 'model_name', - headerName: t('runningModels.name'), - flex: 1, - renderCell: ({ row }) => { - return renderWithCopy(row.model_name) - }, - }, - { - field: 'address', - headerName: t('runningModels.address'), - flex: 1, - }, - { - field: 'accelerators', - headerName: t('runningModels.gpuIndexes'), - flex: 1, - }, - replicaColumn, - { - field: 'url', - headerName: t('runningModels.actions'), - flex: 1, - minWidth: 200, - sortable: false, - filterable: false, - disableColumnMenu: true, - renderCell: ({ row }) => { - // this URL means model_uid - const url = row.url - const openUrl = `${endPoint}/` + url - let pathType - if (row.model_type === 'video') { - pathType = 'videos' - } else if (row.model_type === 'audio') { - pathType = 'audios' - } else { - pathType = 'images' // default - } - const gradioUrl = `${endPoint}/v1/ui/${pathType}/` + url - - if (url === 'IS_LOADING') { - return <div></div> - } - - return ( - <Box - style={{ - width: '100%', - display: 'flex', - justifyContent: 'left', - alignItems: 'left', - }} - > - <IconButton - title="Launch Web UI" - style={{ - borderWidth: '0px', - backgroundColor: 'transparent', - paddingLeft: '0px', - paddingRight: '10px', - }} - onClick={() => { - if (isCallingApi || isUpdatingModel) { - // Make sure no ongoing call - return - } - - setIsCallingApi(true) - - fetcher(openUrl, { - method: 'HEAD', - }) - .then((response) => { - if (response.status === 404) { - // If web UI doesn't exist (404 Not Found) - console.log('UI does not exist, creating new...') - return fetcher(gradioUrl, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - model_type: row.model_type, - model_family: row.model_family, - model_id: row.id, - controlnet: row.controlnet, - model_revision: row.model_revision, - model_name: row.model_name, - model_ability: row.model_ability, - }), - }) - .then((response) => response.json()) - .then(() => - window.open(openUrl, '_blank', 'noopener noreferrer') - ) - .finally(() => setIsCallingApi(false)) - } else if (response.ok) { - // If web UI does exist - console.log('UI exists, opening...') - window.open(openUrl, '_blank', 'noopener noreferrer') - setIsCallingApi(false) - } else { - // Other HTTP errors - console.error( - `Unexpected response status: ${response.status}` - ) - setIsCallingApi(false) - } - }) - .catch((error) => { - console.error('Error:', error) - setIsCallingApi(false) - }) - }} - > - <Box - width="40px" - m="0 auto" - p="5px" - display="flex" - justifyContent="center" - borderRadius="4px" - style={{ - border: '1px solid #e5e7eb', - borderWidth: '1px', - borderColor: '#e5e7eb', - }} - > - <OpenInBrowserOutlinedIcon /> - </Box> - </IconButton> - {renderAutostartButton(row)} - {renderTerminateButton(row)} - </Box> - ) - }, - }, - ] - const audioModelColumns = imageModelColumns - const videoModelColumns = imageModelColumns - const rerankModelColumns = embeddingModelColumns - const flexibleModelColumns = embeddingModelColumns - - const dataGridStyle = { - '& .MuiDataGrid-cell': { - borderBottom: 'none', - }, - '& .MuiDataGrid-columnHeaders': { - borderBottom: 'none', - }, - '& .MuiDataGrid-columnHeaderTitle': { - fontWeight: 'bold', - }, - '& .MuiDataGrid-virtualScroller': { - overflowX: 'visible !important', - overflow: 'visible', - }, - '& .MuiDataGrid-footerContainer': { - borderTop: 'none', - }, - 'border-width': '0px', - } - - const noRowsOverlay = () => { - return ( - <Stack height="100%" alignItems="center" justifyContent="center"> - {t('runningModels.noRunningModels')} - </Stack> - ) - } - - const noResultsOverlay = () => { - return ( - <Stack height="100%" alignItems="center" justifyContent="center"> - {t('runningModels.noRunningModelsMatches')} - </Stack> - ) - } - - const renderWithCopy = (display) => { - const [tooltipOpen, setTooltipOpen] = useState(false) - const [tooltipText, setTooltipText] = useState(t('runningModels.copy')) - - const handleCopy = (event) => { - event.stopPropagation() - - if (navigator.clipboard && window.isSecureContext) { - // for HTTPS - navigator.clipboard - .writeText(display) - .then(() => { - setTooltipText(t('runningModels.copied')) - }) - .catch(() => { - setTooltipText(t('runningModels.copyFailed')) - }) - .finally(() => { - setTooltipOpen(true) - setTimeout(() => { - setTooltipOpen(false) - setTooltipText(t('runningModels.copy')) - }, 1500) - }) - } else { - // for HTTP - const textArea = document.createElement('textarea') - textArea.value = display - textArea.style.position = 'absolute' - textArea.style.left = '-9999px' - document.body.appendChild(textArea) - textArea.select() - - try { - const success = document.execCommand('copy') - if (success) { - setTooltipText(t('runningModels.copied')) - } else { - setTooltipText(t('runningModels.copyFailed')) - } - } catch (err) { - setTooltipText(t('runningModels.copyFailed')) - } - - document.body.removeChild(textArea) - - setTooltipOpen(true) - setTimeout(() => { - setTooltipOpen(false) - setTooltipText(t('runningModels.copy')) - }, 1500) - } - } - - return ( - <div - style={{ - display: 'flex', - alignItems: 'center', - maxWidth: '100%', - overflow: 'hidden', - }} - > - <span - style={{ - flex: 1, - minWidth: 0, - overflow: 'hidden', - whiteSpace: 'nowrap', - textOverflow: 'ellipsis', - marginRight: 8, - }} - > - {display} - </span> - <Tooltip title={tooltipText} open={tooltipOpen}> - <IconButton size="small" onClick={handleCopy}> - <ContentCopyOutlinedIcon fontSize="small" /> - </IconButton> - </Tooltip> - </div> - ) - } - - useEffect(() => { - const dataMap = { - 'model.languageModels': llmData, - 'model.embeddingModels': embeddingModelData, - 'model.rerankModels': rerankModelData, - 'model.imageModels': imageModelData, - 'model.audioModels': audioModelData, - 'model.videoModels': videoModelData, - 'model.flexibleModels': flexibleModelData, - } - - setTabList( - tabList.map((item) => { - if (dataMap[item.label]?.length && dataMap[item.label][0].model_type) { - return { - ...item, - showPrompt: true, - } - } - return { - ...item, - showPrompt: false, - } - }) - ) - }, [ - llmData, - embeddingModelData, - rerankModelData, - imageModelData, - audioModelData, - videoModelData, - flexibleModelData, - ]) - - return ( - <Box - sx={{ - height: '100%', - width: '100%', - padding: '20px 20px 0 20px', - }} - > - <Title title={t('menu.runningModels')} /> - <ErrorMessageSnackBar /> - <TabContext value={tabValue}> - <Box sx={{ borderBottom: 1, borderColor: 'divider' }}> - <TabList - value={tabValue} - onChange={handleTabChange} - aria-label="tabs" - > - {tabList.map((item) => ( - <Tab - key={item.value} - label={ - <Badge - color="secondary" - variant="dot" - invisible={!item.showPrompt} - > - {t(item.label)} - </Badge> - } - value={item.value} - /> - ))} - </TabList> - </Box> - <TabPanel value="/running_models/LLM" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={llmData} - columns={llmColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - <TabPanel value="/running_models/embedding" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={embeddingModelData} - columns={embeddingModelColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - <TabPanel value="/running_models/rerank" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={rerankModelData} - columns={rerankModelColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - <TabPanel value="/running_models/image" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={imageModelData} - columns={imageModelColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - <TabPanel value="/running_models/audio" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={audioModelData} - columns={audioModelColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - <TabPanel value="/running_models/video" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={videoModelData} - columns={videoModelColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - <TabPanel value="/running_models/flexible" sx={{ padding: 0 }}> - <Box sx={{ height: '100%', width: '100%' }}> - <DataGrid - rows={flexibleModelData} - columns={flexibleModelColumns} - autoHeight={true} - sx={dataGridStyle} - slots={{ - noRowsOverlay: noRowsOverlay, - noResultsOverlay: noResultsOverlay, - }} - /> - </Box> - </TabPanel> - </TabContext> - - {/* Replica Details Dialog */} - <Dialog - open={replicaDialogOpen} - onClose={() => setReplicaDialogOpen(false)} - maxWidth="md" - fullWidth - > - <DialogTitle> - {t('modelReplicaDetails.title')} - <Typography variant="caption" display="block" color="text.secondary"> - {t('modelReplicaDetails.modelUid')}: {selectedModelUid} - </Typography> - </DialogTitle> - <DialogContent> - <TableContainer component={Paper} variant="outlined"> - <Table size="small"> - <TableHead> - <TableRow> - <TableCell>{t('modelReplicaDetails.replicaId')}</TableCell> - <TableCell>{t('modelReplicaDetails.modelUid')}</TableCell> - <TableCell> - {t('modelReplicaDetails.workerAddress')} - </TableCell> - <TableCell>{t('modelReplicaDetails.status')}</TableCell> - <TableCell>{t('modelReplicaDetails.createdTime')}</TableCell> - <TableCell align="right"> - {t('modelReplicaDetails.actions')} - </TableCell> - </TableRow> - </TableHead> - <TableBody> - {selectedModelReplicas.map((replica) => ( - <TableRow key={replica.replica_id}> - <TableCell>{replica.replica_id}</TableCell> - <TableCell> - <Typography - variant="caption" - sx={{ fontFamily: 'monospace', fontSize: '0.75rem' }} - > - {replica.replica_model_uid} - </Typography> - </TableCell> - <TableCell>{replica.worker_address}</TableCell> - <TableCell> - <Chip - label={replica.status} - color={ - replica.status === 'READY' - ? 'success' - : replica.status === 'ERROR' - ? 'error' - : 'default' - } - size="small" - /> - </TableCell> - <TableCell> - {new Date(replica.created_ts * 1000).toLocaleString()} - </TableCell> - <TableCell align="right"> - <Tooltip title={t('modelReplicaDetails.remove')}> - <span> - <IconButton - size="small" - color="error" - onClick={() => handleRemoveReplica(replica)} - disabled={removingReplicaId === replica.replica_id} - > - <DeleteOutlineOutlinedIcon fontSize="small" /> - </IconButton> - </span> - </Tooltip> - </TableCell> - </TableRow> - ))} - {selectedModelReplicas.length === 0 && ( - <TableRow> - <TableCell colSpan={6} align="center"> - <Typography variant="body2" color="text.secondary"> - {t('modelReplicaDetails.noReplicaInfo')} - </Typography> - </TableCell> - </TableRow> - )} - </TableBody> - </Table> - </TableContainer> - {selectedModelReplicas.some((r) => r.error_message) && ( - <Box sx={{ mt: 2 }}> - <Typography variant="subtitle2" color="error"> - {t('modelReplicaDetails.errors')}: - </Typography> - {selectedModelReplicas - .filter((r) => r.error_message) - .map((replica, idx) => ( - <Typography - key={idx} - variant="caption" - display="block" - color="error" - > - {t('modelReplicaDetails.replica')} {replica.replica_id}:{' '} - {replica.error_message} - </Typography> - ))} - </Box> - )} - </DialogContent> - <DialogActions> - <Button onClick={() => setReplicaDialogOpen(false)}> - {t('modelReplicaDetails.close')} - </Button> - </DialogActions> - </Dialog> - - <Dialog - open={terminateDialog.open} - onClose={handleCloseTerminateDialog} - aria-labelledby="terminate-dialog-title" - > - <DialogTitle id="terminate-dialog-title"> - {t('runningModels.terminateConfirmTitle')} - </DialogTitle> - <DialogContent> - <DialogContentText component="div"> - <Typography variant="body2" paragraph> - {t('runningModels.terminateConfirmBody', { - replica: terminateDialog.row?.replica ?? 1, - })} - </Typography> - {terminateDialog.row?.model_name && ( - <Typography - variant="caption" - color="text.secondary" - display="block" - > - {t('runningModels.name')}: {terminateDialog.row.model_name} - </Typography> - )} - </DialogContentText> - </DialogContent> - <DialogActions> - <Button onClick={handleCloseTerminateDialog}> - {t('components.cancel')} - </Button> - <Button - onClick={handleConfirmTerminate} - color="error" - variant="contained" - autoFocus - > - {t('runningModels.terminateConfirmOk')} - </Button> - </DialogActions> - </Dialog> - </Box> - ) -} - -export default RunningModels diff --git a/xinference/ui/web/ui/src/scenes/security_settings/index.js b/xinference/ui/web/ui/src/scenes/security_settings/index.js deleted file mode 100644 index 90e9b650e5..0000000000 --- a/xinference/ui/web/ui/src/scenes/security_settings/index.js +++ /dev/null @@ -1,399 +0,0 @@ -import DeleteIcon from '@mui/icons-material/Delete' -import { - Box, - Button, - Card, - CardContent, - Divider, - Grid, - IconButton, - Paper, - Table, - TableBody, - TableCell, - TableContainer, - TableHead, - TableRow, - TextField, - Typography, -} from '@mui/material' -import React, { useContext, useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import { ApiContext } from '../../components/apiContext' -import ErrorMessageSnackBar from '../../components/errorMessageSnackBar' -import Title from '../../components/Title' -import { getEndpoint } from '../../components/utils' - -function SecuritySettings() { - const { t } = useTranslation() - const endpoint = getEndpoint() - const { setErrorMsg } = useContext(ApiContext) - const [config, setConfig] = useState({ ip: {}, key: {} }) - const [bannedIps, setBannedIps] = useState([]) - const [bannedKeys, setBannedKeys] = useState([]) - - const token = sessionStorage.getItem('token') - const headers = { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${token}`, - } - - const fetchConfig = () => { - fetch(endpoint + '/v1/admin/security/rate-limit', { headers }) - .then((res) => { - if (res.ok) res.json().then(setConfig) - else setErrorMsg('Failed to fetch rate limit config') - }) - .catch(() => setErrorMsg('Network error fetching config')) - } - - const fetchBannedIps = () => { - fetch(endpoint + '/v1/admin/security/banned-ips', { headers }) - .then((res) => { - if (res.ok) res.json().then(setBannedIps) - else setErrorMsg('Failed to fetch banned IPs') - }) - .catch(() => setErrorMsg('Network error fetching banned IPs')) - } - - const fetchBannedKeys = () => { - fetch(endpoint + '/v1/admin/security/banned-keys', { headers }) - .then((res) => { - if (res.ok) res.json().then(setBannedKeys) - else setErrorMsg('Failed to fetch banned keys') - }) - .catch(() => setErrorMsg('Network error fetching banned keys')) - } - - const sanitizeConfig = (value) => - Object.fromEntries( - Object.entries(value).filter(([, v]) => v !== '' && v !== null) - ) - - useEffect(() => { - fetchConfig() - fetchBannedIps() - fetchBannedKeys() - }, []) - - const handleSaveConfig = () => { - fetch(endpoint + '/v1/admin/security/rate-limit', { - method: 'PUT', - headers, - body: JSON.stringify({ - ip: sanitizeConfig(config.ip), - key: sanitizeConfig(config.key), - }), - }) - .then((res) => { - if (res.ok) setErrorMsg('') - else setErrorMsg('Failed to update config') - }) - .catch(() => setErrorMsg('Network error saving config')) - } - - const handleUnbanIp = (ip) => { - fetch(endpoint + '/v1/admin/security/unban-ip', { - method: 'POST', - headers, - body: JSON.stringify({ ip }), - }) - .then(() => fetchBannedIps()) - .catch(() => setErrorMsg('Network error unbanning IP')) - } - - const handleUnbanKey = (ip, key_id) => { - fetch(endpoint + '/v1/admin/security/unban-key', { - method: 'POST', - headers, - body: JSON.stringify({ ip, key_id }), - }) - .then(() => fetchBannedKeys()) - .catch(() => setErrorMsg('Network error unbanning key')) - } - - const handleUnbanAllIps = () => { - fetch(endpoint + '/v1/admin/security/unban-all-ips', { - method: 'POST', - headers, - }) - .then(() => fetchBannedIps()) - .catch(() => setErrorMsg('Network error unbanning all IPs')) - } - - const handleUnbanAllKeys = () => { - fetch(endpoint + '/v1/admin/security/unban-all-keys', { - method: 'POST', - headers, - }) - .then(() => fetchBannedKeys()) - .catch(() => setErrorMsg('Network error unbanning all keys')) - } - - return ( - <Box m="20px"> - <ErrorMessageSnackBar /> - <Title title={t('securitySettings.title')} /> - - {/* Rate Limit Config */} - <Card sx={{ mb: 3 }}> - <CardContent> - <Typography variant="h6" mb={2}> - {t('securitySettings.rateLimitConfig')} - </Typography> - <Grid container spacing={2}> - <Grid item xs={12}> - <Typography variant="subtitle1"> - {t('securitySettings.ipLayer')} - </Typography> - </Grid> - <Grid item xs={4}> - <TextField - label={t('securitySettings.maxFailures')} - type="number" - size="small" - fullWidth - value={config.ip.max_failures || ''} - onChange={(e) => - setConfig({ - ...config, - ip: { - ...config.ip, - max_failures: - e.target.value === '' ? '' : parseInt(e.target.value), - }, - }) - } - /> - </Grid> - <Grid item xs={4}> - <TextField - label={t('securitySettings.windowSeconds')} - type="number" - size="small" - fullWidth - value={config.ip.window_seconds || ''} - onChange={(e) => - setConfig({ - ...config, - ip: { - ...config.ip, - window_seconds: - e.target.value === '' ? '' : parseInt(e.target.value), - }, - }) - } - /> - </Grid> - <Grid item xs={4}> - <TextField - label={t('securitySettings.banSeconds')} - type="number" - size="small" - fullWidth - value={config.ip.ban_seconds || ''} - onChange={(e) => - setConfig({ - ...config, - ip: { - ...config.ip, - ban_seconds: - e.target.value === '' ? '' : parseInt(e.target.value), - }, - }) - } - /> - </Grid> - <Grid item xs={12}> - <Divider sx={{ my: 1 }} /> - <Typography variant="subtitle1"> - {t('securitySettings.keyLayer')} - </Typography> - </Grid> - <Grid item xs={4}> - <TextField - label={t('securitySettings.maxFailures')} - type="number" - size="small" - fullWidth - value={config.key.max_failures || ''} - onChange={(e) => - setConfig({ - ...config, - key: { - ...config.key, - max_failures: - e.target.value === '' ? '' : parseInt(e.target.value), - }, - }) - } - /> - </Grid> - <Grid item xs={4}> - <TextField - label={t('securitySettings.windowSeconds')} - type="number" - size="small" - fullWidth - value={config.key.window_seconds || ''} - onChange={(e) => - setConfig({ - ...config, - key: { - ...config.key, - window_seconds: - e.target.value === '' ? '' : parseInt(e.target.value), - }, - }) - } - /> - </Grid> - <Grid item xs={4}> - <TextField - label={t('securitySettings.banSeconds')} - type="number" - size="small" - fullWidth - value={config.key.ban_seconds || ''} - onChange={(e) => - setConfig({ - ...config, - key: { - ...config.key, - ban_seconds: - e.target.value === '' ? '' : parseInt(e.target.value), - }, - }) - } - /> - </Grid> - <Grid item xs={12}> - <Button variant="contained" onClick={handleSaveConfig}> - {t('securitySettings.saveConfig')} - </Button> - </Grid> - </Grid> - </CardContent> - </Card> - - {/* Banned IPs */} - <Card sx={{ mb: 3 }}> - <CardContent> - <Box - display="flex" - justifyContent="space-between" - alignItems="center" - mb={1} - > - <Typography variant="h6"> - {t('securitySettings.bannedIps')} - </Typography> - {bannedIps.length > 0 && ( - <Button size="small" color="error" onClick={handleUnbanAllIps}> - {t('securitySettings.unbanAll')} - </Button> - )} - </Box> - <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}> - {t('securitySettings.bannedIpsDesc')} - </Typography> - {bannedIps.length === 0 ? ( - <Typography color="text.secondary"> - {t('securitySettings.noBannedIps')} - </Typography> - ) : ( - <TableContainer component={Paper} variant="outlined"> - <Table size="small"> - <TableHead> - <TableRow> - <TableCell>{t('securitySettings.ip')}</TableCell> - <TableCell>{t('securitySettings.remaining')}</TableCell> - <TableCell>{t('securitySettings.action')}</TableCell> - </TableRow> - </TableHead> - <TableBody> - {bannedIps.map((row) => ( - <TableRow key={row.ip}> - <TableCell>{row.ip}</TableCell> - <TableCell>{row.remaining_seconds}</TableCell> - <TableCell> - <IconButton - size="small" - onClick={() => handleUnbanIp(row.ip)} - > - <DeleteIcon fontSize="small" /> - </IconButton> - </TableCell> - </TableRow> - ))} - </TableBody> - </Table> - </TableContainer> - )} - </CardContent> - </Card> - - {/* Banned (IP, Key) Pairs */} - <Card> - <CardContent> - <Box - display="flex" - justifyContent="space-between" - alignItems="center" - mb={1} - > - <Typography variant="h6"> - {t('securitySettings.bannedKeys')} - </Typography> - {bannedKeys.length > 0 && ( - <Button size="small" color="error" onClick={handleUnbanAllKeys}> - {t('securitySettings.unbanAll')} - </Button> - )} - </Box> - <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}> - {t('securitySettings.bannedKeysDesc')} - </Typography> - {bannedKeys.length === 0 ? ( - <Typography color="text.secondary"> - {t('securitySettings.noBannedKeys')} - </Typography> - ) : ( - <TableContainer component={Paper} variant="outlined"> - <Table size="small"> - <TableHead> - <TableRow> - <TableCell>{t('securitySettings.ip')}</TableCell> - <TableCell>{t('securitySettings.keyId')}</TableCell> - <TableCell>{t('securitySettings.remaining')}</TableCell> - <TableCell>{t('securitySettings.action')}</TableCell> - </TableRow> - </TableHead> - <TableBody> - {bannedKeys.map((row, idx) => ( - <TableRow key={idx}> - <TableCell>{row.ip}</TableCell> - <TableCell>{row.key_id}</TableCell> - <TableCell>{row.remaining_seconds}</TableCell> - <TableCell> - <IconButton - size="small" - onClick={() => handleUnbanKey(row.ip, row.key_id)} - > - <DeleteIcon fontSize="small" /> - </IconButton> - </TableCell> - </TableRow> - ))} - </TableBody> - </Table> - </TableContainer> - )} - </CardContent> - </Card> - </Box> - ) -} - -export default SecuritySettings diff --git a/xinference/ui/web/ui/src/scenes/user_management/index.js b/xinference/ui/web/ui/src/scenes/user_management/index.js deleted file mode 100644 index 0b34526c3f..0000000000 --- a/xinference/ui/web/ui/src/scenes/user_management/index.js +++ /dev/null @@ -1,546 +0,0 @@ -import BlockIcon from '@mui/icons-material/Block' -import CheckCircleIcon from '@mui/icons-material/CheckCircle' -import DeleteIcon from '@mui/icons-material/Delete' -import EditIcon from '@mui/icons-material/Edit' -import VpnKeyIcon from '@mui/icons-material/VpnKey' -import { - Alert, - Box, - Checkbox, - Chip, - Divider, - FormControlLabel, - FormGroup, - IconButton, - Snackbar, - Tooltip, - Typography, -} from '@mui/material' -import Button from '@mui/material/Button' -import Dialog from '@mui/material/Dialog' -import DialogActions from '@mui/material/DialogActions' -import DialogContent from '@mui/material/DialogContent' -import DialogTitle from '@mui/material/DialogTitle' -import TextField from '@mui/material/TextField' -import { DataGrid } from '@mui/x-data-grid' -import * as React from 'react' -import { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' - -import fetchWrapper from '../../components/fetchWrapper' -import Title from '../../components/Title' - -const ALL_PERMISSIONS = [ - { group: 'admin', items: ['admin'] }, - { - group: 'models', - items: ['models:list', 'models:read', 'models:write', 'models:register'], - }, - { group: 'keys', items: ['keys:create', 'keys:manage'] }, - { group: 'users', items: ['users:manage'] }, - { group: 'cache', items: ['cache:list', 'cache:delete'] }, - { group: 'virtualenv', items: ['virtualenv:list', 'virtualenv:delete'] }, - { group: 'logs', items: ['logs:list'] }, - { group: 'monitor', items: ['monitor:view'] }, -] - -const ALL_PERMISSION_VALUES = ALL_PERMISSIONS.flatMap((g) => g.items) - -function UserManagement() { - const { t } = useTranslation() - const [users, setUsers] = useState([]) - const [createOpen, setCreateOpen] = useState(false) - const [newUsername, setNewUsername] = useState('') - const [newPassword, setNewPassword] = useState('') - const [selectedPerms, setSelectedPerms] = useState([]) - const [snackError, setSnackError] = useState('') - const [snackSeverity, setSnackSeverity] = useState('error') - const [editPermOpen, setEditPermOpen] = useState(false) - const [editingUser, setEditingUser] = useState(null) - const [editPerms, setEditPerms] = useState([]) - const [pwdDialogOpen, setPwdDialogOpen] = useState(false) - const [pwdTargetUser, setPwdTargetUser] = useState(null) - const [newPwd, setNewPwd] = useState('') - const [confirmPwd, setConfirmPwd] = useState('') - const [pwdError, setPwdError] = useState('') - - const loadUsers = async () => { - try { - const data = await fetchWrapper.get('/v1/admin/users') - setUsers(data) - } catch (e) { - console.error(e) - } - } - - useEffect(() => { - loadUsers() - }, []) - - const handleCreate = async () => { - try { - await fetchWrapper.post('/v1/admin/users', { - username: newUsername, - password: newPassword, - permissions: selectedPerms, - }) - setCreateOpen(false) - setNewUsername('') - setNewPassword('') - setSelectedPerms([]) - loadUsers() - } catch (e) { - setSnackSeverity('error') - setSnackError(e.message || String(e)) - } - } - - const handleToggleEnabled = async (user) => { - try { - await fetchWrapper.put(`/v1/admin/users/${user.id}`, { - enabled: !user.enabled, - }) - loadUsers() - } catch (e) { - setSnackSeverity('error') - setSnackError(e.message || String(e)) - } - } - - const handleDelete = async (user) => { - if ( - !window.confirm( - `${t('userManagement.confirmDelete')} "${user.username}"?` - ) - ) - return - try { - await fetchWrapper.delete(`/v1/admin/users/${user.id}`) - loadUsers() - } catch (e) { - setSnackSeverity('error') - setSnackError(e.message || String(e)) - } - } - - const handlePermToggle = (perm) => { - setSelectedPerms((prev) => - prev.includes(perm) ? prev.filter((p) => p !== perm) : [...prev, perm] - ) - } - - const handleSelectAll = () => { - if (selectedPerms.length === ALL_PERMISSION_VALUES.length) { - setSelectedPerms([]) - } else { - setSelectedPerms([...ALL_PERMISSION_VALUES]) - } - } - - const handleEditPermissions = (user) => { - setEditingUser(user) - setEditPerms(user.permissions || []) - setEditPermOpen(true) - } - - const handleEditPermToggle = (perm) => { - setEditPerms((prev) => - prev.includes(perm) ? prev.filter((p) => p !== perm) : [...prev, perm] - ) - } - - const handleEditSelectAll = () => { - if (editPerms.length === ALL_PERMISSION_VALUES.length) { - setEditPerms([]) - } else { - setEditPerms([...ALL_PERMISSION_VALUES]) - } - } - - const handleSavePermissions = async () => { - if (!editingUser) return - try { - await fetchWrapper.put(`/v1/admin/users/${editingUser.id}/permissions`, { - permissions: editPerms, - }) - setEditPermOpen(false) - setEditingUser(null) - loadUsers() - } catch (e) { - setSnackSeverity('error') - setSnackError(e.message || String(e)) - } - } - - const handleChangePassword = (user) => { - setPwdTargetUser(user) - setNewPwd('') - setConfirmPwd('') - setPwdError('') - setPwdDialogOpen(true) - } - - const handleSubmitPassword = async () => { - if (!pwdTargetUser) return - if (newPwd !== confirmPwd) { - setPwdError(t('userManagement.passwordMismatch')) - return - } - if (newPwd.length < 8) { - setPwdError(t('userManagement.passwordTooShort')) - return - } - try { - await fetchWrapper.put(`/v1/admin/users/${pwdTargetUser.id}/password`, { - new_password: newPwd, - }) - setPwdDialogOpen(false) - setPwdTargetUser(null) - setNewPwd('') - setConfirmPwd('') - setSnackSeverity('success') - setSnackError(t('userManagement.changePasswordSuccess')) - } catch (e) { - setPwdError(e.message || String(e)) - } - } - - const columns = [ - { field: 'id', headerName: t('userManagement.id'), width: 60 }, - { field: 'username', headerName: t('userManagement.username'), width: 150 }, - { field: 'source', headerName: t('userManagement.source'), width: 100 }, - { - field: 'enabled', - headerName: t('userManagement.status'), - width: 100, - renderCell: (params) => - params.value ? ( - <Chip - label={t('userManagement.active')} - color="success" - size="small" - /> - ) : ( - <Chip - label={t('userManagement.disabled')} - color="error" - size="small" - /> - ), - }, - { - field: 'permissions', - headerName: t('userManagement.permissions'), - width: 300, - renderCell: (params) => ( - <Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}> - {(params.value || []).map((p) => ( - <Chip - key={p} - label={t(`permissions.${p.replace(/:/g, '_')}`, p)} - size="small" - variant="outlined" - /> - ))} - </Box> - ), - }, - { - field: 'actions', - headerName: t('userManagement.actions'), - width: 150, - renderCell: (params) => ( - <Box> - <Tooltip - title={t('userManagement.editPermissions') || 'Edit Permissions'} - > - <IconButton - size="small" - onClick={() => handleEditPermissions(params.row)} - > - <EditIcon /> - </IconButton> - </Tooltip> - {params.row.source === 'local' && ( - <Tooltip title={t('userManagement.changePassword')}> - <IconButton - size="small" - onClick={() => handleChangePassword(params.row)} - > - <VpnKeyIcon /> - </IconButton> - </Tooltip> - )} - <Tooltip - title={ - params.row.enabled - ? t('apikeyManagement.disableTooltip') - : t('apikeyManagement.enableTooltip') - } - > - <IconButton - size="small" - onClick={() => handleToggleEnabled(params.row)} - > - {params.row.enabled ? <BlockIcon /> : <CheckCircleIcon />} - </IconButton> - </Tooltip> - <Tooltip title={t('apikeyManagement.deleteTooltip')}> - <IconButton size="small" onClick={() => handleDelete(params.row)}> - <DeleteIcon /> - </IconButton> - </Tooltip> - </Box> - ), - }, - ] - - return ( - <Box sx={{ p: 3 }}> - <Title title={t('userManagement.title')} /> - <Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: 2 }}> - <Button variant="contained" onClick={() => setCreateOpen(true)}> - {t('userManagement.createUser')} - </Button> - </Box> - <DataGrid - rows={users} - columns={columns} - autoHeight - pageSizeOptions={[10, 25, 50]} - initialState={{ pagination: { paginationModel: { pageSize: 10 } } }} - getRowHeight={() => 'auto'} - /> - - <Dialog - open={createOpen} - onClose={() => setCreateOpen(false)} - maxWidth="sm" - fullWidth - > - <DialogTitle>{t('userManagement.dialogTitle')}</DialogTitle> - <DialogContent> - <TextField - margin="dense" - label={t('userManagement.usernameLabel')} - fullWidth - value={newUsername} - onChange={(e) => setNewUsername(e.target.value)} - /> - <TextField - margin="dense" - label={t('userManagement.passwordLabel')} - type="password" - fullWidth - value={newPassword} - onChange={(e) => setNewPassword(e.target.value)} - /> - <Box sx={{ mt: 2 }}> - <Box - sx={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - }} - > - <Typography variant="subtitle2"> - {t('userManagement.permissions')} - </Typography> - <FormControlLabel - control={ - <Checkbox - size="small" - checked={ - selectedPerms.length === ALL_PERMISSION_VALUES.length - } - indeterminate={ - selectedPerms.length > 0 && - selectedPerms.length < ALL_PERMISSION_VALUES.length - } - onChange={handleSelectAll} - /> - } - label={t('userManagement.selectAll')} - /> - </Box> - <Divider sx={{ mb: 1 }} /> - {ALL_PERMISSIONS.map((group) => ( - <Box key={group.group} sx={{ mb: 1 }}> - <Typography - variant="caption" - color="text.secondary" - sx={{ fontWeight: 'bold' }} - > - {group.group} - </Typography> - <FormGroup row> - {group.items.map((perm) => ( - <FormControlLabel - key={perm} - control={ - <Checkbox - size="small" - checked={selectedPerms.includes(perm)} - onChange={() => handlePermToggle(perm)} - /> - } - label={t(`permissions.${perm.replace(/:/g, '_')}`, perm)} - sx={{ mr: 2 }} - /> - ))} - </FormGroup> - </Box> - ))} - </Box> - </DialogContent> - <DialogActions> - <Button onClick={() => setCreateOpen(false)}> - {t('userManagement.cancel')} - </Button> - <Button variant="contained" onClick={handleCreate}> - {t('userManagement.create')} - </Button> - </DialogActions> - </Dialog> - - {/* Edit Permissions Dialog */} - <Dialog - open={editPermOpen} - onClose={() => setEditPermOpen(false)} - maxWidth="sm" - fullWidth - > - <DialogTitle> - {t('userManagement.editPermissionsTitle') || 'Edit Permissions'}{' '} - {editingUser && `- ${editingUser.username}`} - </DialogTitle> - <DialogContent> - <Box sx={{ mt: 1 }}> - <Box - sx={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - }} - > - <Typography variant="subtitle2"> - {t('userManagement.permissions')} - </Typography> - <FormControlLabel - control={ - <Checkbox - size="small" - checked={editPerms.length === ALL_PERMISSION_VALUES.length} - indeterminate={ - editPerms.length > 0 && - editPerms.length < ALL_PERMISSION_VALUES.length - } - onChange={handleEditSelectAll} - /> - } - label={t('userManagement.selectAll')} - /> - </Box> - <Divider sx={{ mb: 1 }} /> - {ALL_PERMISSIONS.map((group) => ( - <Box key={group.group} sx={{ mb: 1 }}> - <Typography - variant="caption" - color="text.secondary" - sx={{ fontWeight: 'bold' }} - > - {group.group} - </Typography> - <FormGroup row> - {group.items.map((perm) => ( - <FormControlLabel - key={perm} - control={ - <Checkbox - size="small" - checked={editPerms.includes(perm)} - onChange={() => handleEditPermToggle(perm)} - /> - } - label={t(`permissions.${perm.replace(/:/g, '_')}`, perm)} - sx={{ mr: 2 }} - /> - ))} - </FormGroup> - </Box> - ))} - </Box> - </DialogContent> - <DialogActions> - <Button onClick={() => setEditPermOpen(false)}> - {t('userManagement.cancel')} - </Button> - <Button variant="contained" onClick={handleSavePermissions}> - {t('userManagement.save') || 'Save'} - </Button> - </DialogActions> - </Dialog> - - {/* Change Password Dialog */} - <Dialog - open={pwdDialogOpen} - onClose={() => setPwdDialogOpen(false)} - maxWidth="xs" - fullWidth - > - <DialogTitle> - {t('userManagement.changePasswordTitle')}{' '} - {pwdTargetUser && `- ${pwdTargetUser.username}`} - </DialogTitle> - <DialogContent> - {pwdError && ( - <Alert severity="error" sx={{ mb: 2 }}> - {pwdError} - </Alert> - )} - <TextField - margin="dense" - label={t('userManagement.newPassword')} - type="password" - fullWidth - value={newPwd} - onChange={(e) => setNewPwd(e.target.value)} - /> - <TextField - margin="dense" - label={t('userManagement.confirmPassword')} - type="password" - fullWidth - value={confirmPwd} - onChange={(e) => setConfirmPwd(e.target.value)} - /> - </DialogContent> - <DialogActions> - <Button onClick={() => setPwdDialogOpen(false)}> - {t('userManagement.cancel')} - </Button> - <Button variant="contained" onClick={handleSubmitPassword}> - {t('userManagement.save')} - </Button> - </DialogActions> - </Dialog> - - <Snackbar - open={!!snackError} - autoHideDuration={5000} - onClose={() => setSnackError('')} - anchorOrigin={{ vertical: 'top', horizontal: 'center' }} - > - <Alert - severity={snackSeverity} - onClose={() => setSnackError('')} - variant="filled" - > - {snackError} - </Alert> - </Snackbar> - </Box> - ) -} - -export default UserManagement diff --git a/xinference/ui/web/ui/src/theme.js b/xinference/ui/web/ui/src/theme.js deleted file mode 100644 index 0a76e5bfa5..0000000000 --- a/xinference/ui/web/ui/src/theme.js +++ /dev/null @@ -1,44 +0,0 @@ -import { createTheme } from '@mui/material/styles' - -// mui theme settings -export const themeSettings = (mode) => { - return { - ERROR_COLOR: '#d8342c', - typography: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 12, - h1: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 40, - }, - h2: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 32, - }, - h3: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 24, - }, - h4: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 20, - }, - h5: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 16, - }, - h6: { - fontFamily: ['Source Sans Pro', 'sans-serif'].join(','), - fontSize: 14, - }, - }, - palette: { - mode: mode, - }, - } -} - -export const useMode = (mode = 'light') => { - const theme = createTheme(themeSettings(mode)) - return [theme] -} diff --git a/xinference/ui/web/ui/src/utils/jwt.js b/xinference/ui/web/ui/src/utils/jwt.js deleted file mode 100644 index a89382c9ec..0000000000 --- a/xinference/ui/web/ui/src/utils/jwt.js +++ /dev/null @@ -1,39 +0,0 @@ -// JWT parsing + permission helper shared by MenuSide, PermissionGate, and -// Monitoring. Centralizing the parsing avoids three copies drifting apart -// when the JWT payload shape changes. -// -// Token lives in sessionStorage under the key `token`. The payload is the -// middle base64url segment of a standard JWT; `scopes` is an array of -// strings. - -export function parseTokenFromSession() { - try { - const token = sessionStorage.getItem('token') - if (!token) return null - // JWT payload is base64url-encoded: may contain '-' and '_' and - // lacks padding. atob() throws DOMException on base64url, so - // normalize to standard base64 first. - const base64Url = token.split('.')[1] - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/') - const payload = JSON.parse(atob(base64)) - const scopes = Array.isArray(payload.scopes) ? payload.scopes : [] - return { - username: payload.username || payload.sub || '', - scopes, - } - } catch { - return null - } -} - -// `admin` is a wildcard — admin users implicitly pass any scope check, -// mirroring the backend `if "admin" in token_scopes: return` shortcut in -// both auth_service modules. -export function hasPermission(scopes, scope) { - if (!Array.isArray(scopes)) return false - return scopes.includes(scope) || scopes.includes('admin') -} - -export function isAdmin(scopes) { - return Array.isArray(scopes) && scopes.includes('admin') -}