From 4e2040bf49ff71bc8b08f35f5bdd3d10309360c8 Mon Sep 17 00:00:00 2001 From: Buffik Date: Mon, 26 Dec 2022 23:55:32 +0300 Subject: [PATCH 01/65] feat: create environment setup --- .eslintrc.json | 35 + .prettierrc | 9 + package-lock.json | 16674 ++++++++++++++++ package.json | 65 + public/favicon.ico | Bin 0 -> 3870 bytes public/index.html | 18 + public/logo192.png | Bin 0 -> 5347 bytes public/logo512.png | Bin 0 -> 9664 bytes public/robots.txt | 3 + src/App/App.tsx | 14 + src/App/RootRouter/index.tsx | 22 + .../TestComponentWithHooks/index.tsx | 26 + src/Components/TestForMain/index.tsx | 16 + src/Components/TestForMain/styles.scss | 0 src/Components/TestForOther/index.tsx | 10 + src/Components/header/index.tsx | 42 + src/Components/header/styles.module.scss | 21 + src/Pages/Main/index.tsx | 18 + src/Pages/Main/test/main.test.tsx | 8 + src/Pages/Other/index.tsx | 13 + src/Pages/Other/test/other.test.tsx | 8 + src/globals.d.ts | 1 + src/index.scss | 13 + src/index.tsx | 11 + src/react-app-env.d.ts | 1 + src/setupTests.ts | 5 + tsconfig.json | 27 + 27 files changed, 17060 insertions(+) create mode 100644 .eslintrc.json create mode 100644 .prettierrc create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/favicon.ico create mode 100644 public/index.html create mode 100644 public/logo192.png create mode 100644 public/logo512.png create mode 100644 public/robots.txt create mode 100644 src/App/App.tsx create mode 100644 src/App/RootRouter/index.tsx create mode 100644 src/Components/TestComponentWithHooks/index.tsx create mode 100644 src/Components/TestForMain/index.tsx create mode 100644 src/Components/TestForMain/styles.scss create mode 100644 src/Components/TestForOther/index.tsx create mode 100644 src/Components/header/index.tsx create mode 100644 src/Components/header/styles.module.scss create mode 100644 src/Pages/Main/index.tsx create mode 100644 src/Pages/Main/test/main.test.tsx create mode 100644 src/Pages/Other/index.tsx create mode 100644 src/Pages/Other/test/other.test.tsx create mode 100644 src/globals.d.ts create mode 100644 src/index.scss create mode 100644 src/index.tsx create mode 100644 src/react-app-env.d.ts create mode 100644 src/setupTests.ts create mode 100644 tsconfig.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..e0b3f64 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,35 @@ +{ + "env": { + "browser": true, + "es2021": true, + "jest": true + }, + "extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "airbnb"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2022, + "sourceType": "module" + }, + "plugins": ["react", "@typescript-eslint"], + "rules": { + "import/extensions": [1, "ignorePackages", { + "ts": "never", + "tsx": "never" + }], + "react/react-in-jsx-scope": "off", + "react/jsx-filename-extension": [ + 1, + { "extensions": [".js", ".jsx", "ts", "tsx"] } + ] + }, + "settings": { + "import/resolver": { + "node": { + "extensions": [".js", ".jsx", ".ts", ".tsx"] + } + } + } +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..7abe590 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "singleQuote": true, + "printWidth": 80, + "endOfLine": "auto", + "bracketSpacing": true + } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..3191df3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,16674 @@ +{ + "name": "my-app", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "my-app", + "version": "0.1.0", + "dependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.4", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "prettier": "^2.8.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.4.4", + "react-scripts": "^5.0.1", + "sass": "^1.56.1", + "typescript": "^4.9.3", + "web-vitals": "^2.1.4" + }, + "devDependencies": { + "@svgr/webpack": "^6.5.1", + "@typescript-eslint/eslint-plugin": "^5.45.0", + "@typescript-eslint/parser": "^5.45.0", + "eslint": "^8.29.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.6.1", + "eslint-plugin-react": "^7.31.11", + "eslint-plugin-react-hooks": "^4.6.0" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.1.tgz", + "integrity": "sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==" + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/eslint-parser": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz", + "integrity": "sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==", + "dependencies": { + "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "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/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "dependencies": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", + "dependencies": { + "@babel/helper-explode-assignable-expression": "^7.18.6", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "dependencies": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.5.tgz", + "integrity": "sha512-3RCdA/EmEaikrhayahwToF0fpweU/8o2p8vhc1c/1kftHOdTKuC65kik/TLc+qfbS8JKw4qqJbne4ovICDhmww==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz", + "integrity": "sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "regexpu-core": "^5.2.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.17.7", + "@babel/helper-plugin-utils": "^7.16.7", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2", + "semver": "^6.1.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0-0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-explode-assignable-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "dependencies": { + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-wrap-function": "^7.18.9", + "@babel/types": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/traverse": "^7.19.1", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", + "dependencies": { + "@babel/types": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", + "dependencies": { + "@babel/helper-function-name": "^7.19.0", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "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.18.6", + "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.18.6.tgz", + "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/plugin-proposal-optional-chaining": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-proposal-async-generator-functions": { + "version": "7.20.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.1.tgz", + "integrity": "sha512-Gh5rchzSwE4kC+o/6T8waD0WHEQIsDmjltY8WnWRXHUdH8axZhuH86Ov9M72YhJfDrZseQwuuWaaIT/TmePp3g==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-remap-async-to-generator": "^7.18.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-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-class-static-block": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.5.tgz", + "integrity": "sha512-Lac7PpRJXcC3s9cKsBfl+uc+DYXU5FD06BrTFunQO6QIQT+DwyzDPURAowI3bcvD1dZF/ank1Z5rstUJn3Hn4Q==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/plugin-syntax-decorators": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-dynamic-import": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-export-namespace-from": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@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-proposal-json-strings": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@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-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-object-rest-spread": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.2.tgz", + "integrity": "sha512-Ks6uej9WFK+fvIMesSqbAto5dD8Dz4VuuFvGJFKgIGSkJuRGcrwGECPA1fDgQK3/DbExBJpEkTeYeB8geIFCSQ==", + "dependencies": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-optional-catch-binding": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@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-proposal-optional-chaining": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@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.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz", + "integrity": "sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.20.5", + "@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.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", + "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "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.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", + "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "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.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "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.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-remap-async-to-generator": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.5.tgz", + "integrity": "sha512-WvpEIW9Cbj9ApF3yJCjIEEf1EiNJLtXagOrL5LNWEZOo3jv8pmPoYTSNJQvqej8OavVlgOoOPw6/htGZro6IkA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.2.tgz", + "integrity": "sha512-9rbPp0lCVVoagvtEyQKSo5L8oo0nQS/iif+lwlAz29MccX2642vWDlSZK+2T2buxbopotId2ld7zZAzRfz9j1g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-optimise-call-expression": "^7.18.6", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-split-export-declaration": "^7.18.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.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.2.tgz", + "integrity": "sha512-mENM+ZHrvEgxLTBXUiQ621rRXZes3KWUv6NdQlrnr1TkWVw+hUjQBZuP2X32qKlrlG2BzgR95gkuCRSkJl8vIw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", + "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-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^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-transform-flow-strip-types": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", + "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-flow": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.18.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.19.6.tgz", + "integrity": "sha512-uG3od2mXvAtIFQIh0xrpLH6r5fpSQN04gIVovl+ODLdUMANokxQLZnPBHcjmv3GxRjnqwLuHvppjjcelqUFZvg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.19.6.tgz", + "integrity": "sha512-8PIa1ym4XRTKuSsOUXqDG0YaOlEuTVvHMe5JCfgBMOtHvJKw/4NGovEGN33viISshG/rZNVrACiBmPQLvWN8xQ==", + "dependencies": { + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-simple-access": "^7.19.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.6.tgz", + "integrity": "sha512-fqGLBepcc3kErfR9R3DnVpURmckXP7gj7bAlrTQyBxrigFqszZCkFkcoxzCp2v32XmwXLvbw+8Yq9/b+QqksjQ==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-module-transforms": "^7.19.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-validator-identifier": "^7.19.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", + "dependencies": { + "@babel/helper-module-transforms": "^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-transform-named-capturing-groups-regex": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-replace-supers": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.5.tgz", + "integrity": "sha512-h7plkOmcndIUWXZFLgpbrh2+fXAi47zcUX7IrOQuZdLD0I0KvjJ6cvo3BEcAOsDOcZhVKGJqv07mkSqK0y2isQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.20.2.tgz", + "integrity": "sha512-KS/G8YI8uwMGKErLFOHS/ekhqdHhpEloxs43NecQHVgo2QuQSyJhGIY1fL8UGl9wy5ItVwwoUL4YxVqsplGq2g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz", + "integrity": "sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", + "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.18.6", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/plugin-syntax-jsx": "^7.18.6", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz", + "integrity": "sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz", + "integrity": "sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^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-transform-regenerator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.20.2", + "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.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.19.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz", + "integrity": "sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw==", + "dependencies": { + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-plugin-utils": "^7.19.0", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz", + "integrity": "sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.20.2", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", + "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-0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", + "dependencies": { + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-class-static-block": "^7.18.6", + "@babel/plugin-proposal-dynamic-import": "^7.18.6", + "@babel/plugin-proposal-export-namespace-from": "^7.18.9", + "@babel/plugin-proposal-json-strings": "^7.18.6", + "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", + "@babel/plugin-proposal-numeric-separator": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", + "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.18.9", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-private-property-in-object": "^7.18.6", + "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", + "@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.20.0", + "@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-transform-arrow-functions": "^7.18.6", + "@babel/plugin-transform-async-to-generator": "^7.18.6", + "@babel/plugin-transform-block-scoped-functions": "^7.18.6", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", + "@babel/plugin-transform-computed-properties": "^7.18.9", + "@babel/plugin-transform-destructuring": "^7.20.2", + "@babel/plugin-transform-dotall-regex": "^7.18.6", + "@babel/plugin-transform-duplicate-keys": "^7.18.9", + "@babel/plugin-transform-exponentiation-operator": "^7.18.6", + "@babel/plugin-transform-for-of": "^7.18.8", + "@babel/plugin-transform-function-name": "^7.18.9", + "@babel/plugin-transform-literals": "^7.18.9", + "@babel/plugin-transform-member-expression-literals": "^7.18.6", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", + "@babel/plugin-transform-modules-umd": "^7.18.6", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", + "@babel/plugin-transform-new-target": "^7.18.6", + "@babel/plugin-transform-object-super": "^7.18.6", + "@babel/plugin-transform-parameters": "^7.20.1", + "@babel/plugin-transform-property-literals": "^7.18.6", + "@babel/plugin-transform-regenerator": "^7.18.6", + "@babel/plugin-transform-reserved-words": "^7.18.6", + "@babel/plugin-transform-shorthand-properties": "^7.18.6", + "@babel/plugin-transform-spread": "^7.19.0", + "@babel/plugin-transform-sticky-regex": "^7.18.6", + "@babel/plugin-transform-template-literals": "^7.18.9", + "@babel/plugin-transform-typeof-symbol": "^7.18.9", + "@babel/plugin-transform-unicode-escapes": "^7.18.10", + "@babel/plugin-transform-unicode-regex": "^7.18.6", + "@babel/preset-modules": "^0.1.5", + "@babel/types": "^7.20.2", + "babel-plugin-polyfill-corejs2": "^0.3.3", + "babel-plugin-polyfill-corejs3": "^0.6.0", + "babel-plugin-polyfill-regenerator": "^0.4.1", + "core-js-compat": "^3.25.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz", + "integrity": "sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-react-display-name": "^7.18.6", + "@babel/plugin-transform-react-jsx": "^7.18.6", + "@babel/plugin-transform-react-jsx-development": "^7.18.6", + "@babel/plugin-transform-react-pure-annotations": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-validator-option": "^7.18.6", + "@babel/plugin-transform-typescript": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", + "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.6.tgz", + "integrity": "sha512-tqeujPiuEfcH067mx+7otTQWROVMKHXEaOQcAeNV5dDdbPWvPcFA8/W9LXw2NfjNmOetqLl03dfnG2WALPlsRQ==", + "dependencies": { + "core-js-pure": "^3.25.1", + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "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.0.2", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", + "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.2", + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", + "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/@humanwhocodes/config-array": { + "version": "0.11.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", + "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "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/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/@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/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/@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/load-nyc-config/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/@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/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": "^7.1.2", + "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.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "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.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "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/@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/@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/@remix-run/router": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.4.tgz", + "integrity": "sha512-gTL8H5USTAKOyVA4xczzDJnC3HMssdFa3tRlwBicXynx9XfiXwneHnYQogwSKpdCkjXISrEKSTtX62rLpNEVQg==", + "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.2.0", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", + "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + }, + "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": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", + "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.5.0.tgz", + "integrity": "sha512-8zYdkym7qNyfXpWvu4yq46k41pyNM9SOstoWhKlm+IfdCE1DdnRKeMUPsWIEO/DEkaWxJ8T9esNdG3QwQ93jBA==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.5.0.tgz", + "integrity": "sha512-NFdxMq3xA42Kb1UbzCVxplUc0iqSyM9X8kopImvFnB+uSDdzIHOdbs1op8ofAvVRtbg4oZiyRl3fTYeKcOe9Iw==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", + "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", + "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", + "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", + "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", + "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", + "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", + "@svgr/babel-plugin-remove-jsx-attribute": "*", + "@svgr/babel-plugin-remove-jsx-empty-expression": "*", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^6.5.1", + "@svgr/babel-plugin-svg-dynamic-title": "^6.5.1", + "@svgr/babel-plugin-svg-em-dimensions": "^6.5.1", + "@svgr/babel-plugin-transform-react-native-svg": "^6.5.1", + "@svgr/babel-plugin-transform-svg-component": "^6.5.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", + "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", + "dependencies": { + "@babel/core": "^7.19.6", + "@svgr/babel-preset": "^6.5.1", + "@svgr/plugin-jsx": "^6.5.1", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", + "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "dependencies": { + "@babel/types": "^7.20.0", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", + "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "dependencies": { + "@babel/core": "^7.19.6", + "@svgr/babel-preset": "^6.5.1", + "@svgr/hast-util-to-babel-ast": "^6.5.1", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "^6.0.0" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", + "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "dependencies": { + "cosmiconfig": "^7.0.1", + "deepmerge": "^4.2.2", + "svgo": "^2.8.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", + "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", + "dependencies": { + "@babel/core": "^7.19.6", + "@babel/plugin-transform-react-constant-elements": "^7.18.12", + "@babel/preset-env": "^7.19.4", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.18.6", + "@svgr/core": "^6.5.1", + "@svgr/plugin-jsx": "^6.5.1", + "@svgr/plugin-svgo": "^6.5.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@testing-library/dom": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", + "integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==", + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "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==", + "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/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/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/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/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/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/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/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": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==" + }, + "node_modules/@types/babel__core": { + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@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.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "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.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.4.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", + "integrity": "sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==", + "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.0", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz", + "integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==" + }, + "node_modules/@types/express": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz", + "integrity": "sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.31", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz", + "integrity": "sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dependencies": { + "@types/node": "*" + } + }, + "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-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "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": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" + }, + "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": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", + "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" + }, + "node_modules/@types/node": { + "version": "16.18.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.4.tgz", + "integrity": "sha512-9qGjJ5GyShZjUfx2ArBIGM+xExdfLvvaCyQR0t6yRXKPcWCVYF/WemtX/uIU3r7FYECXRXkIiw2Vnhn6y8d+pw==" + }, + "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.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "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.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", + "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "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.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" + }, + "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.0", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==", + "dependencies": { + "@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.5", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.5.tgz", + "integrity": "sha512-SBwbxYoyPIvxHbeHxTZX2Pe/74F/tX2/D3mMvzabdeJ25bBojfW0TyB8BHrbq/9zaaKICJZjLP+8r6AeZMFCuQ==", + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.2.tgz", + "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==" + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "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.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz", + "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/type-utils": "5.45.0", + "@typescript-eslint/utils": "5.45.0", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.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/eslint-plugin/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.45.0.tgz", + "integrity": "sha512-DnRQg5+3uHHt/gaifTjwg9OKbg9/TWehfJzYHQIDJboPEbF897BKDE/qoqMhW7nf0jWRV1mwVXTaUvtB1/9Gwg==", + "dependencies": { + "@typescript-eslint/utils": "5.45.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.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz", + "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==", + "dependencies": { + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/typescript-estree": "5.45.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.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz", + "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==", + "dependencies": { + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/visitor-keys": "5.45.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.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz", + "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.45.0", + "@typescript-eslint/utils": "5.45.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.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz", + "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==", + "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.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz", + "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==", + "dependencies": { + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/visitor-keys": "5.45.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/typescript-estree/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz", + "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.45.0", + "@typescript-eslint/types": "5.45.0", + "@typescript-eslint/typescript-estree": "5.45.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "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/utils/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.45.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz", + "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==", + "dependencies": { + "@typescript-eslint/types": "5.45.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/@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@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/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.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", + "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.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "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-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-node/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-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.1", + "resolved": "https://registry.npmjs.org/address/-/address-1.2.1.tgz", + "integrity": "sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA==", + "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.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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-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/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": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "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/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.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "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.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "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.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "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/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.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==" + }, + "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/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.13", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.13.tgz", + "integrity": "sha512-49vKpMqcZYsJjwotvt4+h/BCjJVnhGwcLpDt5xkcaOG3eLrG/HUYLagrihYsQ+qrIBgIzX1Rw7a6L8I/ZA1Atg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.4", + "caniuse-lite": "^1.0.30001426", + "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.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==" + }, + "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.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", + "dependencies": { + "@babel/compat-data": "^7.17.7", + "@babel/helper-define-polyfill-provider": "^0.3.3", + "semver": "^6.1.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3", + "core-js-compat": "^3.25.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.3.3" + }, + "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.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "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.1", + "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/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "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/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/bonjour-service": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz", + "integrity": "sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ==", + "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.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.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.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "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.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "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.30001436", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", + "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "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.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" + }, + "node_modules/clean-css": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz", + "integrity": "sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg==", + "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/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/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==" + }, + "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.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" + }, + "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": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "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.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "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.26.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", + "dependencies": { + "browserslist": "^4.21.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", + "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.3.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", + "integrity": "sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w==", + "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.7.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", + "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.18", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "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-loader/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.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-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/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.2.0", + "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.2.0.tgz", + "integrity": "sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/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.14", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.14.tgz", + "integrity": "sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw==", + "dependencies": { + "cssnano-preset-default": "^5.2.13", + "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.13", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz", + "integrity": "sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ==", + "dependencies": { + "css-declaration-sorter": "^6.3.1", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "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.3", + "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.1", + "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/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.1", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", + "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + }, + "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/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.1.0", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.1.0.tgz", + "integrity": "sha512-2pxgvWu3Alv1PoWEyVg7HS8YhGlUFUV7N5oOvfL6d+7xAmLSemMwv/c8Zv/i9KFzxV5Kt5CAvQc70fLwVuf4UA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-get-iterator": "^1.1.2", + "get-intrinsic": "^1.1.3", + "is-arguments": "^1.1.1", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "isarray": "^2.0.5", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.8" + }, + "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.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "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-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.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defined": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", + "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "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/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": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port-alt/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port-alt/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "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.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", + "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.14", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz", + "integrity": "sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg==" + }, + "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-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/dom-serializer/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/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.8", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", + "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "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.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "engines": { + "node": ">=0.12" + }, + "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.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "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-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz", + "integrity": "sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.0", + "has-symbols": "^1.0.1", + "is-arguments": "^1.1.0", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.5", + "isarray": "^2.0.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==" + }, + "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.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "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/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.29.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz", + "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==", + "dependencies": { + "@eslint/eslintrc": "^1.3.3", + "@humanwhocodes/config-array": "^0.11.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "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.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "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.15.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "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.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb": { + "version": "19.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz", + "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + }, + "engines": { + "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^4.3.0" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "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/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "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.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "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-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/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "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/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "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.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "dependencies": { + "@babel/runtime": "^7.18.9", + "aria-query": "^4.2.2", + "array-includes": "^3.1.5", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.4.3", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.2", + "language-tags": "^1.0.5", + "minimatch": "^3.1.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "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.3", + "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-testing-library": { + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz", + "integrity": "sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ==", + "dependencies": { + "@typescript-eslint/utils": "^5.13.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": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/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-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "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.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.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/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-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.18.0.tgz", + "integrity": "sha512-/mR4KI8Ps2spmoc0Ulu9L7agOF0du1CZNQ3dke8yItYlyKNmGrkONemBbd6V8UTc1Wgcqn21t3WYB7dbRmh6/A==", + "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/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": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "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.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.1", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "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/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "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.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", + "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.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.1.tgz", + "integrity": "sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g==", + "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.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "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": "2.6.9", + "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/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "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-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.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "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.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz", + "integrity": "sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==", + "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": "^7.1.6", + "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/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/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.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==" + }, + "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.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "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.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "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": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "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/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/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.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "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-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/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/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.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "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.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==" + }, + "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-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "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/htmlparser2/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/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/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.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz", + "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immer": { + "version": "9.0.16", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.16.tgz", + "integrity": "sha512-qenGE7CstVm1NrHQbMh8YaSzTZTFNP3zPqr3YU0S0UY441j4bJTg4A2Hh5KAhwgaiU6ZZ1Ar6y/2f4TblnMReQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.1.0.tgz", + "integrity": "sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==" + }, + "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-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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ipaddr.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", + "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "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-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-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.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "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-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-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.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "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/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-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/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "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": "^7.1.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": "^7.1.3", + "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/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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.15", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.15.tgz", + "integrity": "sha512-ZHc4W2dnEQPfhn06TBEdWaiUHEZAocYaiVMfwOipY5jcJt/251wVrKCBWBetGZWO5CF8tdb7L3DmdxVlZ2BOIg==", + "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.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "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/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "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": "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/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.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "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.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + }, + "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.5", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", + "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", + "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.6", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.6.tgz", + "integrity": "sha512-HNkaCgM8wZgE/BZACeotAAgpL9FUjEnhgF0FVQMIgH//zqTPreLYMb3rWYkYAqPoF75Jwuycp1da7uz66cfFQg==", + "dependencies": { + "language-subtag-registry": "^0.3.20" + } + }, + "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.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "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.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.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": "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/lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==", + "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/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.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "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.4.12", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.12.tgz", + "integrity": "sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw==", + "dependencies": { + "fs-monkey": "^1.0.3" + }, + "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.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dependencies": { + "braces": "^3.0.2", + "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.1", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.1.tgz", + "integrity": "sha512-viOoaUFy+Z2w43VsGPbtfwFrr0tKwDctK9dUofG5MBViYhD1noGFUzzDIVw0KPwCGUP+c7zqLxm+acuQs7zLzw==", + "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.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.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.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "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.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + }, + "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/nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==" + }, + "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.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "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.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "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/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dependencies": { + "wrappy": "1" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "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.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "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-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "engines": { + "node": ">=0.10.0" + } + }, + "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-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.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "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.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "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.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", + "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "dependencies": { + "browserslist": "^4.16.6", + "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": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/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.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "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": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/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-loader/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz", + "integrity": "sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA==", + "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.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "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.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.0.tgz", + "integrity": "sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/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.2", + "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz", + "integrity": "sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w==", + "funding": [ + { + "type": "kofi", + "url": "https://ko-fi.com/mrcgrtz" + }, + { + "type": "liberapay", + "url": "https://liberapay.com/mrcgrtz" + } + ], + "engines": { + "node": "^12 || ^14 || >=16" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz", + "integrity": "sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w==", + "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.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", + "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-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/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==", + "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/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/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.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "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/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "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-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-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-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.4.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.4.tgz", + "integrity": "sha512-SA6tSrUCRfuLWeYsTJDuriRqfFIsrSvuH7SqAJHegx9ZgxadE119rU8oOX/rG5FYEthpdEaEljdjDlnBxvfr+Q==", + "dependencies": { + "@remix-run/router": "1.0.4" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.4.tgz", + "integrity": "sha512-0Axverhw5d+4SBhLqLpzPhNkmv7gahUwlUVIOrRLGJ4/uwt30JVajVJXqv2Qr/LCwyvHhQc7YyK1Do8a9Jj7qA==", + "dependencies": { + "@remix-run/router": "1.0.4", + "react-router": "6.4.4" + }, + "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/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "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/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.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "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.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsgen": "^0.7.1", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" + }, + "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/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "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/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-cwd/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-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/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": "^7.0.35", + "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/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==" + }, + "node_modules/resolve-url-loader/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "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": "^7.1.3" + }, + "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": "^4.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/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dependencies": { + "randombytes": "^2.1.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-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": { + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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/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.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "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": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dependencies": { + "debug": "2.6.9", + "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": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.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==" + }, + "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.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "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": "2.6.9", + "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/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.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/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "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/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.7.4", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz", + "integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==", + "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/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/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.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "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/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.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "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.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "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/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": "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/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/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/tailwindcss": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.12", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.18", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "6.0.0", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/tailwindcss/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/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.16.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.1.tgz", + "integrity": "sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==", + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "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.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", + "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + }, + "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": "^7.1.4", + "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/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==" + }, + "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/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/tough-cookie": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "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/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "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.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "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/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.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "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/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/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.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "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/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": "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/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/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.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "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.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "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.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", + "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "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.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz", + "integrity": "sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw==", + "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.1", + "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", + "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.4.2" + }, + "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-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "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/webpack/node_modules/@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==" + }, + "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-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.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", + "integrity": "sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz", + "integrity": "sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-build": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.5.4.tgz", + "integrity": "sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==", + "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": "^7.1.6", + "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.5.4", + "workbox-broadcast-update": "6.5.4", + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-google-analytics": "6.5.4", + "workbox-navigation-preload": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-range-requests": "6.5.4", + "workbox-recipes": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4", + "workbox-streams": "6.5.4", + "workbox-sw": "6.5.4", + "workbox-window": "6.5.4" + }, + "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.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", + "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.5.4", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz", + "integrity": "sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-core": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz", + "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==" + }, + "node_modules/workbox-expiration": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.5.4.tgz", + "integrity": "sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz", + "integrity": "sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==", + "dependencies": { + "workbox-background-sync": "6.5.4", + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz", + "integrity": "sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-precaching": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.5.4.tgz", + "integrity": "sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==", + "dependencies": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz", + "integrity": "sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-recipes": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.5.4.tgz", + "integrity": "sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==", + "dependencies": { + "workbox-cacheable-response": "6.5.4", + "workbox-core": "6.5.4", + "workbox-expiration": "6.5.4", + "workbox-precaching": "6.5.4", + "workbox-routing": "6.5.4", + "workbox-strategies": "6.5.4" + } + }, + "node_modules/workbox-routing": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz", + "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-strategies": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz", + "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==", + "dependencies": { + "workbox-core": "6.5.4" + } + }, + "node_modules/workbox-streams": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.5.4.tgz", + "integrity": "sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==", + "dependencies": { + "workbox-core": "6.5.4", + "workbox-routing": "6.5.4" + } + }, + "node_modules/workbox-sw": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.5.4.tgz", + "integrity": "sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==" + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz", + "integrity": "sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==", + "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.5.4" + }, + "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.5.4", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.5.4.tgz", + "integrity": "sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.5.4" + } + }, + "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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "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/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "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" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..33b5b15 --- /dev/null +++ b/package.json @@ -0,0 +1,65 @@ +{ + "name": "my-app", + "version": "0.1.0", + "private": true, + "homepage": "./", + "dependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.4", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.9", + "prettier": "^2.8.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.4.4", + "react-scripts": "^5.0.1", + "sass": "^1.56.1", + "typescript": "^4.9.3", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "repository": { + "type": "git", + "url": "" + }, + "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": { + "@svgr/webpack": "^6.5.1", + "@typescript-eslint/eslint-plugin": "^5.45.0", + "@typescript-eslint/parser": "^5.45.0", + "eslint": "^8.29.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jsx-a11y": "^6.6.1", + "eslint-plugin-react": "^7.31.11", + "eslint-plugin-react-hooks": "^4.6.0" + }, + "overrides": { + "@svgr/webpack": "$@svgr/webpack" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..0d77b13 --- /dev/null +++ b/public/index.html @@ -0,0 +1,18 @@ + + + + + + + + + + React App + + +
+ + diff --git a/public/logo192.png b/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9 GIT binary patch literal 5347 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/src/App/App.tsx b/src/App/App.tsx new file mode 100644 index 0000000..0ff3527 --- /dev/null +++ b/src/App/App.tsx @@ -0,0 +1,14 @@ +import React from 'react'; +import { HashRouter } from 'react-router-dom'; +import RootRouter from './RootRouter'; + +function App() { + return ( + + + + + ); +} + +export default App; diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx new file mode 100644 index 0000000..e68f6b4 --- /dev/null +++ b/src/App/RootRouter/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { Route, Routes } from 'react-router-dom'; +import Header from '../../Components/header'; +import Main from '../../Pages/Main'; +import Other from '../../Pages/Other'; + +// Компонент который осуществляет роутинг по страницам SPA, +// header вынесен из роутов,то он будет постоянным +// Можно сдеать каждому компоненту к которому мы роутим свой хедер внутри компонента, +// если нам нужен индивидуальный хедер на каждой страницы или убрать где-то хедер + +export default function RootRouter() { + return ( +
+
+ + } /> + } /> + +
+ ); +} diff --git a/src/Components/TestComponentWithHooks/index.tsx b/src/Components/TestComponentWithHooks/index.tsx new file mode 100644 index 0000000..a723b0b --- /dev/null +++ b/src/Components/TestComponentWithHooks/index.tsx @@ -0,0 +1,26 @@ +import { useEffect, useState } from 'react'; + +function TestComponentWithHooks() { + // пример использования хука useState + const [counter, setCounter] = useState(0); + // пример использования хука useEffect, который запуститься только 1 раз при рендере страницы + // массив зависимостей в таком случае должен быть пустым + useEffect(() => { + console.log('вызывается один раз при рендере'); + }, []); + // этот useEffect запустится при рендере + // + при каждом изменении значения переменной указанной в массиве зависимостей + useEffect(() => { + console.log(`Текущий counter: ${counter}`); + }, [counter]); + + return ( +
+

{`Current counter: ${counter}`}

+ + +
+ ); +} + +export default TestComponentWithHooks; diff --git a/src/Components/TestForMain/index.tsx b/src/Components/TestForMain/index.tsx new file mode 100644 index 0000000..3986d0e --- /dev/null +++ b/src/Components/TestForMain/index.tsx @@ -0,0 +1,16 @@ +import './styles.scss'; + +interface Props { + number: number +} +// компонент объявлен в виде function expression, особой разницы нет, можно и declaration +// также посмотрите на типизацию пропсов, можно типизировать через FC, почитайте в доке +function TestForMain({ number }: Props) { + return ( +
+

{`Main page component №${number}`}

+
+ ); +} + +export default TestForMain; diff --git a/src/Components/TestForMain/styles.scss b/src/Components/TestForMain/styles.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/Components/TestForOther/index.tsx b/src/Components/TestForOther/index.tsx new file mode 100644 index 0000000..98f7b1a --- /dev/null +++ b/src/Components/TestForOther/index.tsx @@ -0,0 +1,10 @@ +// компонент создан через function expression, как создавать особого значения не имеет +function TestForOther() { + return ( +
+

Other page component

+
+ ); +} + +export default TestForOther; diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx new file mode 100644 index 0000000..a6e45bf --- /dev/null +++ b/src/Components/header/index.tsx @@ -0,0 +1,42 @@ +import React, { useMemo } from 'react'; +import { NavLink } from 'react-router-dom'; +// тут стили импортированы при помощи модулей, это один из способов подключения стилей. +// В таком случае в компонентах можно использовать повторяющиеся названия для стилей, +// т.к. к ним присоединиться случайный хеш и на самом деле название стиля будет отличаться +import styles from './styles.module.scss'; + +// компонент созданный при помощи function declaration, +// можно писать и используя expression. В другом компоненте будет пример +export default function Header() { + // можно не обращать внимание на useMemo, это уже более продвинутый уровень + // ниже функция которая навешивает определенный стиль исходя их переменной isActive, + // это встроенная переменная в элементе NavLink + // NavLink мы взяли из react-router-dom + const activeStyles = useMemo( + () => (bool: boolean) => (bool + ? styles.header__navigation__link__active + : styles.header__navigation__link), + [], + ); + + return ( +
+ +
+ ); +} diff --git a/src/Components/header/styles.module.scss b/src/Components/header/styles.module.scss new file mode 100644 index 0000000..47dbf1d --- /dev/null +++ b/src/Components/header/styles.module.scss @@ -0,0 +1,21 @@ +.header { + height: 100px; + background-color: red; + &__navigation { + display: flex; + height: 100%; + align-items: center; + &__link { + display: block; + margin-left: 50px; + color: white; + text-decoration: none; + &__active { + display: block; + text-decoration: underline; + margin-left: 50px; + color: black; + } + } + } +} \ No newline at end of file diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx new file mode 100644 index 0000000..27b6b88 --- /dev/null +++ b/src/Pages/Main/index.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import TestForMain from '../../Components/TestForMain'; + +function Main() { + const testArr = [1, 2, 3, 4]; + + // Рендерим 4 компонента на основе массива, передаем в каждый компонент пропсы из массива + // При таком рендере важно указывать key для каждого компонента. Он должен быть уникальным + return ( + <> + { + testArr.map((item) => ) + } + + ); +} + +export default Main; diff --git a/src/Pages/Main/test/main.test.tsx b/src/Pages/Main/test/main.test.tsx new file mode 100644 index 0000000..a1fe01b --- /dev/null +++ b/src/Pages/Main/test/main.test.tsx @@ -0,0 +1,8 @@ +import { render, screen } from '@testing-library/react'; +import Main from '../index'; +// Тест. Проверяем зарендерилась страница с теми блоками которые мы ожидаем на ней увидеть +test('renders main page', () => { + render(
); + const textElement = screen.getByText(/Main page component №1/i); + expect(textElement).toBeInTheDocument(); +}); diff --git a/src/Pages/Other/index.tsx b/src/Pages/Other/index.tsx new file mode 100644 index 0000000..68b6391 --- /dev/null +++ b/src/Pages/Other/index.tsx @@ -0,0 +1,13 @@ +import TestComponentWithHooks from '../../Components/TestComponentWithHooks'; +import TestForOther from '../../Components/TestForOther'; + +function Other() { + return ( + <> + + + + ); +} + +export default Other; diff --git a/src/Pages/Other/test/other.test.tsx b/src/Pages/Other/test/other.test.tsx new file mode 100644 index 0000000..7888bc8 --- /dev/null +++ b/src/Pages/Other/test/other.test.tsx @@ -0,0 +1,8 @@ +import { render, screen } from '@testing-library/react'; +import Other from '../index'; +// Тест. Проверяем зарендерилась страница с теми блоками которые мы ожидаем на ней увидеть +test('renders other page', () => { + render(); + const textElement = screen.getByText(/Other page component/i); + expect(textElement).toBeInTheDocument(); +}); diff --git a/src/globals.d.ts b/src/globals.d.ts new file mode 100644 index 0000000..26144e8 --- /dev/null +++ b/src/globals.d.ts @@ -0,0 +1 @@ +declare module '*.module.scss'; diff --git a/src/index.scss b/src/index.scss new file mode 100644 index 0000000..ec2585e --- /dev/null +++ b/src/index.scss @@ -0,0 +1,13 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} diff --git a/src/index.tsx b/src/index.tsx new file mode 100644 index 0000000..d7099e5 --- /dev/null +++ b/src/index.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import './index.scss'; +import App from './App/App'; + +const root = ReactDOM.createRoot( + document.getElementById('root') as HTMLElement, +); +root.render( + , +); diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts new file mode 100644 index 0000000..6431bc5 --- /dev/null +++ b/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/setupTests.ts b/src/setupTests.ts new file mode 100644 index 0000000..8f2609b --- /dev/null +++ b/src/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..dcb64dd --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "noImplicitAny": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": [ + "src" + ] +} From dad1e53bee82ce8fc02363c091e35d23bad555b6 Mon Sep 17 00:00:00 2001 From: Dinara Date: Mon, 2 Jan 2023 17:46:10 +0400 Subject: [PATCH 02/65] feat: add page 404 --- src/App/RootRouter/index.tsx | 2 ++ src/Pages/PageNotFound/index.tsx | 12 ++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 src/Pages/PageNotFound/index.tsx diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index e68f6b4..9bb61f8 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -3,6 +3,7 @@ import { Route, Routes } from 'react-router-dom'; import Header from '../../Components/header'; import Main from '../../Pages/Main'; import Other from '../../Pages/Other'; +import PageNotFound from '../../Pages/PageNotFound'; // Компонент который осуществляет роутинг по страницам SPA, // header вынесен из роутов,то он будет постоянным @@ -16,6 +17,7 @@ export default function RootRouter() { } /> } /> + } /> ); diff --git a/src/Pages/PageNotFound/index.tsx b/src/Pages/PageNotFound/index.tsx new file mode 100644 index 0000000..95c1d94 --- /dev/null +++ b/src/Pages/PageNotFound/index.tsx @@ -0,0 +1,12 @@ +import React from 'react'; + +function PageNotFound() { + return ( +
+

404 Page Not Found!

+

This page does not seem to exist.

+
+ ); +} + +export default PageNotFound; From 63270437caa22409c425f0dd12b61b37cde72053 Mon Sep 17 00:00:00 2001 From: Buffik Date: Tue, 3 Jan 2023 21:13:50 +0300 Subject: [PATCH 03/65] feat: add template of cart, add rendering products from server, add +/- buttons to change count of product --- src/App/RootRouter/index.tsx | 2 + src/Components/API/PostService.ts | 35 ++++++++ .../CartProduct/CartProduct.module.scss | 12 +++ src/Components/CartProduct/CartProduct.tsx | 49 ++++++++++ .../UI/button/ProductCartButton.module.scss | 0 .../UI/button/ProductCartButton.tsx | 20 +++++ src/Components/header/index.tsx | 6 ++ src/Pages/Cart/cart.tsx | 89 +++++++++++++++++++ src/hooks/useFetching.ts | 24 +++++ src/types/types.ts | 32 +++++++ 10 files changed, 269 insertions(+) create mode 100644 src/Components/API/PostService.ts create mode 100644 src/Components/CartProduct/CartProduct.module.scss create mode 100644 src/Components/CartProduct/CartProduct.tsx create mode 100644 src/Components/UI/button/ProductCartButton.module.scss create mode 100644 src/Components/UI/button/ProductCartButton.tsx create mode 100644 src/Pages/Cart/cart.tsx create mode 100644 src/hooks/useFetching.ts create mode 100644 src/types/types.ts diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index e68f6b4..c1ff22c 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Route, Routes } from 'react-router-dom'; import Header from '../../Components/header'; +import Cart from '../../Pages/Cart/cart'; import Main from '../../Pages/Main'; import Other from '../../Pages/Other'; @@ -16,6 +17,7 @@ export default function RootRouter() { } /> } /> + } /> ); diff --git a/src/Components/API/PostService.ts b/src/Components/API/PostService.ts new file mode 100644 index 0000000..e41ae19 --- /dev/null +++ b/src/Components/API/PostService.ts @@ -0,0 +1,35 @@ +import { TProductPartialProps } from '../../types/types'; + +export default class PostService { + // static async getAll(limit = 10, page = 1) { + // const response = await axios.get( + // 'https://jsonplaceholder.typicode.com/posts', + // { + // params: { + // _limit: limit, + // _page: page, + // }, + // } + // ); + // return response; + // } + + static getById(id:number) { + const URL = `https://dummyjson.com/products/${id}`; + return fetch(URL).then((response) => response.json()); + } + + static async getCartItems(arr:TProductPartialProps[]) { + let itemRequests = []; + itemRequests = arr.map((item) => PostService.getById(item.id)); + const promises = await Promise.all(itemRequests); + return promises; + } + + // static async getCommentsByPostId(id) { + // const response = await axios.get( + // `https://jsonplaceholder.typicode.com/posts/${id}/comments` + // ); + // return response; + // } +} diff --git a/src/Components/CartProduct/CartProduct.module.scss b/src/Components/CartProduct/CartProduct.module.scss new file mode 100644 index 0000000..9b41e3c --- /dev/null +++ b/src/Components/CartProduct/CartProduct.module.scss @@ -0,0 +1,12 @@ +.cardProduct { + max-width: 60%; + padding: 1rem; + border: 2px solid teal; + border-radius: 10px; +} + +.infoWrapper { + display: flex; + align-items: center; + flex-direction: column; +} \ No newline at end of file diff --git a/src/Components/CartProduct/CartProduct.tsx b/src/Components/CartProduct/CartProduct.tsx new file mode 100644 index 0000000..d33ce9a --- /dev/null +++ b/src/Components/CartProduct/CartProduct.tsx @@ -0,0 +1,49 @@ +/* eslint-disable max-len */ +import React from 'react'; +import { TProductsCart } from '../../types/types'; +import ProductCartButton from '../UI/button/ProductCartButton'; +import styles from './CartProduct.module.scss'; + +function CartProduct(props:TProductsCart) { + // eslint-disable-next-line max-len + const { + title, + description, + price, + category, + brand, + discountPercentage, + rating, + stock, + thumbnail, + onClickHandlerIncrease, + data, + onClickHandlerDecrease, + } = props; + if (!data) { + return ( +
Is loading
+ ); + } + return ( +
+ {title} +
+

{title}

+
+

{description}

+
{price}
+
{category}
+
{brand}
+
{discountPercentage}
+
{rating}
+
{stock}
+
+
+
+
{data.count}
+
{data.count === 1 ? 'Delete from cart' : '-'}
+
+ ); +} + +export default CartProduct; diff --git a/src/Components/UI/button/ProductCartButton.module.scss b/src/Components/UI/button/ProductCartButton.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/Components/UI/button/ProductCartButton.tsx b/src/Components/UI/button/ProductCartButton.tsx new file mode 100644 index 0000000..9bbab68 --- /dev/null +++ b/src/Components/UI/button/ProductCartButton.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import styles from './ProductCartButton.module.scss'; + +interface CartButtonProps { + children: React.ReactNode + // eslint-disable-next-line no-unused-vars + onClick: (event:React.MouseEvent) => void + value: number + +} + +function ProductCartButton({ children, onClick, value }: CartButtonProps) { + return ( + + ); +} + +export default ProductCartButton; diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index a6e45bf..0c9ad84 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -36,6 +36,12 @@ export default function Header() { > Other page + activeStyles(isActive)} + to="/cart" + > + Cart + ); diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx new file mode 100644 index 0000000..b524318 --- /dev/null +++ b/src/Pages/Cart/cart.tsx @@ -0,0 +1,89 @@ +/* eslint-disable max-len */ +import React, { useEffect, useState } from 'react'; +import PostService from '../../Components/API/PostService'; +import CartProduct from '../../Components/CartProduct/CartProduct'; +import useFetching from '../../hooks/useFetching'; +import { TProductsItem, TProductPartialProps } from '../../types/types'; + +function Cart() { + const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 10, count: 1 }]; + const [productsInCart, setProductsInCart] = useState(arr); + const [productsInCartCount, setproductsInCartCount] = useState(arr); + const [products, setProducts] = useState(null); + const [fetchProductsById] = useFetching(async () => { + const response = await PostService.getCartItems(productsInCart).then((items) => items.map((item) => item)); + setProducts(response); + }); + + useEffect(() => { + fetchProductsById(); + }, [productsInCart]); + + const increaseProductCount = (event: React.MouseEvent) => { + const cur = Number(event.currentTarget.value); + const maxCount = products?.reduce((acc, product) => { + if (product.id === cur) { + // eslint-disable-next-line no-param-reassign + acc += product.stock; + return acc; + } + return acc; + }, 0); + const result = productsInCartCount.map((product) => { + if (maxCount && product.count === maxCount) { + return product; + } + if (product.id === cur) { + return { ...product, count: product.count + 1 }; + } + return product; + }); + setproductsInCartCount(result); + }; + + const decreaseProductCount = (event: React.MouseEvent) => { + const cur = Number(event.currentTarget.value); + const result = productsInCartCount.reduce((acc, product) => { + if (product.id === cur && product.count === 1) { + setProductsInCart(productsInCart.filter((el) => el.id !== cur)); + return acc; + } + if (product.id === cur) { + acc.push({ ...product, count: product.count - 1 }); + return acc; + } + acc.push(product); + return acc; + }, []); + setproductsInCartCount(result); + }; + + // eslint-disable-next-line max-len + return ( +
+ {!products ? ( + <>Is Loading... + ) : ( + products.map((product: TProductsItem, index) => ( + + )) + )} +
+ ); +} + +export default Cart; diff --git a/src/hooks/useFetching.ts b/src/hooks/useFetching.ts new file mode 100644 index 0000000..9bb1784 --- /dev/null +++ b/src/hooks/useFetching.ts @@ -0,0 +1,24 @@ +import { useState } from 'react'; + +const useFetching = (callback: () => any) => { + const [isLoading, setIsLoading] = useState(false); + + const [error, setError] = useState(''); + + const fetching = async () => { + try { + setIsLoading(true); + await callback(); + } catch (err) { + if (err instanceof Error) { + setError(err.message); + } + } finally { + setIsLoading(false); + } + }; + + return [fetching, isLoading, error] as const; +}; + +export default useFetching; diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..321bac8 --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,32 @@ +export type TProductsItem = { + id?: number; + title: string; + description: string; + price: number; + category: string; + brand: string; + discountPercentage: number; + images?: string[]; + rating: number; + stock: number; + thumbnail: string; +} + +export type TProductPartialProps = { + id: number, + count: number +} + +export type TProductCartIdCountProps = { + data: TProductPartialProps +} + +export type TProductHandlers = { + + // eslint-disable-next-line no-unused-vars, no-undef + onClickHandlerIncrease: (event: React.MouseEvent) => void, + // eslint-disable-next-line no-unused-vars, no-undef + onClickHandlerDecrease: (event: React.MouseEvent) => void +} + +export type TProductsCart = TProductsItem & TProductHandlers & TProductCartIdCountProps From 46a3e0c15ee09b0a3792fd25ee4ad33252b3011f Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 14:43:14 +0400 Subject: [PATCH 04/65] feat: add fetching and displaying products on main page --- src/Pages/Main/index.tsx | 74 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 27b6b88..4561908 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,15 +1,77 @@ -import React from 'react'; -import TestForMain from '../../Components/TestForMain'; +import React, { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +// import TestForMain from '../../Components/TestForMain'; function Main() { - const testArr = [1, 2, 3, 4]; + // const { cartItems } = props; + // const testArr = [1, 2, 3, 4]; + const [products, setProducts] = useState([]); + + const fetchProducts = async () => { + const response = await fetch('https://dummyjson.com/products?limit=10'); + const productsList = await response.json(); + setProducts(productsList.products); + }; + + useEffect(() => { + fetchProducts(); + }, []); + + type TProductsItem = { + id: number; + title: string; + description: string; + price: number; + category: string; + brand: string; + discountPercentage: number; + images: string[]; + rating: number; + stock: number; + thumbnail: string; + } - // Рендерим 4 компонента на основе массива, передаем в каждый компонент пропсы из массива - // При таком рендере важно указывать key для каждого компонента. Он должен быть уникальным return ( <> { - testArr.map((item) => ) + products.map((item: TProductsItem) => ( +
+

{item.title}

+ {item.title} +
+
Category:
+
{item.category}
+
+
+
Brand:
+
{item.brand}
+
+
+
Price:
+
+ $ + {item.price} +
+
+
+
Discount:
+
+ {item.discountPercentage} + % +
+
+
+
Rating:
+
{item.rating}
+
+
+
Stock:
+
{item.stock}
+
+ + Details +
+ )) } ); From d4047d3d55d5e42055549e7d66af155e04ce87c9 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 14:45:39 +0400 Subject: [PATCH 05/65] feat: move cart logic to upper component --- src/App/App.tsx | 69 +++++++++++++++++- src/App/RootRouter/index.tsx | 35 ++++++++- src/Components/header/index.tsx | 20 ++++- src/Pages/Cart/cart.tsx | 125 +++++++++++++++++++------------- 4 files changed, 191 insertions(+), 58 deletions(-) diff --git a/src/App/App.tsx b/src/App/App.tsx index 0ff3527..16afc3d 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -1,11 +1,76 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { HashRouter } from 'react-router-dom'; import RootRouter from './RootRouter'; +import PostService from '../Components/API/PostService'; +import useFetching from '../hooks/useFetching'; +import { TProductsItem, TProductPartialProps } from '../types/types'; function App() { + // type TCartItem = { + // id: number; + // count: number; + // } + // const [cartItems, setCartItems] = useState([]); + const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }]; + const [productsInCart, setProductsInCart] = useState(arr); + const [productsInCartCount, setproductsInCartCount] = useState(arr); + const [products, setProducts] = useState(null); + const [fetchProductsById] = useFetching(async () => { + const response = await PostService.getCartItems(productsInCart) + .then((items) => items.map((item) => item)); + setProducts(response); + }); + + useEffect(() => { + fetchProductsById(); + }, [productsInCart]); + + const increaseProductCount = (event: React.MouseEvent) => { + const cur = Number(event.currentTarget.value); + const maxCount = products?.reduce((acc, product) => { + if (product.id === cur) { + return acc + product.stock; + } + return acc; + }, 0); + const result = productsInCartCount.map((product) => { + if (maxCount && product.count === maxCount) { + return product; + } + if (product.id === cur) { + return { ...product, count: product.count + 1 }; + } + return product; + }); + setproductsInCartCount(result); + }; + + const decreaseProductCount = (event: React.MouseEvent) => { + const cur = Number(event.currentTarget.value); + const result = productsInCartCount.reduce((acc, product) => { + if (product.id === cur && product.count === 1) { + setProductsInCart(productsInCart.filter((el) => el.id !== cur)); + return acc; + } + if (product.id === cur) { + acc.push({ ...product, count: product.count - 1 }); + return acc; + } + acc.push(product); + return acc; + }, []); + setproductsInCartCount(result); + }; + return ( - + ); diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index d121cd5..2a49bbd 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -5,20 +5,49 @@ import Cart from '../../Pages/Cart/cart'; import Main from '../../Pages/Main'; import Other from '../../Pages/Other'; import PageNotFound from '../../Pages/PageNotFound'; +import { TProductsItem, TProductPartialProps } from '../../types/types'; // Компонент который осуществляет роутинг по страницам SPA, // header вынесен из роутов,то он будет постоянным // Можно сдеать каждому компоненту к которому мы роутим свой хедер внутри компонента, // если нам нужен индивидуальный хедер на каждой страницы или убрать где-то хедер +// type TCartItem = { +// id: number; +// count: number; +// } -export default function RootRouter() { +type TProps = { + // productsInCart: TProductPartialProps[]; + productsInCartCount: TProductPartialProps[]; + products: TProductsItem[] | null; + // eslint-disable-next-line no-unused-vars + increaseProductCount(event: React.MouseEvent): void; + // eslint-disable-next-line no-unused-vars + decreaseProductCount(event: React.MouseEvent): void; +} + +export default function RootRouter(props: TProps) { + const { + productsInCartCount, products, increaseProductCount, decreaseProductCount, + } = props; return (
-
+
} /> } /> - } /> + + )} + /> } />
diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 0c9ad84..3419f2c 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -4,10 +4,24 @@ import { NavLink } from 'react-router-dom'; // В таком случае в компонентах можно использовать повторяющиеся названия для стилей, // т.к. к ним присоединиться случайный хеш и на самом деле название стиля будет отличаться import styles from './styles.module.scss'; +import { TProductPartialProps } from '../../types/types'; + +type TProps = { + // productsInCart: TProductPartialProps[]; + productsInCartCount: TProductPartialProps[]; + // products: TProductsItem[] | null; + // eslint-disable-next-line no-unused-vars + // increaseProductCount(event: React.MouseEvent): void; + // eslint-disable-next-line no-unused-vars + // decreaseProductCount(event: React.MouseEvent): void; +} // компонент созданный при помощи function declaration, // можно писать и используя expression. В другом компоненте будет пример -export default function Header() { +export default function Header(props: TProps) { + const { productsInCartCount } = props; + // console.log(`header: ${productsInCartCount.reduce((acc, elem) => acc + elem.count, 0)}`); + // const { cartItems } = props; // можно не обращать внимание на useMemo, это уже более продвинутый уровень // ниже функция которая навешивает определенный стиль исходя их переменной isActive, // это встроенная переменная в элементе NavLink @@ -42,6 +56,10 @@ export default function Header() { > Cart +

+ Count: + {productsInCartCount.reduce((acc, elem) => acc + elem.count, 0)} +

); diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index b524318..2e1673f 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,62 +1,83 @@ /* eslint-disable max-len */ -import React, { useEffect, useState } from 'react'; -import PostService from '../../Components/API/PostService'; +import React from 'react'; +// import React, { useEffect, useState } from 'react'; +// import PostService from '../../Components/API/PostService'; import CartProduct from '../../Components/CartProduct/CartProduct'; -import useFetching from '../../hooks/useFetching'; +// import useFetching from '../../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../../types/types'; -function Cart() { - const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 10, count: 1 }]; - const [productsInCart, setProductsInCart] = useState(arr); - const [productsInCartCount, setproductsInCartCount] = useState(arr); - const [products, setProducts] = useState(null); - const [fetchProductsById] = useFetching(async () => { - const response = await PostService.getCartItems(productsInCart).then((items) => items.map((item) => item)); - setProducts(response); - }); +// type TCartItem = { +// id: number; +// count: number; +// } +// type TCartItems = TCartItem[]; - useEffect(() => { - fetchProductsById(); - }, [productsInCart]); +type TProps = { + // productsInCart: TProductPartialProps[]; + productsInCartCount: TProductPartialProps[]; + products: TProductsItem[] | null; + // eslint-disable-next-line no-unused-vars + increaseProductCount(event: React.MouseEvent): void; + // eslint-disable-next-line no-unused-vars + decreaseProductCount(event: React.MouseEvent): void; +} + +function Cart(props: TProps) { + const { + productsInCartCount, products, increaseProductCount, decreaseProductCount, + } = props; + // console.log(`cartItems: ${cartItems}`); + // const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 10, count: 1 }]; + // const [productsInCart, setProductsInCart] = useState(arr); + // const [productsInCartCount, setproductsInCartCount] = useState(arr); + // const [products, setProducts] = useState(null); + // const [fetchProductsById] = useFetching(async () => { + // const response = await PostService.getCartItems(productsInCart).then((items) => items.map((item) => item)); + // setProducts(response); + // }); + + // useEffect(() => { + // fetchProductsById(); + // }, [productsInCart]); - const increaseProductCount = (event: React.MouseEvent) => { - const cur = Number(event.currentTarget.value); - const maxCount = products?.reduce((acc, product) => { - if (product.id === cur) { - // eslint-disable-next-line no-param-reassign - acc += product.stock; - return acc; - } - return acc; - }, 0); - const result = productsInCartCount.map((product) => { - if (maxCount && product.count === maxCount) { - return product; - } - if (product.id === cur) { - return { ...product, count: product.count + 1 }; - } - return product; - }); - setproductsInCartCount(result); - }; + // const increaseProductCount = (event: React.MouseEvent) => { + // const cur = Number(event.currentTarget.value); + // const maxCount = products?.reduce((acc, product) => { + // if (product.id === cur) { + // // eslint-disable-next-line no-param-reassign + // acc += product.stock; + // return acc; + // } + // return acc; + // }, 0); + // const result = productsInCartCount.map((product) => { + // if (maxCount && product.count === maxCount) { + // return product; + // } + // if (product.id === cur) { + // return { ...product, count: product.count + 1 }; + // } + // return product; + // }); + // setproductsInCartCount(result); + // }; - const decreaseProductCount = (event: React.MouseEvent) => { - const cur = Number(event.currentTarget.value); - const result = productsInCartCount.reduce((acc, product) => { - if (product.id === cur && product.count === 1) { - setProductsInCart(productsInCart.filter((el) => el.id !== cur)); - return acc; - } - if (product.id === cur) { - acc.push({ ...product, count: product.count - 1 }); - return acc; - } - acc.push(product); - return acc; - }, []); - setproductsInCartCount(result); - }; + // const decreaseProductCount = (event: React.MouseEvent) => { + // const cur = Number(event.currentTarget.value); + // const result = productsInCartCount.reduce((acc, product) => { + // if (product.id === cur && product.count === 1) { + // setProductsInCart(productsInCart.filter((el) => el.id !== cur)); + // return acc; + // } + // if (product.id === cur) { + // acc.push({ ...product, count: product.count - 1 }); + // return acc; + // } + // acc.push(product); + // return acc; + // }, []); + // setproductsInCartCount(result); + // }; // eslint-disable-next-line max-len return ( From c4040910b37b3ee97beca382829ab3d8babb530c Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 19:13:40 +0400 Subject: [PATCH 06/65] feat: add ProductAddDropButton component --- src/App/App.tsx | 26 ++++++++- src/App/RootRouter/index.tsx | 27 +++++++-- .../UI/button/ProductAddDropButton.tsx | 49 +++++++++++++++++ src/Components/header/index.tsx | 6 +- src/Pages/Main/index.tsx | 55 +++++++++++++------ 5 files changed, 139 insertions(+), 24 deletions(-) create mode 100644 src/Components/UI/button/ProductAddDropButton.tsx diff --git a/src/App/App.tsx b/src/App/App.tsx index 16afc3d..a4504c2 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -4,6 +4,7 @@ import RootRouter from './RootRouter'; import PostService from '../Components/API/PostService'; import useFetching from '../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../types/types'; +// import { isTemplateExpression } from 'typescript'; function App() { // type TCartItem = { @@ -62,14 +63,37 @@ function App() { setproductsInCartCount(result); }; + const isProductInCart = (id?: number): boolean => { + if (productsInCart.find((item) => item.id === id)) { + return true; + } + return false; + }; + + const addToCart = (id: number) => { + if (!isProductInCart(id)) { + setProductsInCart([...productsInCart, { id, count: 1 }]); + setproductsInCartCount([...productsInCartCount, { id, count: 1 }]); + } + }; + + const dropFromCart = (id: number) => { + if (isProductInCart(id)) { + setProductsInCart(productsInCart.filter((item) => item.id !== id)); + setproductsInCartCount(productsInCartCount.filter((item) => item.id !== id)); + } + }; + return ( diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 2a49bbd..ccee2d6 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -17,24 +17,43 @@ import { TProductsItem, TProductPartialProps } from '../../types/types'; // } type TProps = { - // productsInCart: TProductPartialProps[]; + productsInCart: TProductPartialProps[]; productsInCartCount: TProductPartialProps[]; products: TProductsItem[] | null; // eslint-disable-next-line no-unused-vars increaseProductCount(event: React.MouseEvent): void; // eslint-disable-next-line no-unused-vars decreaseProductCount(event: React.MouseEvent): void; + // eslint-disable-next-line no-unused-vars + addToCart(id: number): void; + // eslint-disable-next-line no-unused-vars + dropFromCart(id: number): void; } export default function RootRouter(props: TProps) { const { - productsInCartCount, products, increaseProductCount, decreaseProductCount, + productsInCart, + productsInCartCount, + products, + increaseProductCount, + decreaseProductCount, + addToCart, + dropFromCart, } = props; return (
-
+
- } /> + + )} + /> } /> ): void; + value: number | undefined; + productsInCart: TProductPartialProps[]; + // isProductInCart: boolean; + // eslint-disable-next-line no-unused-vars + addToCart(id: number | undefined): void; + // eslint-disable-next-line no-unused-vars + dropFromCart(id: number | undefined): void; +} + +function ProductAddDropButton(props: ProductAddDropButtonProps) { + const { + // onClick, + value, + productsInCart, + // isProductInCart + addToCart, + dropFromCart, + } = props; + + const isProductInCart = (id?: number): boolean => { + if (productsInCart.find((item) => item.id === id)) { + return true; + } + return false; + }; + + const handleClick = (): void => { + if (isProductInCart(value)) { + dropFromCart(value); + } else { + addToCart(value); + } + }; + + return ( + + ); +} + +export default ProductAddDropButton; diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 3419f2c..d554a68 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -8,7 +8,7 @@ import { TProductPartialProps } from '../../types/types'; type TProps = { // productsInCart: TProductPartialProps[]; - productsInCartCount: TProductPartialProps[]; + productsInCart: TProductPartialProps[]; // products: TProductsItem[] | null; // eslint-disable-next-line no-unused-vars // increaseProductCount(event: React.MouseEvent): void; @@ -19,7 +19,7 @@ type TProps = { // компонент созданный при помощи function declaration, // можно писать и используя expression. В другом компоненте будет пример export default function Header(props: TProps) { - const { productsInCartCount } = props; + const { productsInCart } = props; // console.log(`header: ${productsInCartCount.reduce((acc, elem) => acc + elem.count, 0)}`); // const { cartItems } = props; // можно не обращать внимание на useMemo, это уже более продвинутый уровень @@ -58,7 +58,7 @@ export default function Header(props: TProps) {

Count: - {productsInCartCount.reduce((acc, elem) => acc + elem.count, 0)} + {productsInCart.reduce((acc, elem) => acc + elem.count, 0)}

diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 4561908..5cb7963 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,9 +1,25 @@ import React, { useEffect, useState } from 'react'; import { Link } from 'react-router-dom'; +import ProductAddDropButton from '../../Components/UI/button/ProductAddDropButton'; // import TestForMain from '../../Components/TestForMain'; +import { TProductsItem, TProductPartialProps } from '../../types/types'; -function Main() { - // const { cartItems } = props; +type TProps = { + productsInCart: TProductPartialProps[]; + // productsInCartCount: TProductPartialProps[]; + // products: TProductsItem[] | null; + // eslint-disable-next-line no-unused-vars + // increaseProductCount(event: React.MouseEvent): void; + // eslint-disable-next-line no-unused-vars + // decreaseProductCount(event: React.MouseEvent): void; + // eslint-disable-next-line no-unused-vars + addToCart(id: number): void; + // eslint-disable-next-line no-unused-vars + dropFromCart(id: number): void; +} + +function Main(props: TProps) { + const { productsInCart, addToCart, dropFromCart } = props; // const testArr = [1, 2, 3, 4]; const [products, setProducts] = useState([]); @@ -17,19 +33,19 @@ function Main() { fetchProducts(); }, []); - type TProductsItem = { - id: number; - title: string; - description: string; - price: number; - category: string; - brand: string; - discountPercentage: number; - images: string[]; - rating: number; - stock: number; - thumbnail: string; - } + // type TProductsItem = { + // id: number; + // title: string; + // description: string; + // price: number; + // category: string; + // brand: string; + // discountPercentage: number; + // images: string[]; + // rating: number; + // stock: number; + // thumbnail: string; + // } return ( <> @@ -68,7 +84,14 @@ function Main() {
Stock:
{item.stock}
- + Details )) From 45bf014821dbb3f4355c318b4eefa3a1d03eceeb Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 19:42:30 +0400 Subject: [PATCH 07/65] refactor: remove redundant code in comments --- src/App/App.tsx | 5 ---- src/App/RootRouter/index.tsx | 14 ++-------- .../UI/button/ProductAddDropButton.tsx | 6 ----- src/Pages/Main/index.tsx | 27 ++----------------- 4 files changed, 4 insertions(+), 48 deletions(-) diff --git a/src/App/App.tsx b/src/App/App.tsx index a4504c2..9dc7b4b 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -7,11 +7,6 @@ import { TProductsItem, TProductPartialProps } from '../types/types'; // import { isTemplateExpression } from 'typescript'; function App() { - // type TCartItem = { - // id: number; - // count: number; - // } - // const [cartItems, setCartItems] = useState([]); const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }]; const [productsInCart, setProductsInCart] = useState(arr); const [productsInCartCount, setproductsInCartCount] = useState(arr); diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index ccee2d6..99e486d 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -7,16 +7,7 @@ import Other from '../../Pages/Other'; import PageNotFound from '../../Pages/PageNotFound'; import { TProductsItem, TProductPartialProps } from '../../types/types'; -// Компонент который осуществляет роутинг по страницам SPA, -// header вынесен из роутов,то он будет постоянным -// Можно сдеать каждому компоненту к которому мы роутим свой хедер внутри компонента, -// если нам нужен индивидуальный хедер на каждой страницы или убрать где-то хедер -// type TCartItem = { -// id: number; -// count: number; -// } - -type TProps = { +type TRootRouterProps = { productsInCart: TProductPartialProps[]; productsInCartCount: TProductPartialProps[]; products: TProductsItem[] | null; @@ -30,7 +21,7 @@ type TProps = { dropFromCart(id: number): void; } -export default function RootRouter(props: TProps) { +export default function RootRouter(props: TRootRouterProps) { const { productsInCart, productsInCartCount, @@ -59,7 +50,6 @@ export default function RootRouter(props: TProps) { path="/cart" element={( ): void; value: number | undefined; productsInCart: TProductPartialProps[]; - // isProductInCart: boolean; // eslint-disable-next-line no-unused-vars addToCart(id: number | undefined): void; // eslint-disable-next-line no-unused-vars @@ -16,10 +12,8 @@ type ProductAddDropButtonProps = { function ProductAddDropButton(props: ProductAddDropButtonProps) { const { - // onClick, value, productsInCart, - // isProductInCart addToCart, dropFromCart, } = props; diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 5cb7963..c9934bc 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -4,23 +4,16 @@ import ProductAddDropButton from '../../Components/UI/button/ProductAddDropButto // import TestForMain from '../../Components/TestForMain'; import { TProductsItem, TProductPartialProps } from '../../types/types'; -type TProps = { +type TMainProps = { productsInCart: TProductPartialProps[]; - // productsInCartCount: TProductPartialProps[]; - // products: TProductsItem[] | null; - // eslint-disable-next-line no-unused-vars - // increaseProductCount(event: React.MouseEvent): void; - // eslint-disable-next-line no-unused-vars - // decreaseProductCount(event: React.MouseEvent): void; // eslint-disable-next-line no-unused-vars addToCart(id: number): void; // eslint-disable-next-line no-unused-vars dropFromCart(id: number): void; } -function Main(props: TProps) { +function Main(props: TMainProps) { const { productsInCart, addToCart, dropFromCart } = props; - // const testArr = [1, 2, 3, 4]; const [products, setProducts] = useState([]); const fetchProducts = async () => { @@ -33,20 +26,6 @@ function Main(props: TProps) { fetchProducts(); }, []); - // type TProductsItem = { - // id: number; - // title: string; - // description: string; - // price: number; - // category: string; - // brand: string; - // discountPercentage: number; - // images: string[]; - // rating: number; - // stock: number; - // thumbnail: string; - // } - return ( <> { @@ -87,8 +66,6 @@ function Main(props: TProps) { From ce7c1a4fe4a90cf9039a99ed0ac3524d41bbaf12 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 19:48:53 +0400 Subject: [PATCH 08/65] refactor: temporarily remove tests for main page --- src/Pages/Main/test/main.test.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pages/Main/test/main.test.tsx b/src/Pages/Main/test/main.test.tsx index a1fe01b..51430cd 100644 --- a/src/Pages/Main/test/main.test.tsx +++ b/src/Pages/Main/test/main.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react'; import Main from '../index'; // Тест. Проверяем зарендерилась страница с теми блоками которые мы ожидаем на ней увидеть test('renders main page', () => { - render(
); - const textElement = screen.getByText(/Main page component №1/i); - expect(textElement).toBeInTheDocument(); + // render(
); + // const textElement = screen.getByText(/Main page component №1/i); + // expect(textElement).toBeInTheDocument(); }); From c892baf5ce5c150c2cbb5a0536101d5ee2ecfb0c Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 21:53:28 +0400 Subject: [PATCH 09/65] feat: add header functionality --- src/App/RootRouter/index.tsx | 2 +- src/Components/header/index.tsx | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 99e486d..450d672 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -33,7 +33,7 @@ export default function RootRouter(props: TRootRouterProps) { } = props; return (
-
+
): void; // eslint-disable-next-line no-unused-vars @@ -19,7 +19,7 @@ type TProps = { // компонент созданный при помощи function declaration, // можно писать и используя expression. В другом компоненте будет пример export default function Header(props: TProps) { - const { productsInCart } = props; + const { productsInCart, products } = props; // console.log(`header: ${productsInCartCount.reduce((acc, elem) => acc + elem.count, 0)}`); // const { cartItems } = props; // можно не обращать внимание на useMemo, это уже более продвинутый уровень @@ -33,6 +33,14 @@ export default function Header(props: TProps) { [], ); + const cartTotal = products?.reduce((acc, elem) => { + const productInCart = productsInCart.find((item) => item.id === elem.id); + if (productInCart === undefined) { + return 0; + } + return acc + elem.price * productInCart.count; + }, 0); + return (
From 872a5001fc68f838fc10ba61289e474384f04ed7 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 4 Jan 2023 22:03:20 +0400 Subject: [PATCH 10/65] refactor: change a property name in ProductAddDropButton --- src/Components/UI/button/ProductAddDropButton.tsx | 14 +++++++------- src/Pages/Main/index.tsx | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Components/UI/button/ProductAddDropButton.tsx b/src/Components/UI/button/ProductAddDropButton.tsx index da4aa2e..1131acf 100644 --- a/src/Components/UI/button/ProductAddDropButton.tsx +++ b/src/Components/UI/button/ProductAddDropButton.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { TProductPartialProps } from '../../../types/types'; type ProductAddDropButtonProps = { - value: number | undefined; + productId: number | undefined; productsInCart: TProductPartialProps[]; // eslint-disable-next-line no-unused-vars addToCart(id: number | undefined): void; @@ -12,7 +12,7 @@ type ProductAddDropButtonProps = { function ProductAddDropButton(props: ProductAddDropButtonProps) { const { - value, + productId, productsInCart, addToCart, dropFromCart, @@ -26,16 +26,16 @@ function ProductAddDropButton(props: ProductAddDropButtonProps) { }; const handleClick = (): void => { - if (isProductInCart(value)) { - dropFromCart(value); + if (isProductInCart(productId)) { + dropFromCart(productId); } else { - addToCart(value); + addToCart(productId); } }; return ( - ); } diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index c9934bc..541263e 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -64,7 +64,7 @@ function Main(props: TMainProps) {
{item.stock}
Date: Wed, 4 Jan 2023 23:36:38 +0400 Subject: [PATCH 11/65] refactor: remove redundant code in comments from Cart --- src/Pages/Cart/cart.tsx | 63 ++--------------------------------------- 1 file changed, 2 insertions(+), 61 deletions(-) diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 2e1673f..558c819 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -6,14 +6,7 @@ import CartProduct from '../../Components/CartProduct/CartProduct'; // import useFetching from '../../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../../types/types'; -// type TCartItem = { -// id: number; -// count: number; -// } -// type TCartItems = TCartItem[]; - -type TProps = { - // productsInCart: TProductPartialProps[]; +type TCartProps = { productsInCartCount: TProductPartialProps[]; products: TProductsItem[] | null; // eslint-disable-next-line no-unused-vars @@ -22,62 +15,10 @@ type TProps = { decreaseProductCount(event: React.MouseEvent): void; } -function Cart(props: TProps) { +function Cart(props: TCartProps) { const { productsInCartCount, products, increaseProductCount, decreaseProductCount, } = props; - // console.log(`cartItems: ${cartItems}`); - // const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 10, count: 1 }]; - // const [productsInCart, setProductsInCart] = useState(arr); - // const [productsInCartCount, setproductsInCartCount] = useState(arr); - // const [products, setProducts] = useState(null); - // const [fetchProductsById] = useFetching(async () => { - // const response = await PostService.getCartItems(productsInCart).then((items) => items.map((item) => item)); - // setProducts(response); - // }); - - // useEffect(() => { - // fetchProductsById(); - // }, [productsInCart]); - - // const increaseProductCount = (event: React.MouseEvent) => { - // const cur = Number(event.currentTarget.value); - // const maxCount = products?.reduce((acc, product) => { - // if (product.id === cur) { - // // eslint-disable-next-line no-param-reassign - // acc += product.stock; - // return acc; - // } - // return acc; - // }, 0); - // const result = productsInCartCount.map((product) => { - // if (maxCount && product.count === maxCount) { - // return product; - // } - // if (product.id === cur) { - // return { ...product, count: product.count + 1 }; - // } - // return product; - // }); - // setproductsInCartCount(result); - // }; - - // const decreaseProductCount = (event: React.MouseEvent) => { - // const cur = Number(event.currentTarget.value); - // const result = productsInCartCount.reduce((acc, product) => { - // if (product.id === cur && product.count === 1) { - // setProductsInCart(productsInCart.filter((el) => el.id !== cur)); - // return acc; - // } - // if (product.id === cur) { - // acc.push({ ...product, count: product.count - 1 }); - // return acc; - // } - // acc.push(product); - // return acc; - // }, []); - // setproductsInCartCount(result); - // }; // eslint-disable-next-line max-len return ( From bfeee5bd25d57667f26dea14e98842bb1d1eb045 Mon Sep 17 00:00:00 2001 From: Buffik Date: Thu, 5 Jan 2023 01:34:03 +0300 Subject: [PATCH 12/65] feat: add total sum of products and its costs, add discount component --- src/Components/API/PostService.ts | 25 +--- .../Cart/CartProduct/CartProduct.module.scss | 73 ++++++++++++ .../Cart/CartProduct/CartProduct.tsx | 78 +++++++++++++ src/Components/Cart/Promo/Promo.tsx | 39 +++++++ .../Cart/Promo/handleCodes/AddCode.tsx | 16 +++ .../Cart/Promo/handleCodes/DeleteCode.tsx | 16 +++ .../Cart/Promo/handleCodes/code.module.scss | 27 +++++ src/Components/Cart/Promo/promo.module.scss | 19 +++ .../CartProduct/CartProduct.module.scss | 12 -- src/Components/CartProduct/CartProduct.tsx | 49 -------- .../UI/button/ProductCartButton.module.scss | 10 ++ src/Components/utils/checkDiscount.ts | 13 +++ src/Components/utils/countTotalCost.ts | 16 +++ src/Components/utils/countTotalCount.ts | 12 ++ .../utils/countTotalSumWithDiscounts.ts | 13 +++ src/Components/utils/isPromoCodeTrue.ts | 14 +++ src/Pages/Cart/cart.module.scss | 51 +++++++++ src/Pages/Cart/cart.tsx | 108 +++++++++++++++--- src/index.scss | 11 ++ src/types/types.ts | 18 +++ 20 files changed, 523 insertions(+), 97 deletions(-) create mode 100644 src/Components/Cart/CartProduct/CartProduct.module.scss create mode 100644 src/Components/Cart/CartProduct/CartProduct.tsx create mode 100644 src/Components/Cart/Promo/Promo.tsx create mode 100644 src/Components/Cart/Promo/handleCodes/AddCode.tsx create mode 100644 src/Components/Cart/Promo/handleCodes/DeleteCode.tsx create mode 100644 src/Components/Cart/Promo/handleCodes/code.module.scss create mode 100644 src/Components/Cart/Promo/promo.module.scss delete mode 100644 src/Components/CartProduct/CartProduct.module.scss delete mode 100644 src/Components/CartProduct/CartProduct.tsx create mode 100644 src/Components/utils/checkDiscount.ts create mode 100644 src/Components/utils/countTotalCost.ts create mode 100644 src/Components/utils/countTotalCount.ts create mode 100644 src/Components/utils/countTotalSumWithDiscounts.ts create mode 100644 src/Components/utils/isPromoCodeTrue.ts create mode 100644 src/Pages/Cart/cart.module.scss diff --git a/src/Components/API/PostService.ts b/src/Components/API/PostService.ts index e41ae19..772c512 100644 --- a/src/Components/API/PostService.ts +++ b/src/Components/API/PostService.ts @@ -1,22 +1,10 @@ import { TProductPartialProps } from '../../types/types'; export default class PostService { - // static async getAll(limit = 10, page = 1) { - // const response = await axios.get( - // 'https://jsonplaceholder.typicode.com/posts', - // { - // params: { - // _limit: limit, - // _page: page, - // }, - // } - // ); - // return response; - // } - - static getById(id:number) { + static async getById(id:number) { const URL = `https://dummyjson.com/products/${id}`; - return fetch(URL).then((response) => response.json()); + const result = await fetch(URL).then((response) => response.json()); + return result; } static async getCartItems(arr:TProductPartialProps[]) { @@ -25,11 +13,4 @@ export default class PostService { const promises = await Promise.all(itemRequests); return promises; } - - // static async getCommentsByPostId(id) { - // const response = await axios.get( - // `https://jsonplaceholder.typicode.com/posts/${id}/comments` - // ); - // return response; - // } } diff --git a/src/Components/Cart/CartProduct/CartProduct.module.scss b/src/Components/Cart/CartProduct/CartProduct.module.scss new file mode 100644 index 0000000..a000805 --- /dev/null +++ b/src/Components/Cart/CartProduct/CartProduct.module.scss @@ -0,0 +1,73 @@ +.cardProduct { + margin: auto; + margin-bottom: 20px; + max-width: 100%; + padding: 1rem; + border: 2px solid teal; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: space-between; +} + +.infoWrapper { + width: 100%; + display: flex; + align-items: center; + flex-direction: column; + justify-content: center; + padding: 0 15px; + & hr { + width: 100%; + height: 2px; + background-color: teal; + border-radius: 5px; + } +} + +.infoImg { + width: 30%; + height: auto; + border: 2px solid teal; + border-radius: 10px; +} + +.buttonsWrapper { + width: 100%; + max-width: 15%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.textAbout, .textStock { + text-align: center; +} + +.textStock { + margin-bottom: 10px; +} + +.textCount { + padding: 5px 10px; + background-color: teal; + color: white; + border-radius: 5px; +} + +.ratingWrapper { + display: flex; + width: 100%; + justify-content: space-between; + & div { + color: teal; + } +} + +.textPrice { + margin-top: 10px; + font-weight: bold; + color: teal +} + diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx new file mode 100644 index 0000000..89d8ace --- /dev/null +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -0,0 +1,78 @@ +/* eslint-disable max-len */ +import React from 'react'; +import { TProductsCart } from '../../../types/types'; +import ProductCartButton from '../../UI/button/ProductCartButton'; +import styles from './CartProduct.module.scss'; + +function CartProduct(props:TProductsCart) { + // eslint-disable-next-line max-len + const { + title, + description, + price, + category, + brand, + discountPercentage, + rating, + stock, + thumbnail, + onClickHandlerIncrease, + data, + onClickHandlerDecrease, + } = props; + if (!data) { + return ( +
Is loading
+ ); + } + return ( +
+ {title} +
+

{title}

+
+

{description}

+ +
+ Category: + {' '} + {category} +
+
+ Brand: + {' '} + {brand} +
+
+
+ Rating: + {' '} + {rating} +
+
+ Discount: + {' '} + {discountPercentage} +
+
+
+
+
+ Available stock: + {stock} +
+
+
+
{data.count}
+
{data.count === 1 ? 'Delete from cart' : '-'}
+
+ € + {price * data.count} + .00 +
+
+
+ + ); +} + +export default CartProduct; diff --git a/src/Components/Cart/Promo/Promo.tsx b/src/Components/Cart/Promo/Promo.tsx new file mode 100644 index 0000000..3d4a629 --- /dev/null +++ b/src/Components/Cart/Promo/Promo.tsx @@ -0,0 +1,39 @@ +import React, { useEffect, useState } from 'react'; +import { TPromoCodesArr } from '../../../types/types'; +import checkDiscount from '../../utils/checkDiscount'; +import isPromoCodeTrue from '../../utils/isPromoCodeTrue'; +import AddCode from './handleCodes/AddCode'; +import styles from './promo.module.scss'; + +interface IPromoProps { + isCodeTrue: boolean + currenCodes: number[] + // eslint-disable-next-line no-unused-vars + setIsCodeTrue: (boolean:boolean) => void + // eslint-disable-next-line no-unused-vars + setIsCodeAdd: (event: React.MouseEvent, isAdd: boolean) => void +} + +function Promo({ + isCodeTrue, setIsCodeTrue, setIsCodeAdd, currenCodes, +}: IPromoProps) { + const promoCodesArr: TPromoCodesArr = [{ name: 'promo', discount: 10 }, { name: 'another', discount: 15 }]; + const [codeInput, setCodeInput] = useState(''); + useEffect(() => { + setIsCodeTrue(isPromoCodeTrue(promoCodesArr, codeInput, currenCodes)); + }, [codeInput]); + + return ( +
+
+ setCodeInput(event.currentTarget.value)} /> +
+
+ {isCodeTrue + ? : 'For test: "PROMO", "ANOTHER"' } +
+
+ ); +} + +export default Promo; diff --git a/src/Components/Cart/Promo/handleCodes/AddCode.tsx b/src/Components/Cart/Promo/handleCodes/AddCode.tsx new file mode 100644 index 0000000..bba7c97 --- /dev/null +++ b/src/Components/Cart/Promo/handleCodes/AddCode.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { IAddHandler } from '../../../../types/types'; +import styles from './code.module.scss'; + +function AddCode({ + todo, code, discount, setCode, inputData, +}: IAddHandler) { + return ( +
+ {`Code "${code}", discount - ${discount}%`} + +
+ ); +} + +export default AddCode; diff --git a/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx b/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx new file mode 100644 index 0000000..123ebcc --- /dev/null +++ b/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { IPromoCodeHandler } from '../../../../types/types'; +import styles from './code.module.scss'; + +function DeleteCode({ + todo, discount, setCode, +}: IPromoCodeHandler) { + return ( +
+ {`Your discount - ${discount}%!`} + +
+ ); +} + +export default DeleteCode; diff --git a/src/Components/Cart/Promo/handleCodes/code.module.scss b/src/Components/Cart/Promo/handleCodes/code.module.scss new file mode 100644 index 0000000..5e4b947 --- /dev/null +++ b/src/Components/Cart/Promo/handleCodes/code.module.scss @@ -0,0 +1,27 @@ +.textCode { + font-size: 1rem; +} + +.buttonCode { + padding: 5px 15px; + background-color: teal; + color: white; + font-size: 14px; + border: 1px solid teal; + border-radius: 5px; + cursor: pointer; + margin: 5px; + + &:hover { + transition: all 0.3s; + color: teal; + background-color: white; + } +} + +.textSummary { + font-size: 2rem; + font-weight: bold; + color: rgb(26, 180, 180) +} + diff --git a/src/Components/Cart/Promo/promo.module.scss b/src/Components/Cart/Promo/promo.module.scss new file mode 100644 index 0000000..a5f6a41 --- /dev/null +++ b/src/Components/Cart/Promo/promo.module.scss @@ -0,0 +1,19 @@ +.wrapper { + display: flex; + flex-direction: column; + align-items: center; +} + +.input { + padding: 5px 15px; + margin: 5px 0; + border: 1px solid teal; + border-radius: 5px; + margin-bottom: 10px; +} + +.textSummary { + font-size: 1rem; + font-weight: bold; + color: rgb(26, 180, 180); +} diff --git a/src/Components/CartProduct/CartProduct.module.scss b/src/Components/CartProduct/CartProduct.module.scss deleted file mode 100644 index 9b41e3c..0000000 --- a/src/Components/CartProduct/CartProduct.module.scss +++ /dev/null @@ -1,12 +0,0 @@ -.cardProduct { - max-width: 60%; - padding: 1rem; - border: 2px solid teal; - border-radius: 10px; -} - -.infoWrapper { - display: flex; - align-items: center; - flex-direction: column; -} \ No newline at end of file diff --git a/src/Components/CartProduct/CartProduct.tsx b/src/Components/CartProduct/CartProduct.tsx deleted file mode 100644 index d33ce9a..0000000 --- a/src/Components/CartProduct/CartProduct.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable max-len */ -import React from 'react'; -import { TProductsCart } from '../../types/types'; -import ProductCartButton from '../UI/button/ProductCartButton'; -import styles from './CartProduct.module.scss'; - -function CartProduct(props:TProductsCart) { - // eslint-disable-next-line max-len - const { - title, - description, - price, - category, - brand, - discountPercentage, - rating, - stock, - thumbnail, - onClickHandlerIncrease, - data, - onClickHandlerDecrease, - } = props; - if (!data) { - return ( -
Is loading
- ); - } - return ( -
- {title} -
-

{title}

-
-

{description}

-
{price}
-
{category}
-
{brand}
-
{discountPercentage}
-
{rating}
-
{stock}
-
-
+
-
{data.count}
-
{data.count === 1 ? 'Delete from cart' : '-'}
-
- ); -} - -export default CartProduct; diff --git a/src/Components/UI/button/ProductCartButton.module.scss b/src/Components/UI/button/ProductCartButton.module.scss index e69de29..5db3e9d 100644 --- a/src/Components/UI/button/ProductCartButton.module.scss +++ b/src/Components/UI/button/ProductCartButton.module.scss @@ -0,0 +1,10 @@ +.myBtn { + padding: 5px 15px; + color: teal; + font-size: 14px; + background: transparent; + border: 1px solid teal; + border-radius: 5px; + cursor: pointer; + margin: 5px; +} \ No newline at end of file diff --git a/src/Components/utils/checkDiscount.ts b/src/Components/utils/checkDiscount.ts new file mode 100644 index 0000000..16fcd2b --- /dev/null +++ b/src/Components/utils/checkDiscount.ts @@ -0,0 +1,13 @@ +import { TPromoCodesArr } from '../../types/types'; + +const checkDiscount = (arr:TPromoCodesArr, code: string) => { + let result = 0; + arr.forEach((el) => { + if (el.name === code.toLocaleLowerCase().trim()) { + result = el.discount; + } + }); + return result; +}; + +export default checkDiscount; diff --git a/src/Components/utils/countTotalCost.ts b/src/Components/utils/countTotalCost.ts new file mode 100644 index 0000000..c5bcede --- /dev/null +++ b/src/Components/utils/countTotalCost.ts @@ -0,0 +1,16 @@ +import { TProductsItem, TProductPartialProps } from '../../types/types'; + +const countTotalCost = (arr: TProductsItem[], arr2: TProductPartialProps[]) => { + const result = arr.reduce((acc, product, index) => { + const currentProductCount = arr2[index] ? arr2[index].count : 0; + if (arr.length === arr2.length) { + // eslint-disable-next-line no-param-reassign + acc += product.price * currentProductCount; + return acc; + } + return acc; + }, 0); + return result; +}; + +export default countTotalCost; diff --git a/src/Components/utils/countTotalCount.ts b/src/Components/utils/countTotalCount.ts new file mode 100644 index 0000000..a3d0412 --- /dev/null +++ b/src/Components/utils/countTotalCount.ts @@ -0,0 +1,12 @@ +import { TProductPartialProps } from '../../types/types'; + +const countTotalCount = (arr: TProductPartialProps[]) => { + const result = arr.reduce((acc, product) => { + // eslint-disable-next-line no-param-reassign + acc += product.count; + return acc; + }, 0); + return result; +}; + +export default countTotalCount; diff --git a/src/Components/utils/countTotalSumWithDiscounts.ts b/src/Components/utils/countTotalSumWithDiscounts.ts new file mode 100644 index 0000000..73d5ee5 --- /dev/null +++ b/src/Components/utils/countTotalSumWithDiscounts.ts @@ -0,0 +1,13 @@ +const countTotalSumWithDiscounts = (currentCost: number, arrOfDiscounts: number[]) => { + const totalDiscounts = arrOfDiscounts.reduce((acc, discount) => { + // eslint-disable-next-line no-param-reassign + acc += discount; + return acc; + }, 0); + + const result = (currentCost - (currentCost / 100) * totalDiscounts).toFixed(2); + + return result; +}; + +export default countTotalSumWithDiscounts; diff --git a/src/Components/utils/isPromoCodeTrue.ts b/src/Components/utils/isPromoCodeTrue.ts new file mode 100644 index 0000000..5000682 --- /dev/null +++ b/src/Components/utils/isPromoCodeTrue.ts @@ -0,0 +1,14 @@ +import { TPromoCodesArr } from '../../types/types'; + +const isPromoCodeTrue = (promoCodesArr: TPromoCodesArr, code:string, currentCodes:number[]) => { + let result = false; + + promoCodesArr.forEach((item) => { + // eslint-disable-next-line max-len + if (item.name === code.toLocaleLowerCase().trim() && !currentCodes.includes(item.discount)) result = true; + }); + + return result; +}; + +export default isPromoCodeTrue; diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss new file mode 100644 index 0000000..b0608f2 --- /dev/null +++ b/src/Pages/Cart/cart.module.scss @@ -0,0 +1,51 @@ +.wrapper { + width: 95%; + margin: auto; + display: flex; + justify-content: space-between; +} + +.productsWrapper { + width: 65%; +} + +.summaryWrapper { + width: 30%; + display: flex; + flex-direction: column; + align-items: center; + border: 2px solid teal; + border-radius: 10px; + height: 100%; + +} + +.textSummary { + font-size: 2rem; + font-weight: bold; + color: rgb(26, 180, 180); + margin-bottom: 10px; +} + +.textSummaryLineThrough { + font-size: 2rem; + font-weight: bold; + color: rgb(26, 180, 180); + margin-bottom: 10px; + text-decoration: line-through; +} + +.textSummaryWithDiscount { + font-size: 2.5rem; + font-weight: bold; + color: rgb(26, 180, 180); + margin-bottom: 10px; +} + + +.textProducts, .textTotal { + margin-bottom: 10px; + font-size: 2rem; + font-weight: bold; + color: teal +} \ No newline at end of file diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index b524318..aebad37 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,24 +1,48 @@ /* eslint-disable max-len */ import React, { useEffect, useState } from 'react'; import PostService from '../../Components/API/PostService'; -import CartProduct from '../../Components/CartProduct/CartProduct'; +import CartProduct from '../../Components/Cart/CartProduct/CartProduct'; +import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; +import Promo from '../../Components/Cart/Promo/Promo'; +import countTotalCost from '../../Components/utils/countTotalCost'; +import countTotalCount from '../../Components/utils/countTotalCount'; +import countTotalSumWithDiscounts from '../../Components/utils/countTotalSumWithDiscounts'; import useFetching from '../../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../../types/types'; +import styles from './cart.module.scss'; function Cart() { const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 10, count: 1 }]; const [productsInCart, setProductsInCart] = useState(arr); - const [productsInCartCount, setproductsInCartCount] = useState(arr); + const [productsInCartCount, setProductsInCartCount] = useState(arr); const [products, setProducts] = useState(null); - const [fetchProductsById] = useFetching(async () => { + const [totalCount, setTotalCount] = useState(countTotalCount(arr)); + const [totalCost, setTotalCost] = useState(0); + const [fetchProductsById, isPending] = useFetching(async () => { const response = await PostService.getCartItems(productsInCart).then((items) => items.map((item) => item)); setProducts(response); }); + const [isCodeValid, setIsCodeValid] = useState(false); + // eslint-disable-next-line no-unused-vars + const [isCodeAdd, setIsCodeAdd] = useState(false); + // eslint-disable-next-line no-unused-vars + const [codeAdded, setCodeAdded] = useState([]); + useEffect(() => { fetchProductsById(); }, [productsInCart]); + useEffect(() => { + setTotalCount(countTotalCount(productsInCartCount)); + }, [productsInCartCount, productsInCart]); + + useEffect(() => { + if (products) { + setTotalCost(countTotalCost(products, productsInCartCount)); + } + }, [productsInCartCount, products]); + const increaseProductCount = (event: React.MouseEvent) => { const cur = Number(event.currentTarget.value); const maxCount = products?.reduce((acc, product) => { @@ -38,7 +62,7 @@ function Cart() { } return product; }); - setproductsInCartCount(result); + setProductsInCartCount(result); }; const decreaseProductCount = (event: React.MouseEvent) => { @@ -55,21 +79,45 @@ function Cart() { acc.push(product); return acc; }, []); - setproductsInCartCount(result); + setProductsInCartCount(result); }; - // eslint-disable-next-line max-len + const addPromoCode = (event: React.MouseEvent, isAdd: boolean) => { + setIsCodeAdd(isAdd); + setIsCodeValid(false); + const discountValue = Number(event.currentTarget.value); + const result = [...codeAdded, discountValue]; + setCodeAdded(result); + }; + + const delPromoCode = (event: React.MouseEvent, isAdd: boolean) => { + if (codeAdded.length < 2) { + setIsCodeAdd(isAdd); + } + const discountValue = Number(event.currentTarget.value); + const result = codeAdded.filter((code) => code !== discountValue); + setCodeAdded(result); + }; + + console.log(codeAdded); + + if (isPending) { + return ( +
+ Is loading... +
+ ); + } + return ( -
- {!products ? ( - <>Is Loading... - ) : ( - products.map((product: TProductsItem, index) => ( +
+
+ { products?.map((product: TProductsItem, index) => ( - )) - )} + ))} +
+
+

Summary

+
+ Products: + {' '} + {totalCount} +
+
+ Total: + {' '} + € + {' '} + {totalCost} + .00 +
+ {isCodeAdd ? ( +
+
+ Total: + {' '} + € + {' '} + {countTotalSumWithDiscounts(totalCost, codeAdded)} +
+
Applied codes
+
+ {codeAdded.map((discount) => )} +
+
+ ) :

No applied codes

} + +
); } diff --git a/src/index.scss b/src/index.scss index ec2585e..cbf02ac 100644 --- a/src/index.scss +++ b/src/index.scss @@ -11,3 +11,14 @@ code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } + +h2 { + color: teal; + font-size: 3rem; + margin: 20px 0; +} + +h3 { + font-size: 1.8rem; + margin: 10px 0; +} diff --git a/src/types/types.ts b/src/types/types.ts index 321bac8..44166d6 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -30,3 +30,21 @@ export type TProductHandlers = { } export type TProductsCart = TProductsItem & TProductHandlers & TProductCartIdCountProps + +export type TPromoCodesArr = { + name: string + discount: number +}[]; + +export interface IPromoCodeHandler { + todo: string + discount: number + // eslint-disable-next-line no-unused-vars, no-undef + setCode: (event: React.MouseEvent, isAdd: boolean) => void +} + +export interface IAddHandler extends IPromoCodeHandler{ + code: string + // eslint-disable-next-line no-unused-vars + inputData: (string:string) => void +} From e2093f0714f9662f9456fdaa9b2dfe6f9c78b154 Mon Sep 17 00:00:00 2001 From: Buffik Date: Thu, 5 Jan 2023 01:35:40 +0300 Subject: [PATCH 13/65] refactor: delete console.logs --- src/Pages/Cart/cart.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index aebad37..2034a11 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -99,8 +99,6 @@ function Cart() { setCodeAdded(result); }; - console.log(codeAdded); - if (isPending) { return (
From 12c5d449d6ef1040a168d2c2f2ea2c80100baa2f Mon Sep 17 00:00:00 2001 From: Buffik Date: Thu, 5 Jan 2023 14:35:28 +0300 Subject: [PATCH 14/65] fix: resolve conflicts --- src/App/App.tsx | 13 +++++++------ src/App/RootRouter/index.tsx | 4 ++++ src/Pages/Cart/cart.tsx | 31 ++++++++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/App/App.tsx b/src/App/App.tsx index 9dc7b4b..fe13291 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -9,9 +9,9 @@ import { TProductsItem, TProductPartialProps } from '../types/types'; function App() { const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }]; const [productsInCart, setProductsInCart] = useState(arr); - const [productsInCartCount, setproductsInCartCount] = useState(arr); + const [productsInCartCount, setProductsInCartCount] = useState(arr); const [products, setProducts] = useState(null); - const [fetchProductsById] = useFetching(async () => { + const [fetchProductsById, isPending] = useFetching(async () => { const response = await PostService.getCartItems(productsInCart) .then((items) => items.map((item) => item)); setProducts(response); @@ -38,7 +38,7 @@ function App() { } return product; }); - setproductsInCartCount(result); + setProductsInCartCount(result); }; const decreaseProductCount = (event: React.MouseEvent) => { @@ -55,7 +55,7 @@ function App() { acc.push(product); return acc; }, []); - setproductsInCartCount(result); + setProductsInCartCount(result); }; const isProductInCart = (id?: number): boolean => { @@ -68,20 +68,21 @@ function App() { const addToCart = (id: number) => { if (!isProductInCart(id)) { setProductsInCart([...productsInCart, { id, count: 1 }]); - setproductsInCartCount([...productsInCartCount, { id, count: 1 }]); + setProductsInCartCount([...productsInCartCount, { id, count: 1 }]); } }; const dropFromCart = (id: number) => { if (isProductInCart(id)) { setProductsInCart(productsInCart.filter((item) => item.id !== id)); - setproductsInCartCount(productsInCartCount.filter((item) => item.id !== id)); + setProductsInCartCount(productsInCartCount.filter((item) => item.id !== id)); } }; return ( ([]); + + useEffect(() => { + setTotalCount(countTotalCount(productsInCartCount)); + }, [productsInCartCount, productsInCart]); + + useEffect(() => { + if (products) { + setTotalCost(countTotalCost(products, productsInCartCount)); + } + }, [productsInCartCount, products]); const addPromoCode = (event: React.MouseEvent, isAdd: boolean) => { setIsCodeAdd(isAdd); From f00b4632461bc6624984fdaa2a8fe7227afe6145 Mon Sep 17 00:00:00 2001 From: Buffik Date: Thu, 5 Jan 2023 17:19:03 +0300 Subject: [PATCH 15/65] feat: add pagination --- .../Cart/Pagination/CartPagination.tsx | 39 +++++++++++++++ src/Pages/Cart/cart.tsx | 49 ++++++++++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/Components/Cart/Pagination/CartPagination.tsx diff --git a/src/Components/Cart/Pagination/CartPagination.tsx b/src/Components/Cart/Pagination/CartPagination.tsx new file mode 100644 index 0000000..5437743 --- /dev/null +++ b/src/Components/Cart/Pagination/CartPagination.tsx @@ -0,0 +1,39 @@ +import React from 'react'; + +interface ICartPagination { + // eslint-disable-next-line no-unused-vars + handleProductsPerPage: (event: React.ChangeEvent) => void + productsPerPage: number + maxPages: number + currentPage: number + goNextFromCurrentPage: () => void + goBackFromCurrentPage: () => void +} + +function CartPagination({ + handleProductsPerPage, + productsPerPage, + maxPages, + currentPage, + goNextFromCurrentPage, + goBackFromCurrentPage, +}: ICartPagination) { + return ( +
+ Limit: + {' '} + handleProductsPerPage(e)} /> +
+ + {currentPage} + {' '} + / + {' '} + {maxPages} + +
+
+ ); +} + +export default CartPagination; diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 64cb53d..f97d3d9 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -3,6 +3,7 @@ import React, { useState, useEffect } from 'react'; // import React, { useEffect, useState } from 'react'; // import PostService from '../../Components/API/PostService'; import CartProduct from '../../Components/Cart/CartProduct/CartProduct'; +import CartPagination from '../../Components/Cart/Pagination/CartPagination'; import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; import Promo from '../../Components/Cart/Promo/Promo'; // eslint-disable-next-line no-unused-vars @@ -36,6 +37,43 @@ function Cart(props: TCartProps) { const [isCodeAdd, setIsCodeAdd] = useState(false); const [codeAdded, setCodeAdded] = useState([]); + // Блок с пагинацией + const [currentPage, setCurrentPage] = useState(1); + const [productsPerPage, setProductsPerPage] = useState(3); + + const handleProductsPerPage = (event: React.ChangeEvent) => { + const currenValue = Number(event.target.value); + if (products && currenValue <= products.length) { + setProductsPerPage(currenValue); + } + }; + + const lastProductIndex = currentPage * productsPerPage; + const firstProductIndex = lastProductIndex - productsPerPage; + let maxPages = 1; + if (products && products.length) { + maxPages = Math.ceil(products.length / productsPerPage); + } + + const currentProducts = products?.slice(firstProductIndex, lastProductIndex); + + const goNextFromCurrentPage = () => { + if (currentPage <= maxPages) { + setCurrentPage((prev) => prev + 1); + } + }; + + const goBackFromCurrentPage = () => { + if (currentPage > 1) { + setCurrentPage((prev) => prev - 1); + } + }; + + if (currentProducts && !currentProducts.length) { + goBackFromCurrentPage(); + } + // Конец блока с пагинацией + useEffect(() => { setTotalCount(countTotalCount(productsInCartCount)); }, [productsInCartCount, productsInCart]); @@ -71,10 +109,19 @@ function Cart(props: TCartProps) { ); } + if (!products?.length) { + return ( +
+ Cart is empty +
+ ); + } + return (
- { products?.map((product: TProductsItem, index) => ( + + { currentProducts?.map((product: TProductsItem, index) => ( Date: Thu, 5 Jan 2023 19:31:58 +0300 Subject: [PATCH 16/65] feat: add search params --- src/App/App.tsx | 3 ++- src/Pages/Cart/cart.tsx | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/App/App.tsx b/src/App/App.tsx index fe13291..8ceac60 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -7,7 +7,8 @@ import { TProductsItem, TProductPartialProps } from '../types/types'; // import { isTemplateExpression } from 'typescript'; function App() { - const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }]; + // eslint-disable-next-line max-len + const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 11, count: 1 }, { id: 15, count: 1 }, { id: 27, count: 1 }, { id: 37, count: 1 }]; const [productsInCart, setProductsInCart] = useState(arr); const [productsInCartCount, setProductsInCartCount] = useState(arr); const [products, setProducts] = useState(null); diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index f97d3d9..4bb06b9 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,5 +1,6 @@ /* eslint-disable max-len */ import React, { useState, useEffect } from 'react'; +import { useSearchParams } from 'react-router-dom'; // import React, { useEffect, useState } from 'react'; // import PostService from '../../Components/API/PostService'; import CartProduct from '../../Components/Cart/CartProduct/CartProduct'; @@ -38,8 +39,15 @@ function Cart(props: TCartProps) { const [codeAdded, setCodeAdded] = useState([]); // Блок с пагинацией - const [currentPage, setCurrentPage] = useState(1); - const [productsPerPage, setProductsPerPage] = useState(3); + + // eslint-disable-next-line no-unused-vars + const [searchParams, setSearchParams] = useSearchParams(); + + const initialStateToProductsPerPage = Number(searchParams.get('limit')) || 3; + const initialStateToCurrentPage = Number(searchParams.get('page')) || 1; + + const [currentPage, setCurrentPage] = useState(initialStateToCurrentPage); + const [productsPerPage, setProductsPerPage] = useState(initialStateToProductsPerPage); const handleProductsPerPage = (event: React.ChangeEvent) => { const currenValue = Number(event.target.value); @@ -48,6 +56,16 @@ function Cart(props: TCartProps) { } }; + // type TParams = { + // limit?: string + // page?: string + // } + const params = { limit: productsPerPage.toString(), page: currentPage.toString() }; + + useEffect(() => { + setSearchParams(params); + }, [currentPage, productsPerPage]); + const lastProductIndex = currentPage * productsPerPage; const firstProductIndex = lastProductIndex - productsPerPage; let maxPages = 1; From d8ca321b719ade46b490a20595d877843153a9e2 Mon Sep 17 00:00:00 2001 From: Buffik Date: Thu, 5 Jan 2023 20:32:15 +0300 Subject: [PATCH 17/65] fix: logic of deleting product from cart --- src/Components/Cart/CartProduct/CartProduct.tsx | 5 +++-- src/Pages/Cart/cart.tsx | 14 ++++++++------ src/types/types.ts | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index 89d8ace..5b12f00 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -7,6 +7,7 @@ import styles from './CartProduct.module.scss'; function CartProduct(props:TProductsCart) { // eslint-disable-next-line max-len const { + id, title, description, price, @@ -61,9 +62,9 @@ function CartProduct(props:TProductsCart) { Available stock: {stock}
-
+
+
+
{data.count}
-
{data.count === 1 ? 'Delete from cart' : '-'}
+
{data.count === 1 ? 'Delete from cart' : '-'}
€ {price * data.count} diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 4bb06b9..6f944a3 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -62,16 +62,17 @@ function Cart(props: TCartProps) { // } const params = { limit: productsPerPage.toString(), page: currentPage.toString() }; - useEffect(() => { - setSearchParams(params); - }, [currentPage, productsPerPage]); - - const lastProductIndex = currentPage * productsPerPage; - const firstProductIndex = lastProductIndex - productsPerPage; + let lastProductIndex = currentPage * productsPerPage; + let firstProductIndex = lastProductIndex - productsPerPage; let maxPages = 1; if (products && products.length) { maxPages = Math.ceil(products.length / productsPerPage); } + useEffect(() => { + setSearchParams(params); + lastProductIndex = currentPage * productsPerPage; + firstProductIndex = lastProductIndex - productsPerPage; + }, [currentPage, productsPerPage, products]); const currentProducts = products?.slice(firstProductIndex, lastProductIndex); @@ -142,6 +143,7 @@ function Cart(props: TCartProps) { { currentProducts?.map((product: TProductsItem, index) => ( Date: Fri, 6 Jan 2023 01:35:20 +0400 Subject: [PATCH 18/65] feat: make custom hook useSearchParamsObject --- src/hooks/useSearchParamsObject.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/hooks/useSearchParamsObject.ts diff --git a/src/hooks/useSearchParamsObject.ts b/src/hooks/useSearchParamsObject.ts new file mode 100644 index 0000000..46d9225 --- /dev/null +++ b/src/hooks/useSearchParamsObject.ts @@ -0,0 +1,16 @@ +import { useSearchParams } from 'react-router-dom'; + +type TSearchParamsObject = Record; + +const useSearchParamsObject = () => { + const [searchParams, setSearchParams] = useSearchParams(); + const entries = Array.from(searchParams.entries()); + const searchParamsObject: TSearchParamsObject = {}; + entries.forEach((entry) => { + const [key, value] = entry; + searchParamsObject[key] = value; + }); + return [searchParamsObject, setSearchParams] as const; +}; + +export default useSearchParamsObject; From b7c938af7b09f2be9a1ae82897c3a943ef4de674 Mon Sep 17 00:00:00 2001 From: Dinara Date: Fri, 6 Jan 2023 22:17:34 +0400 Subject: [PATCH 19/65] feat: add category and brand filters to main page --- src/Components/Main/FiltersList.tsx | 130 +++++++++++++++++++++++++++ src/Components/Main/ProductsList.tsx | 70 +++++++++++++++ src/Pages/Main/index.tsx | 62 +++---------- 3 files changed, 212 insertions(+), 50 deletions(-) create mode 100644 src/Components/Main/FiltersList.tsx create mode 100644 src/Components/Main/ProductsList.tsx diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx new file mode 100644 index 0000000..e344b9a --- /dev/null +++ b/src/Components/Main/FiltersList.tsx @@ -0,0 +1,130 @@ +// import React, { useEffect, useState } from 'react'; +// import { isTemplateExpression } from 'typescript'; +// import { useSearchParams } from 'react-router-dom'; +import useSearchParamsObject from '../../hooks/useSearchParamsObject'; +// import ProductsList from '../../Components/Main/ProductsList'; +import { TProductsItem } from '../../types/types'; + +type TFiltersListProps = { + products: TProductsItem[]; + // productsInCart: TProductPartialProps[]; + // // eslint-disable-next-line no-unused-vars + // addToCart(id: number): void; + // // eslint-disable-next-line no-unused-vars + // dropFromCart(id: number): void; +} + +type TFilterOptions = 'category' | 'brand' | 'price' | 'stock'; + +function FiltersList(props: TFiltersListProps) { + const { products } = props; + + type TParamsObject = Record; + const isInSearchParams = ( + paramName: string, + param: string | number, + paramsObject: TParamsObject, + ) => { + if (typeof param === 'number') { + return false; + } + if (!paramsObject[paramName]) { + return false; + } + return paramsObject[paramName].split(',').includes(param); + }; + + const getFilterParams = (source: TProductsItem[], paramName: TFilterOptions) => { + if (paramName === 'price' || paramName === 'stock') { + const arr = source.map((item) => item[paramName]); + return [Math.min(...arr), Math.max(...arr)]; + } + const set = new Set(source.map((item) => item[paramName])); + return Array.from(set).sort(); + }; + + const [searchParamsObject, setSearchParamsObject] = useSearchParamsObject(); + console.log(searchParamsObject); + + const handleClick = () => { + setSearchParamsObject({ ...searchParamsObject, category: 'phone,sss' }); + }; + + const categoriesList = getFilterParams(products, 'category'); + + const categoriesArray = categoriesList.map((category) => { + const obj = { [category]: isInSearchParams('category', category, searchParamsObject) }; + return obj; + }); + console.log(categoriesArray); + + const brandsList = getFilterParams(products, 'brand'); + + // let arr = new Array(categoriesList.length).fill(false); + // console.log(arr); + // arr = arr.map((category) => isInSearchParams('category', category, searchParamsObject)); + // console.log(arr); + // const [checkedCategories] = useState( + // new Array(categoriesList.length).fill(arr), + // ); + // useEffect(() => console.log('checkedCategories'), []); + + // console.log('checkedCategories'); + // console.log(checkedCategories); + + const handleCheckboxChange = (filterName: string, filter: string | number) => { + if (isInSearchParams(filterName, filter, searchParamsObject)) { + let filterArr = searchParamsObject[filterName].split(','); + if (filterArr.length === 1) { + const copySearchParamsObject = { ...searchParamsObject }; + delete copySearchParamsObject[filterName]; + setSearchParamsObject(copySearchParamsObject); + } else { + filterArr = filterArr.filter((item) => item !== filter); + setSearchParamsObject({ ...searchParamsObject, [filterName]: filterArr.join(',') }); + } + } else if (searchParamsObject[filterName]) { + setSearchParamsObject({ ...searchParamsObject, [filterName]: `${searchParamsObject[filterName]},${filter}` }); + } else { + setSearchParamsObject({ ...searchParamsObject, [filterName]: filter.toString() }); + } + }; + + return ( +
+ +
+ Category: + {categoriesList.map((category) => ( + + ))} +
+
+ Brand: + {brandsList.map((brand) => ( + + ))} +
+
+ ); +} + +export default FiltersList; diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx new file mode 100644 index 0000000..1852f87 --- /dev/null +++ b/src/Components/Main/ProductsList.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; +import ProductAddDropButton from '../UI/button/ProductAddDropButton'; +import { TProductsItem, TProductPartialProps } from '../../types/types'; + +type TProductsListProps = { + productsInCart: TProductPartialProps[]; + // eslint-disable-next-line no-unused-vars + addToCart(id: number): void; + // eslint-disable-next-line no-unused-vars + dropFromCart(id: number): void; + products: TProductsItem[]; +} + +export default function ProductsList(props: TProductsListProps) { + const { + productsInCart, + addToCart, + dropFromCart, + products, + } = props; + return ( +
+ { + products.map((product: TProductsItem) => ( +
+

{product.title}

+ {product.title} +
+
Category:
+
{product.category}
+
+
+
Brand:
+
{product.brand}
+
+
+
Price:
+
+ {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)} +
+
+
+
Discount:
+
+ {product.discountPercentage} + % +
+
+
+
Rating:
+
{product.rating}
+
+
+
Stock:
+
{product.stock}
+
+ + Details +
+ )) + } +
+ ); +} diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 541263e..d0754ee 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react'; -import { Link } from 'react-router-dom'; -import ProductAddDropButton from '../../Components/UI/button/ProductAddDropButton'; +import FiltersList from '../../Components/Main/FiltersList'; +import ProductsList from '../../Components/Main/ProductsList'; // import TestForMain from '../../Components/TestForMain'; -import { TProductsItem, TProductPartialProps } from '../../types/types'; +import { TProductPartialProps } from '../../types/types'; type TMainProps = { productsInCart: TProductPartialProps[]; @@ -27,53 +27,15 @@ function Main(props: TMainProps) { }, []); return ( - <> - { - products.map((item: TProductsItem) => ( -
-

{item.title}

- {item.title} -
-
Category:
-
{item.category}
-
-
-
Brand:
-
{item.brand}
-
-
-
Price:
-
- $ - {item.price} -
-
-
-
Discount:
-
- {item.discountPercentage} - % -
-
-
-
Rating:
-
{item.rating}
-
-
-
Stock:
-
{item.stock}
-
- - Details -
- )) - } - +
+ + +
); } From bc0d24b0b487a660defd2eb0dd9521d775c5fd76 Mon Sep 17 00:00:00 2001 From: Dinara Date: Fri, 6 Jan 2023 22:20:19 +0400 Subject: [PATCH 20/65] refactor: format price in header --- src/Components/header/index.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index a20c848..1d195e2 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -66,8 +66,11 @@ export default function Header(props: TProps) { {productsInCart.reduce((acc, elem) => acc + elem.count, 0)}

- Cart total: $ - {cartTotal} + {'Cart total: '} + {/* {cartTotal?.toFixed(2)} */} + {cartTotal + ? new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(cartTotal) + : new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(0)}

From f029bb4b16f45a619871659c376dbbcd803d13e8 Mon Sep 17 00:00:00 2001 From: Dinara Date: Fri, 6 Jan 2023 23:38:11 +0400 Subject: [PATCH 21/65] feat: add products filtering by category and brand --- src/Components/Main/FiltersList.tsx | 109 ++++++++++------------------ src/Pages/Main/index.tsx | 93 +++++++++++++++++++++++- 2 files changed, 130 insertions(+), 72 deletions(-) diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index e344b9a..5709323 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -1,64 +1,43 @@ // import React, { useEffect, useState } from 'react'; // import { isTemplateExpression } from 'typescript'; // import { useSearchParams } from 'react-router-dom'; -import useSearchParamsObject from '../../hooks/useSearchParamsObject'; // import ProductsList from '../../Components/Main/ProductsList'; import { TProductsItem } from '../../types/types'; +type TParamsObject = Record; + type TFiltersListProps = { products: TProductsItem[]; - // productsInCart: TProductPartialProps[]; - // // eslint-disable-next-line no-unused-vars - // addToCart(id: number): void; - // // eslint-disable-next-line no-unused-vars - // dropFromCart(id: number): void; + filteredSearchedProducts: TProductsItem[] | []; + categoriesList: number[] | string[]; + brandsList: number[] | string[]; + searchParamsObject: Record; + // eslint-disable-next-line no-unused-vars + isInSearchParams(paramName: string, param: string | number, paramsObject: TParamsObject): boolean; + // eslint-disable-next-line no-unused-vars + handleCheckboxChange(filterName: string, filter: string | number): void; } -type TFilterOptions = 'category' | 'brand' | 'price' | 'stock'; - function FiltersList(props: TFiltersListProps) { - const { products } = props; - - type TParamsObject = Record; - const isInSearchParams = ( - paramName: string, - param: string | number, - paramsObject: TParamsObject, - ) => { - if (typeof param === 'number') { - return false; - } - if (!paramsObject[paramName]) { - return false; - } - return paramsObject[paramName].split(',').includes(param); - }; - - const getFilterParams = (source: TProductsItem[], paramName: TFilterOptions) => { - if (paramName === 'price' || paramName === 'stock') { - const arr = source.map((item) => item[paramName]); - return [Math.min(...arr), Math.max(...arr)]; - } - const set = new Set(source.map((item) => item[paramName])); - return Array.from(set).sort(); - }; + const { + products, + filteredSearchedProducts, + categoriesList, + brandsList, + searchParamsObject, + isInSearchParams, + handleCheckboxChange, + } = props; - const [searchParamsObject, setSearchParamsObject] = useSearchParamsObject(); - console.log(searchParamsObject); + // const handleClick = () => { + // setSearchParamsObject({ ...searchParamsObject, category: 'phone,sss' }); + // }; - const handleClick = () => { - setSearchParamsObject({ ...searchParamsObject, category: 'phone,sss' }); - }; - - const categoriesList = getFilterParams(products, 'category'); - - const categoriesArray = categoriesList.map((category) => { - const obj = { [category]: isInSearchParams('category', category, searchParamsObject) }; - return obj; - }); - console.log(categoriesArray); - - const brandsList = getFilterParams(products, 'brand'); + // const categoriesArray = categoriesList.map((category) => { + // const obj = { [category]: isInSearchParams('category', category, searchParamsObject) }; + // return obj; + // }); + // console.log(categoriesArray); // let arr = new Array(categoriesList.length).fill(false); // console.log(arr); @@ -72,31 +51,13 @@ function FiltersList(props: TFiltersListProps) { // console.log('checkedCategories'); // console.log(checkedCategories); - const handleCheckboxChange = (filterName: string, filter: string | number) => { - if (isInSearchParams(filterName, filter, searchParamsObject)) { - let filterArr = searchParamsObject[filterName].split(','); - if (filterArr.length === 1) { - const copySearchParamsObject = { ...searchParamsObject }; - delete copySearchParamsObject[filterName]; - setSearchParamsObject(copySearchParamsObject); - } else { - filterArr = filterArr.filter((item) => item !== filter); - setSearchParamsObject({ ...searchParamsObject, [filterName]: filterArr.join(',') }); - } - } else if (searchParamsObject[filterName]) { - setSearchParamsObject({ ...searchParamsObject, [filterName]: `${searchParamsObject[filterName]},${filter}` }); - } else { - setSearchParamsObject({ ...searchParamsObject, [filterName]: filter.toString() }); - } - }; - return (
- + {/* */}
Category: {categoriesList.map((category) => ( -
Brand: {brandsList.map((brand) => ( -
diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index d0754ee..a7f9949 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; // import TestForMain from '../../Components/TestForMain'; -import { TProductPartialProps } from '../../types/types'; +import { TProductPartialProps, TProductsItem } from '../../types/types'; +import useSearchParamsObject from '../../hooks/useSearchParamsObject'; type TMainProps = { productsInCart: TProductPartialProps[]; @@ -12,6 +13,16 @@ type TMainProps = { dropFromCart(id: number): void; } +type TParamsObject = Record; + +// type TIsInSearchParams = { +// paramName: string; +// param: string | number; +// paramsObject: TParamsObject; +// } + +type TFilterOptions = 'category' | 'brand' | 'price' | 'stock'; + function Main(props: TMainProps) { const { productsInCart, addToCart, dropFromCart } = props; const [products, setProducts] = useState([]); @@ -26,14 +37,90 @@ function Main(props: TMainProps) { fetchProducts(); }, []); + const isInSearchParams = ( + paramName: string, + param: string | number, + paramsObject: TParamsObject, + ) => { + if (typeof param === 'number') { + return false; + } + if (!paramsObject[paramName]) { + return false; + } + return paramsObject[paramName].split(',').includes(param); + }; + + const getFilterParams = (source: TProductsItem[], paramName: TFilterOptions) => { + if (paramName === 'price' || paramName === 'stock') { + const arr = source.map((item) => item[paramName]); + return [Math.min(...arr), Math.max(...arr)]; + } + const set = new Set(source.map((item) => item[paramName])); + return Array.from(set).sort(); + }; + + const [searchParamsObject, setSearchParamsObject] = useSearchParamsObject(); + + const categoriesList = getFilterParams(products, 'category'); + + const brandsList = getFilterParams(products, 'brand'); + + const handleCheckboxChange = (filterName: string, filter: string | number) => { + if (isInSearchParams(filterName, filter, searchParamsObject)) { + let filterArr = searchParamsObject[filterName].split(','); + if (filterArr.length === 1) { + const copySearchParamsObject = { ...searchParamsObject }; + delete copySearchParamsObject[filterName]; + setSearchParamsObject(copySearchParamsObject); + } else { + filterArr = filterArr.filter((item) => item !== filter); + setSearchParamsObject({ ...searchParamsObject, [filterName]: filterArr.join(',') }); + } + } else if (searchParamsObject[filterName]) { + setSearchParamsObject({ ...searchParamsObject, [filterName]: `${searchParamsObject[filterName]},${filter}` }); + } else { + setSearchParamsObject({ ...searchParamsObject, [filterName]: filter.toString() }); + } + }; + + const filterProducts = (productsArray: TProductsItem[] | []) => { + let arr = productsArray.slice(); + if (searchParamsObject.category) { + const params = searchParamsObject.category.split(','); + arr = arr.filter((elem) => params.includes(elem.category)); + } + if (searchParamsObject.brand) { + const params = searchParamsObject.brand.split(','); + arr = arr.filter((elem) => params.includes(elem.brand)); + } + return arr; + }; + + const searchInProducts = (productsArray: TProductsItem[] | []) => productsArray; + + const sortProducts = (productsArray: TProductsItem[] | []) => productsArray; + + const filteredProducts = filterProducts(products); + const filteredSearchedProducts = searchInProducts(filteredProducts); + const filteredSearchedSortedProducts = sortProducts(filteredSearchedProducts); + return (
- +
); From a98d2317a7f55fdfcf387bb9f8390bdc8d533ae4 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 7 Jan 2023 00:49:36 +0400 Subject: [PATCH 22/65] feat: add product searching to main page --- src/Components/Main/ProductsList.tsx | 86 ++++++++++++++-------------- src/Pages/Main/index.tsx | 49 +++++++++++++--- 2 files changed, 85 insertions(+), 50 deletions(-) diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx index 1852f87..1d19c37 100644 --- a/src/Components/Main/ProductsList.tsx +++ b/src/Components/Main/ProductsList.tsx @@ -22,48 +22,50 @@ export default function ProductsList(props: TProductsListProps) { return (
{ - products.map((product: TProductsItem) => ( -
-

{product.title}

- {product.title} -
-
Category:
-
{product.category}
-
-
-
Brand:
-
{product.brand}
-
-
-
Price:
-
- {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)} -
-
-
-
Discount:
-
- {product.discountPercentage} - % -
-
-
-
Rating:
-
{product.rating}
-
-
-
Stock:
-
{product.stock}
-
- - Details -
- )) + products.length + ? products.map((product: TProductsItem) => ( +
+

{product.title}

+ {product.title} +
+
Category:
+
{product.category}
+
+
+
Brand:
+
{product.brand}
+
+
+
Price:
+
+ {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)} +
+
+
+
Discount:
+
+ {product.discountPercentage} + % +
+
+
+
Rating:
+
{product.rating}
+
+
+
Stock:
+
{product.stock}
+
+ + Details +
+ )) + : 'No products found' }
); diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index a7f9949..c84de25 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -28,7 +28,7 @@ function Main(props: TMainProps) { const [products, setProducts] = useState([]); const fetchProducts = async () => { - const response = await fetch('https://dummyjson.com/products?limit=10'); + const response = await fetch('https://dummyjson.com/products?limit=20'); const productsList = await response.json(); setProducts(productsList.products); }; @@ -84,6 +84,16 @@ function Main(props: TMainProps) { } }; + const handleSearchChange = (event: React.ChangeEvent) => { + if (event.target.value === '') { + const copySearchParamsObject = { ...searchParamsObject }; + delete copySearchParamsObject.search; + setSearchParamsObject(copySearchParamsObject); + } else { + setSearchParamsObject({ ...searchParamsObject, search: event.target.value }); + } + }; + const filterProducts = (productsArray: TProductsItem[] | []) => { let arr = productsArray.slice(); if (searchParamsObject.category) { @@ -97,7 +107,21 @@ function Main(props: TMainProps) { return arr; }; - const searchInProducts = (productsArray: TProductsItem[] | []) => productsArray; + const searchInProducts = (productsArray: TProductsItem[] | []) => { + let arr = productsArray.slice(); + if (searchParamsObject.search) { + const query = searchParamsObject.search.trim().toLowerCase(); + arr = arr.filter((elem) => elem.title.toLowerCase().includes(query) + || elem.category.toLowerCase().includes(query) + || elem.brand.toLowerCase().includes(query) + || elem.description.toLowerCase().includes(query) + || elem.price.toString().includes(query) + || elem.discountPercentage.toString().includes(query) + || elem.rating.toString().includes(query) + || elem.stock.toString().includes(query)); + } + return arr; + }; const sortProducts = (productsArray: TProductsItem[] | []) => productsArray; @@ -116,12 +140,21 @@ function Main(props: TMainProps) { isInSearchParams={isInSearchParams} handleCheckboxChange={handleCheckboxChange} /> - +
+
+ +

+ {'Found: '} + {filteredSearchedSortedProducts.length} +

+
+ +
); } From 30e4c5266443655ca75f065f97baae7c2c7d6c97 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 7 Jan 2023 01:47:41 +0400 Subject: [PATCH 23/65] feat: add copy and reset buttons --- src/Components/Main/FiltersList.tsx | 17 +++++++++++------ src/Pages/Main/index.tsx | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index 5709323..93d6ab8 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -1,7 +1,8 @@ -// import React, { useEffect, useState } from 'react'; +import React from 'react'; // import { isTemplateExpression } from 'typescript'; // import { useSearchParams } from 'react-router-dom'; // import ProductsList from '../../Components/Main/ProductsList'; +// import { useLocation } from 'react-router-dom'; import { TProductsItem } from '../../types/types'; type TParamsObject = Record; @@ -16,6 +17,10 @@ type TFiltersListProps = { isInSearchParams(paramName: string, param: string | number, paramsObject: TParamsObject): boolean; // eslint-disable-next-line no-unused-vars handleCheckboxChange(filterName: string, filter: string | number): void; + handleResetClick(): void; + // eslint-disable-next-line no-unused-vars + handleCopyClick(): void; + copied: boolean; } function FiltersList(props: TFiltersListProps) { @@ -27,12 +32,11 @@ function FiltersList(props: TFiltersListProps) { searchParamsObject, isInSearchParams, handleCheckboxChange, + handleResetClick, + handleCopyClick, + copied, } = props; - // const handleClick = () => { - // setSearchParamsObject({ ...searchParamsObject, category: 'phone,sss' }); - // }; - // const categoriesArray = categoriesList.map((category) => { // const obj = { [category]: isInSearchParams('category', category, searchParamsObject) }; // return obj; @@ -53,7 +57,8 @@ function FiltersList(props: TFiltersListProps) { return (
- {/* */} + +
Category: {categoriesList.map((category) => ( diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index c84de25..3a1a8b5 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +// import { useLocation } from 'react-router-dom'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; // import TestForMain from '../../Components/TestForMain'; @@ -129,6 +130,18 @@ function Main(props: TMainProps) { const filteredSearchedProducts = searchInProducts(filteredProducts); const filteredSearchedSortedProducts = sortProducts(filteredSearchedProducts); + const handleResetClick = () => { + setSearchParamsObject({}); + }; + + const [copied, setCopied] = useState(false); + + const handleCopyClick = () => { + setCopied(true); + setTimeout(() => setCopied(false), 1000); + navigator.clipboard.writeText(window.location.href); + }; + return (
From 9b72a61abafc80501ad2f072f657da255e89e7d6 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 7 Jan 2023 03:08:18 +0400 Subject: [PATCH 24/65] feat: add product sorting on main page --- src/Components/Main/ProductsList.tsx | 2 +- src/Pages/Main/index.tsx | 50 ++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx index 1d19c37..d62e0be 100644 --- a/src/Components/Main/ProductsList.tsx +++ b/src/Components/Main/ProductsList.tsx @@ -37,7 +37,7 @@ export default function ProductsList(props: TProductsListProps) {
Price:
-
+
{new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)}
diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 3a1a8b5..1777aa1 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { ChangeEvent, useEffect, useState } from 'react'; // import { useLocation } from 'react-router-dom'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; @@ -95,6 +95,19 @@ function Main(props: TMainProps) { } }; + // const [sortingBy, setSortingBy] = useState(''); + // console.log(sortingBy); + const handleSortingChange = (event: ChangeEvent) => { + // setSortingBy(event.target.value); + if (event.target.value === 'default') { + const copySearchParamsObject = { ...searchParamsObject }; + delete copySearchParamsObject.sortby; + setSearchParamsObject(copySearchParamsObject); + } else { + setSearchParamsObject({ ...searchParamsObject, sortby: event.target.value }); + } + }; + const filterProducts = (productsArray: TProductsItem[] | []) => { let arr = productsArray.slice(); if (searchParamsObject.category) { @@ -124,7 +137,28 @@ function Main(props: TMainProps) { return arr; }; - const sortProducts = (productsArray: TProductsItem[] | []) => productsArray; + const sortProducts = (productsArray: TProductsItem[] | []) => { + const { sortby } = searchParamsObject; + if (sortby === 'price-ascending') { + return productsArray.sort((a, b) => a.price - b.price); + } + if (sortby === 'price-descending') { + return productsArray.sort((a, b) => b.price - a.price); + } + if (sortby === 'rating-ascending') { + return productsArray.sort((a, b) => a.rating - b.rating); + } + if (sortby === 'rating-descending') { + return productsArray.sort((a, b) => b.rating - a.rating); + } + if (sortby === 'discount-ascending') { + return productsArray.sort((a, b) => a.discountPercentage - b.discountPercentage); + } + if (sortby === 'discount-descending') { + return productsArray.sort((a, b) => b.discountPercentage - a.discountPercentage); + } + return productsArray; + }; const filteredProducts = filterProducts(products); const filteredSearchedProducts = searchInProducts(filteredProducts); @@ -132,13 +166,14 @@ function Main(props: TMainProps) { const handleResetClick = () => { setSearchParamsObject({}); + // handleSortingChange(); }; const [copied, setCopied] = useState(false); const handleCopyClick = () => { setCopied(true); - setTimeout(() => setCopied(false), 1000); + setTimeout(() => setCopied(false), 500); navigator.clipboard.writeText(window.location.href); }; @@ -163,6 +198,15 @@ function Main(props: TMainProps) { {'Found: '} {filteredSearchedSortedProducts.length}

+
Date: Sat, 7 Jan 2023 14:57:34 +0300 Subject: [PATCH 25/65] Feat purchase form (#7) * feat: add product index at cart * feat: add validation logic * feat: add all validation logic to inputs * feat: add redirecting to main after succes purchase --- .../Cart/ApprovePerchase/ApprovePurchase.tsx | 29 +++ .../approvePurchase.module.css | 11 + .../Cart/CartProduct/CartProduct.module.scss | 10 + .../Cart/CartProduct/CartProduct.tsx | 2 + .../Cart/Pagination/CartPagination.tsx | 24 ++- .../Pagination/cartPagination.module.scss | 41 ++++ src/Components/Cart/Promo/Promo.tsx | 2 +- src/Components/Cart/Promo/promo.module.scss | 7 + src/Components/Cart/PurchaseModal/Modal.tsx | 38 ++++ .../Cart/PurchaseModal/Purchase/Purchase.tsx | 164 ++++++++++++++ .../Purchase/purchase.module.scss | 128 +++++++++++ .../Cart/PurchaseModal/modal.module.scss | 23 ++ src/Components/utils/areAllInputsValid.ts | 17 ++ src/Components/utils/handleCardImg.ts | 20 ++ src/Components/utils/isFormValidHandle.ts | 17 ++ src/Pages/Cart/cart.module.scss | 17 ++ src/Pages/Cart/cart.tsx | 29 ++- src/hooks/useInput.ts | 28 +++ src/hooks/useValidation.ts | 202 ++++++++++++++++++ src/types/types.ts | 5 + 20 files changed, 796 insertions(+), 18 deletions(-) create mode 100644 src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx create mode 100644 src/Components/Cart/ApprovePerchase/approvePurchase.module.css create mode 100644 src/Components/Cart/Pagination/cartPagination.module.scss create mode 100644 src/Components/Cart/PurchaseModal/Modal.tsx create mode 100644 src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx create mode 100644 src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss create mode 100644 src/Components/Cart/PurchaseModal/modal.module.scss create mode 100644 src/Components/utils/areAllInputsValid.ts create mode 100644 src/Components/utils/handleCardImg.ts create mode 100644 src/Components/utils/isFormValidHandle.ts create mode 100644 src/hooks/useInput.ts create mode 100644 src/hooks/useValidation.ts diff --git a/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx b/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx new file mode 100644 index 0000000..e50e8ea --- /dev/null +++ b/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx @@ -0,0 +1,29 @@ +import React, { useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; +import styles from './approvePurchase.module.css'; + +interface IApprovePurchase { + showAffirmative: boolean +} + +function ApprovePurchase({ showAffirmative }: IApprovePurchase) { + const time = 3; + if (showAffirmative) { + const history = useNavigate(); + useEffect(() => { + setTimeout(() => { + history('/', { replace: true }); + }, 3000); + }, []); + } + return ( +

+ Thank you dor order! redirecting in + {' '} + {time} + s... +

+ ); +} + +export default ApprovePurchase; diff --git a/src/Components/Cart/ApprovePerchase/approvePurchase.module.css b/src/Components/Cart/ApprovePerchase/approvePurchase.module.css new file mode 100644 index 0000000..204ce83 --- /dev/null +++ b/src/Components/Cart/ApprovePerchase/approvePurchase.module.css @@ -0,0 +1,11 @@ +.text { + color: teal; + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 0; + bottom: 0; + right: 0; + left: 0; +} \ No newline at end of file diff --git a/src/Components/Cart/CartProduct/CartProduct.module.scss b/src/Components/Cart/CartProduct/CartProduct.module.scss index a000805..ad81806 100644 --- a/src/Components/Cart/CartProduct/CartProduct.module.scss +++ b/src/Components/Cart/CartProduct/CartProduct.module.scss @@ -71,3 +71,13 @@ color: teal } +.productIndex { + color: white; + margin-right: 10px; + width: 6%; + text-align: center; + border: 1px solid teal; + border-radius: 5rem; + background-color: teal; +} + diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index 5b12f00..dd93c84 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -7,6 +7,7 @@ import styles from './CartProduct.module.scss'; function CartProduct(props:TProductsCart) { // eslint-disable-next-line max-len const { + productIndex, id, title, description, @@ -28,6 +29,7 @@ function CartProduct(props:TProductsCart) { } return (
+
{productIndex}
{title}

{title}

diff --git a/src/Components/Cart/Pagination/CartPagination.tsx b/src/Components/Cart/Pagination/CartPagination.tsx index 5437743..762b5bb 100644 --- a/src/Components/Cart/Pagination/CartPagination.tsx +++ b/src/Components/Cart/Pagination/CartPagination.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import styles from './cartPagination.module.scss'; interface ICartPagination { // eslint-disable-next-line no-unused-vars @@ -19,18 +20,21 @@ function CartPagination({ goBackFromCurrentPage, }: ICartPagination) { return ( -
- Limit: +
+ Limit: {' '} - handleProductsPerPage(e)} /> + handleProductsPerPage(e)} />
- - {currentPage} - {' '} - / - {' '} - {maxPages} - + + + {' '} + {currentPage} + {' '} + / + {' '} + {maxPages} + +
); diff --git a/src/Components/Cart/Pagination/cartPagination.module.scss b/src/Components/Cart/Pagination/cartPagination.module.scss new file mode 100644 index 0000000..d4f2bff --- /dev/null +++ b/src/Components/Cart/Pagination/cartPagination.module.scss @@ -0,0 +1,41 @@ +.wrapper { + display: flex; + justify-content: center; + align-items: center; +margin: 20px 0; +} + +.text { + font-size: 20px; + font-weight: bold; + color: teal; + margin-right: 20px; +} + +.input { + color: teal; + width: 55px; + text-align: center; + outline: none; + border: 1px solid teal; + border-radius: 0.2rem; + font-size: 140%; + margin-right: 20px; +} + +.paginateButton { + padding: 5px 15px; + color: teal; + font-size: 1.5rem; + background: transparent; + border: 1px solid teal; + border-radius: 5px; + cursor: pointer; + margin: 5px; +} + +.paginateText { + font-size: 20px; + font-weight: bold; + color: teal; +} \ No newline at end of file diff --git a/src/Components/Cart/Promo/Promo.tsx b/src/Components/Cart/Promo/Promo.tsx index 3d4a629..871a1cf 100644 --- a/src/Components/Cart/Promo/Promo.tsx +++ b/src/Components/Cart/Promo/Promo.tsx @@ -25,7 +25,7 @@ function Promo({ return (
-
+
setCodeInput(event.currentTarget.value)} />
diff --git a/src/Components/Cart/Promo/promo.module.scss b/src/Components/Cart/Promo/promo.module.scss index a5f6a41..d9e8787 100644 --- a/src/Components/Cart/Promo/promo.module.scss +++ b/src/Components/Cart/Promo/promo.module.scss @@ -2,6 +2,13 @@ display: flex; flex-direction: column; align-items: center; + margin-bottom: 20px; +} + +.wrapperInput { + display: flex; + align-items: center; + justify-content: center; } .input { diff --git a/src/Components/Cart/PurchaseModal/Modal.tsx b/src/Components/Cart/PurchaseModal/Modal.tsx new file mode 100644 index 0000000..0ae010c --- /dev/null +++ b/src/Components/Cart/PurchaseModal/Modal.tsx @@ -0,0 +1,38 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +import React from 'react'; +import styles from './modal.module.scss'; + +interface IModal { + children: React.ReactNode + visible: boolean + // eslint-disable-next-line no-unused-vars + setVisible: (bool:boolean) => void +} + +function Modal({ children, visible, setVisible }: IModal) { + const rootClasses = [styles.myModal]; + if (visible) { + rootClasses.push(styles.active); + } + return ( +
setVisible(false)} + onKeyUp={(e) => { + if (e.key === 'Escape') { + setVisible(false); + } + }} + > +
e.stopPropagation()} + > + {children} +
+
+ ); +} + +export default Modal; diff --git a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx new file mode 100644 index 0000000..d736b6b --- /dev/null +++ b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx @@ -0,0 +1,164 @@ +import React, { useEffect, useState } from 'react'; +import useInput from '../../../../hooks/useInput'; +import handleCardImg from '../../../utils/handleCardImg'; +import isFormValidHandle from '../../../utils/isFormValidHandle'; +import styles from './purchase.module.scss'; + +interface IPurchase { + // eslint-disable-next-line no-unused-vars + setShowAffirmative: (bool: boolean) => void +} + +function Purchase({ setShowAffirmative }: IPurchase) { + const [runValidate, setRunValidate] = useState(false); + // eslint-disable-next-line no-unused-vars + const [isFormValid, setIsFormValid] = useState(false); + const handleClickButton = (event: React.MouseEvent, isFormVal: boolean) => { + event.preventDefault(); + if (!isFormVal) setRunValidate(true); + if (isFormVal) { + setShowAffirmative(true); + } + }; + + const name = useInput('', runValidate, { isEmpty: true, minLengthName: true, minLengthNameForEachWord: true }); + const phone = useInput('', runValidate, { + isEmpty: true, isPhoneLengthInvalid: true, isPhoneNotStartWithPlus: true, isPhoneInvalid: true, + }); + const address = useInput('', runValidate, { isEmpty: true, minLengthAddressForEachWord: true, minLengthAddress: true }); + const email = useInput('', runValidate, { isEmpty: true, isMailInvalid: true }); + const cardNumber = useInput('', runValidate, { isEmpty: true, isCardNumberInvalid: true, isCardNumberLengthInvalid: true }); + const cardMonth = useInput('', runValidate, { isEmpty: true, isCardDateMonthInvalid: true }); + const cardYear = useInput('', runValidate, { isCardDateYearInvalid: true }); + const cardCVV = useInput('', runValidate, { isEmpty: true, isCardCVVInvalid: true }); + + useEffect(() => { + const result = isFormValidHandle([ + name.isAllValid, + phone.isAllValid, + address.isAllValid, + email.isAllValid, + cardNumber.isAllValid, + cardMonth.isAllValid, + cardYear.isAllValid, + cardCVV.isAllValid, + ]); + setIsFormValid(result); + }, [name.isAllValid, + phone.isAllValid, + address.isAllValid, + email.isAllValid, + cardNumber.isAllValid, + cardMonth.isAllValid, + cardYear.isAllValid, + cardCVV.isAllValid]); + return ( +
+
+

Personal details

+ {(name.isDirty) + && ( +
+ {name.isEmpty &&
!! Enter your Name and Surname !!
} + {name.minLengthName &&
!! Minimum 2 words required !!
} + {name.minLengthNameForEachWord && ( +
+ !! Minimum 2 words with 3 letters in each required !! +
+ )} +
+ )} + name.onChange(e)} value={name.value} type="text" name="Name" placeholder="Name" /> + {(phone.isDirty) + && ( +
+ {phone.isEmpty &&
!! Enter your phone !!
} + {phone.isPhoneLengthInvalid &&
!! Minimum 9 digits required !!
} + {phone.isPhoneNotStartWithPlus &&
!! Should start from `+` !!
} + {phone.isPhoneInvalid &&
!! Should contains only digits !!
} +
+ )} + phone.onChange(e)} value={phone.value} type="text" name="Phone" placeholder="Phone" /> + {(address.isDirty) + && ( +
+ {address.isEmpty &&
!! Enter your address !!
} + {address.minLengthAddress &&
!! Minimum 3 words required !!
} + {address.minLengthAddressForEachWord && ( +
+ !! Minimum 3 words with 5 letters in each required !! +
+ )} +
+ )} + address.onChange(e)} type="text" name="Address" placeholder="Delivery address" /> + {(email.isDirty) + && ( +
+ {email.isEmpty &&
!! Enter your e-mail !!
} + {email.isMailInvalid &&
!! E-mail should be correct !!
} +
+ )} + email.onChange(e)} type="text" name="Email" placeholder="E-mail" /> +
+

Credit card details

+ {(cardNumber.isDirty) + && ( +
+ {cardNumber.isEmpty &&
!! Enter your card number !!
} + {cardNumber.isCardNumberInvalid && ( +
+ !! Card number should contain only digits !! +
+ )} + {cardNumber.isCardNumberLengthInvalid && ( +
+ !! Card number length should be at least 16 !! +
+ )} +
+ )} +
+ + cardNumber.onChange(e)} type="text" name="cardNumber" placeholder="Card number" className={styles.cardNumberInput} /> +
+ {(cardMonth.isDirty) + && ( +
+ {cardMonth.isEmpty &&
!! Enter your card date !!
} + {cardCVV.isEmpty &&
!! Enter your card CVV !!
} + {cardMonth.isCardDateMonthInvalid &&
!! Enter correct month !!
} + {cardYear.isCardDateYearInvalid &&
!! Enter correct year !!
} + {cardCVV.isCardCVVInvalid &&
!! Enter correct CVV !!
} +
+ )} +
+
+ Date: +
+ cardMonth.onChange(e)} type="text" name="month" placeholder="MM" /> + / + cardYear.onChange(e)} type="text" name="year" placeholder="YY" /> +
+
+
+ {' '} + CVV: + {' '} + cardCVV.onChange(e)} type="text" name="cardCVV" placeholder="CVV" className={styles.otherDataCVV} /> +
+
+
+ +
+
+ ); +} + +export default Purchase; diff --git a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss new file mode 100644 index 0000000..b3d304f --- /dev/null +++ b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss @@ -0,0 +1,128 @@ +.formWrapper { + width: 60vw; + height: 60%; +} + +.myForm { + display: flex; + flex-direction: column; + align-items: center; +} + +.myInput { + margin-bottom: 20px; + width: 60%; + font-size: 1.5rem; + border-radius: 5px; + padding: 10px; +} + +.cardWrapper { + width: 55%; + padding: 10px; + display: flex; + align-items: center; + flex-direction: column; + border: 2px solid teal; + border-radius: 10px; + margin-bottom: 20px; +} + +.cardNumber { + width: 100%; + display: flex; + justify-content: center; + align-items: center; + margin-bottom: 20px; +} + +.cardImg { + background-color: #fff; + width: 10%; + border-radius: 0.3rem; + padding: 0.3rem; + margin-right: 10px; +} + +.cardNumberInput { + font-size: 1.5rem; + border: 2px solid teal; + border-radius: 10px; + width: 75%; + margin: auto 0; + &:focus { + outline: 0; + } +} + +.otherData { + display: flex; + width: 300px; + align-items: center; + justify-content: space-between; +} + +.otherDataCVV { + width: 35px; + border-radius: 0.3rem; + font-size: 1rem; + padding: 5px; + border: 2px solid teal; + margin-bottom: 0; + &:focus { + outline: 0; + } +} + +.otherDataExpirationWrapper { + display: flex; + align-items: center; +} + +.otherDataExpirationPlaceholder { + margin-right: 3px; +} + +.dataExpiration { + margin-right: 5px; + display: flex; + border: 2px solid teal; + border-radius: 5px; + & input { + text-align: center; + width: 30px; + border: 0; + font-size: 1rem; + padding: 5px; + margin-bottom: 0; + &:focus { + outline: 0; + } + } +} + +.formButton { + cursor: pointer; + font-size: 2rem; + padding: 10px 20px; + background-color: teal; + color: white; + border: 2px solid teal; + border-radius: 10px; + &:hover { + transition: 0.3s all; + color: teal; + background-color: white; + } +} + +.errorTextWrapper { + color: red; + width: 75%; + display: flex; + flex-wrap: wrap; + justify-content: center; + & > div { + padding: 0 10px 5px 10px; + } +} diff --git a/src/Components/Cart/PurchaseModal/modal.module.scss b/src/Components/Cart/PurchaseModal/modal.module.scss new file mode 100644 index 0000000..738c978 --- /dev/null +++ b/src/Components/Cart/PurchaseModal/modal.module.scss @@ -0,0 +1,23 @@ +.myModal { + position: fixed; + top: 0; + bottom: 0; + right: 0; + left: 0; + display: none; + background: rgba(0, 0, 0, 0.5); + overflow: scroll; +} + +.myModalContent { + padding: 25px; + background: white; + border-radius: 20px; + min-width: 250px; +} + +.myModal.active { + display: flex; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/src/Components/utils/areAllInputsValid.ts b/src/Components/utils/areAllInputsValid.ts new file mode 100644 index 0000000..fe8e752 --- /dev/null +++ b/src/Components/utils/areAllInputsValid.ts @@ -0,0 +1,17 @@ +// eslint-disable-next-line no-unused-vars +type TareAllInputsValid = (args: boolean[]) => boolean + +const areAllInputsValid: TareAllInputsValid = (args) => { + const result = args.reduce((acc, bool) => { + if (bool) { + // eslint-disable-next-line no-param-reassign + acc = false; + return acc; + } + return acc; + }, true); + + return result; +}; + +export default areAllInputsValid; diff --git a/src/Components/utils/handleCardImg.ts b/src/Components/utils/handleCardImg.ts new file mode 100644 index 0000000..c2d000b --- /dev/null +++ b/src/Components/utils/handleCardImg.ts @@ -0,0 +1,20 @@ +const cardImgPlaceholder = 'https://i.guim.co.uk/img/media/b73cc57cb1d46ae742efd06b6c58805e8600d482/16_0_2443_1466/master/2443.jpg?width=700&quality=85&auto=format&fit=max&s=fb1dca6cdd4589cd9ef2fc941935de71'; +const cardImgVisa = 'https://cdn.visa.com/v2/assets/images/logos/visa/blue/logo.png'; +const cardImgMasterCard = 'https://www.mastercard.hu/content/dam/public/mastercardcom/eu/hu/images/mc-logo-52.svg'; +const cardImgAExpress = 'https://www.aexp-static.com/cdaas/one/statics/axp-static-assets/1.8.0/package/dist/img/logos/dls-logo-stack.svg'; +const handleCardImg = (data: string) => { + const firstDigit = data.split('')[0]; + switch (firstDigit) { + case '3': + return cardImgAExpress; + + case '4': + return cardImgVisa; + + case '5': + return cardImgMasterCard; + default: + return cardImgPlaceholder; + } +}; +export default handleCardImg; diff --git a/src/Components/utils/isFormValidHandle.ts b/src/Components/utils/isFormValidHandle.ts new file mode 100644 index 0000000..b768724 --- /dev/null +++ b/src/Components/utils/isFormValidHandle.ts @@ -0,0 +1,17 @@ +// eslint-disable-next-line no-unused-vars +type TIsFormValidHandle = (args: boolean[]) => boolean + +const isFormValidHandle: TIsFormValidHandle = (args) => { + const result = args.reduce((acc, bool) => { + if (!bool) { + // eslint-disable-next-line no-param-reassign + acc = false; + return acc; + } + return acc; + }, true); + + return result; +}; + +export default isFormValidHandle; diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index b0608f2..f45a599 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -48,4 +48,21 @@ font-size: 2rem; font-weight: bold; color: teal +} + +.byuButton { + font-size: 2rem; + padding: 5px 15px; + background-color: teal; + color: white; + border: 1px solid teal; + border-radius: 5px; + cursor: pointer; + margin: 5px; + + &:hover { + transition: all 0.3s; + color: teal; + background-color: white; + } } \ No newline at end of file diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 6f944a3..bd277d8 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,12 +1,15 @@ /* eslint-disable max-len */ import React, { useState, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; +import ApprovePurchase from '../../Components/Cart/ApprovePerchase/ApprovePurchase'; // import React, { useEffect, useState } from 'react'; // import PostService from '../../Components/API/PostService'; import CartProduct from '../../Components/Cart/CartProduct/CartProduct'; import CartPagination from '../../Components/Cart/Pagination/CartPagination'; import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; import Promo from '../../Components/Cart/Promo/Promo'; +import Modal from '../../Components/Cart/PurchaseModal/Modal'; +import Purchase from '../../Components/Cart/PurchaseModal/Purchase/Purchase'; // eslint-disable-next-line no-unused-vars import countTotalCost from '../../Components/utils/countTotalCost'; import countTotalCount from '../../Components/utils/countTotalCount'; @@ -30,13 +33,14 @@ function Cart(props: TCartProps) { const { productsInCart, isPending, productsInCartCount, products, increaseProductCount, decreaseProductCount, } = props; - // eslint-disable-next-line no-unused-vars const [totalCount, setTotalCount] = useState(countTotalCount(productsInCartCount)); - // eslint-disable-next-line no-unused-vars const [totalCost, setTotalCost] = useState(0); const [isCodeValid, setIsCodeValid] = useState(false); const [isCodeAdd, setIsCodeAdd] = useState(false); const [codeAdded, setCodeAdded] = useState([]); + // Подтверждение покупки + const [formVisible, setFormVisible] = useState(false); + const [showAffirmative, setShowAffirmative] = useState(false); // Блок с пагинацией @@ -56,10 +60,6 @@ function Cart(props: TCartProps) { } }; - // type TParams = { - // limit?: string - // page?: string - // } const params = { limit: productsPerPage.toString(), page: currentPage.toString() }; let lastProductIndex = currentPage * productsPerPage; @@ -136,6 +136,12 @@ function Cart(props: TCartProps) { ); } + if (showAffirmative) { + return ( + + ); + } + return (
@@ -143,6 +149,7 @@ function Cart(props: TCartProps) { { currentProducts?.map((product: TProductsItem, index) => ( ))}
@@ -190,7 +197,15 @@ function Cart(props: TCartProps) {
) :

No applied codes

} +
+ + + +
); } diff --git a/src/hooks/useInput.ts b/src/hooks/useInput.ts new file mode 100644 index 0000000..4162920 --- /dev/null +++ b/src/hooks/useInput.ts @@ -0,0 +1,28 @@ +import React, { useEffect, useState } from 'react'; +import { TValidations } from '../types/types'; +import useValidation from './useValidation'; + +const useInput = (initialValue: string, runValidate: boolean, validations: TValidations) => { + const [value, setValue] = useState(initialValue); + const [isDirty, setIsDirty] = useState(false); + const valid = useValidation(value, validations); + + useEffect(() => { + if (runValidate) { + setIsDirty(true); + } else setIsDirty(false); + }, [runValidate]); + + const onChange = (e: React.FormEvent) => { + setValue(e.currentTarget.value); + }; + + return { + value, + isDirty, + onChange, + ...valid, + }; +}; + +export default useInput; diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts new file mode 100644 index 0000000..0c0042d --- /dev/null +++ b/src/hooks/useValidation.ts @@ -0,0 +1,202 @@ +/* eslint-disable no-unused-vars */ +import { useState, useEffect } from 'react'; +import areAllInputsValid from '../Components/utils/areAllInputsValid'; +import { TValidations } from '../types/types'; + +const useValidation = (value: string, validations:TValidations) => { + const [isEmpty, setIsEmpty] = useState(false); + + // Валидация личных данных + + // Имя должно состоять минимум из двух слов + const [minLengthName, setMinLengthName] = useState(false); + // Каждое слово в имени не менее 3-х символов + const [minLengthNameForEachWord, setMinLengthNameForEachWord] = useState(false); + + // Телефон должен содержать не менее 9 цифр + const [isPhoneLengthInvalid, setIsPhoneLengthInvalid] = useState(false); + // Телефон должен начинаться с + + const [isPhoneNotStartWithPlus, setIsPhoneNotStartWithPlus] = useState(false); + // Телефон должен состоять только из цифр + const [isPhoneInvalid, setIsPhoneInvalid] = useState(false); + + // Адрес не менее 3-х слов + const [minLengthAddress, setMinLengthAddress] = useState(false); + // Каждое слово в адресе не менее 5-ти символов + const [minLengthAddressForEachWord, setMinLengthAddressForEachWord] = useState(false); + + // Валидациея почты + const [isMailInvalid, setIsMailInvalid] = useState(false); + + // Валидация банковской карточки + + // Номер карты должен состоять только из цифр + const [isCardNumberInvalid, setIsCardNumberInvalid] = useState(false); + // Номер карты должен состоять из 16 цифр + const [isCardNumberLengthInvalid, setIsCardNumberLengthInvalid] = useState(false); + + // Верное количество месяцев + const [isCardDateMonthInvalid, setIsCardDateMonthInvalid] = useState(false); + // Верное количество лет + const [isCardDateYearInvalid, setIsCardDateYearInvalid] = useState(false); + + // Верное количество лет + const [isCardCVVInvalid, setIsCardCVVInvalid] = useState(false); + + useEffect(() => { + const validationsKeys = Object.keys(validations); + validationsKeys.forEach((key) => { + switch (key) { + case 'isEmpty': + if (value.length === 0) { + setIsEmpty(true); + } else { + setIsEmpty(false); + } + break; + + case 'minLengthName': + if (value.trim().split(' ').length < 2) { + setMinLengthName(true); + } else setMinLengthName(false); + break; + + case 'minLengthNameForEachWord': + if (value.trim().split(' ').reduce((acc, word) => { + if (word.length > 2) { + return acc + 1; + } + return acc; + }, 0) >= 2) { + setMinLengthNameForEachWord(false); + } else { + setMinLengthNameForEachWord(true); + } + break; + + case 'isPhoneLengthInvalid': + if (value.trim().split(' ').join('').length < 10) { + setIsPhoneLengthInvalid(true); + } else { + setIsPhoneLengthInvalid(false); + } + break; + + case 'isPhoneNotStartWithPlus': + if (value.split('')[0] !== '+') { + setIsPhoneNotStartWithPlus(true); + } else { + setIsPhoneNotStartWithPlus(false); + } + break; + + case 'isPhoneInvalid': + value.split('').forEach((char, index) => { + if (index !== 0) { + if (!/[0-9]/.test(char)) { + setIsPhoneInvalid(true); + } else setIsPhoneInvalid(false); + } + }); + break; + + case 'minLengthAddress': + if (value.split(' ').length < 3) setMinLengthAddress(true); + else setMinLengthAddress(false); + break; + + case 'minLengthAddressForEachWord': + if (value.split(' ').reduce((acc, word) => { + if (word.length > 4) { + return acc + 1; + } + return acc; + }, 0) > 2) { + setMinLengthAddressForEachWord(false); + } else { + setMinLengthAddressForEachWord(true); + } + break; + + case 'isMailInvalid': + if (/^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/iu.test(value)) { + setIsMailInvalid(false); + } else { + setIsMailInvalid(true); + } + break; + + case 'isCardNumberInvalid': + if (!value.length) setIsCardNumberInvalid(true); + value.split('').forEach((char) => { + if (!/[0-9]/.test(char)) { + setIsCardNumberInvalid(true); + } else setIsCardNumberInvalid(false); + }); + break; + + case 'isCardNumberLengthInvalid': + if (value.length < 16) { + setIsCardNumberLengthInvalid(true); + } else setIsCardNumberLengthInvalid(false); + break; + + case 'isCardDateMonthInvalid': + if (!/^(0[1-9]|1[0-2])$/.test(value)) { + setIsCardDateMonthInvalid(true); + } else setIsCardDateMonthInvalid(false); + break; + + case 'isCardDateYearInvalid': + if (!/^(2[3-9]|[3-9][0-9])$/.test(value)) { + setIsCardDateYearInvalid(true); + } else setIsCardDateYearInvalid(false); + break; + + case 'isCardCVVInvalid': + if (!/^\d{3}$/.test(value)) { + setIsCardCVVInvalid(true); + } else setIsCardCVVInvalid(false); + break; + + default: + break; + } + }); + }, [value]); + + const isAllValid = areAllInputsValid([isEmpty, + minLengthName, + minLengthNameForEachWord, + isPhoneLengthInvalid, + isPhoneNotStartWithPlus, + isPhoneInvalid, + minLengthAddress, + minLengthAddressForEachWord, + isMailInvalid, + isCardNumberInvalid, + isCardNumberLengthInvalid, + isCardDateMonthInvalid, + isCardDateYearInvalid, + isCardCVVInvalid]); + + return { + isEmpty, + minLengthName, + minLengthNameForEachWord, + isPhoneLengthInvalid, + isPhoneNotStartWithPlus, + isPhoneInvalid, + minLengthAddress, + minLengthAddressForEachWord, + isMailInvalid, + isCardNumberInvalid, + isCardNumberLengthInvalid, + isCardDateMonthInvalid, + isCardDateYearInvalid, + isCardCVVInvalid, + isAllValid, + }; +}; + +export default useValidation; diff --git a/src/types/types.ts b/src/types/types.ts index 695d7d4..300a801 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -19,6 +19,7 @@ export type TProductPartialProps = { export type TProductCartIdCountProps = { data: TProductPartialProps + productIndex: number } export type TProductHandlers = { @@ -48,3 +49,7 @@ export interface IAddHandler extends IPromoCodeHandler{ // eslint-disable-next-line no-unused-vars inputData: (string:string) => void } + +export type TValidations = { + [key:string]: boolean +}; From 9db476c2385f5161f6132315d8e0c2beb772ecf2 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 7 Jan 2023 19:48:05 +0400 Subject: [PATCH 26/65] feat: add loading spinner component --- src/Components/UI/LoadingSpinner.module.scss | 44 ++++++++++++++++++++ src/Components/UI/LoadingSpinner.tsx | 12 ++++++ 2 files changed, 56 insertions(+) create mode 100644 src/Components/UI/LoadingSpinner.module.scss create mode 100644 src/Components/UI/LoadingSpinner.tsx diff --git a/src/Components/UI/LoadingSpinner.module.scss b/src/Components/UI/LoadingSpinner.module.scss new file mode 100644 index 0000000..e4255de --- /dev/null +++ b/src/Components/UI/LoadingSpinner.module.scss @@ -0,0 +1,44 @@ +.container { + width: 55px; + height: 55px; + display: flex; + justify-content: center; + align-items: center; +} + +.spinner { + position: relative; + width: 10px; + height: 10px; + border-radius: 5px; + background-color: transparent; + box-shadow: 0 -20px 0 0 var(--spinner-color), 14.14px -14.14px 0 0 var(--spinner-color), 20px 0 0 0 var(--spinner-color), 14.14px 14.14px 0 0 transparent, 0 20px 0 0 transparent, -14.14px 14.14px 0 0 transparent, -20px 0 0 0 transparent, -14.14px -14.14px 0 0 transparent; + animation: spinner 1.5s infinite linear; +} + +@keyframes spinner { + 0%, 100% { + box-shadow: 0 -20px 0 0 var(--spinner-color), 14.14px -14.14px 0 0 var(--spinner-color), 20px 0 0 0 var(--spinner-color), 14.14px 14.14px 0 -5px transparent, 0 20px 0 -5px transparent, -14.14px 14.14px 0 -5px transparent, -20px 0 0 -5px transparent, -14.14px -14.14px 0 -5px transparent; + } + 12.5% { + box-shadow: 0 -20px 0 -5px transparent, 14.14px -14.14px 0 0 var(--spinner-color), 20px 0 0 0 var(--spinner-color), 14.14px 14.14px 0 0 var(--spinner-color), 0 20px 0 -5px transparent, -14.14px 14.14px 0 -5px transparent, -20px 0 0 -5px transparent, -14.14px -14.14px 0 -5px transparent; + } + 25% { + box-shadow: 0 -20px 0 -5px transparent, 14.14px -14.14px 0 -5px transparent, 20px 0 0 0 var(--spinner-color), 14.14px 14.14px 0 0 var(--spinner-color), 0 20px 0 0 var(--spinner-color), -14.14px 14.14px 0 -5px transparent, -20px 0 0 -5px transparent, -14.14px -14.14px 0 -5px transparent; + } + 37.5% { + box-shadow: 0 -20px 0 -5px transparent, 14.14px -14.14px 0 -5px transparent, 20px 0 0 -5px transparent, 14.14px 14.14px 0 0 var(--spinner-color), 0 20px 0 0 var(--spinner-color), -14.14px 14.14px 0 0 var(--spinner-color), -20px 0 0 -5px transparent, -14.14px -14.14px 0 -5px transparent; + } + 50% { + box-shadow: 0 -20px 0 -5px transparent, 14.14px -14.14px 0 -5px transparent, 20px 0 0 -5px transparent, 14.14px 14.14px 0 -5px transparent, 0 20px 0 0 var(--spinner-color), -14.14px 14.14px 0 0 var(--spinner-color), -20px 0 0 0 var(--spinner-color), -14.14px -14.14px 0 -5px transparent; + } + 62.5% { + box-shadow: 0 -20px 0 -5px transparent, 14.14px -14.14px 0 -5px transparent, 20px 0 0 -5px transparent, 14.14px 14.14px 0 -5px transparent, 0 20px 0 -5px transparent, -14.14px 14.14px 0 0 var(--spinner-color), -20px 0 0 0 var(--spinner-color), -14.14px -14.14px 0 0 var(--spinner-color); + } + 75% { + box-shadow: 0 -20px 0 0 var(--spinner-color), 14.14px -14.14px 0 -5px transparent, 20px 0 0 -5px transparent, 14.14px 14.14px 0 -5px transparent, 0 20px 0 -5px transparent, -14.14px 14.14px 0 -5px transparent, -20px 0 0 0 var(--spinner-color), -14.14px -14.14px 0 0 var(--spinner-color); + } + 87.5% { + box-shadow: 0 -20px 0 0 var(--spinner-color), 14.14px -14.14px 0 0 var(--spinner-color), 20px 0 0 -5px transparent, 14.14px 14.14px 0 -5px transparent, 0 20px 0 -5px transparent, -14.14px 14.14px 0 -5px transparent, -20px 0 0 -5px transparent, -14.14px -14.14px 0 0 var(--spinner-color); + } +} diff --git a/src/Components/UI/LoadingSpinner.tsx b/src/Components/UI/LoadingSpinner.tsx new file mode 100644 index 0000000..2c21046 --- /dev/null +++ b/src/Components/UI/LoadingSpinner.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import styles from './LoadingSpinner.module.scss'; + +function LoadingSpinner() { + return ( +
+
+
+ ); +} + +export default LoadingSpinner; From 248e64b41203cc1bb072400d8e1c3d4f7912377e Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Sun, 8 Jan 2023 14:56:35 +0300 Subject: [PATCH 27/65] Feat product page (#8) * feat: create template of produtc page * feat: add page to route --- src/App/RootRouter/index.tsx | 4 +- src/Components/Main/ProductsList.tsx | 2 +- src/Components/ProductPage/ProductPage.tsx | 121 ++++++++++++++++++ .../ProductPage/productPage.module.scss | 30 +++++ src/types/types.ts | 5 +- 5 files changed, 158 insertions(+), 4 deletions(-) create mode 100644 src/Components/ProductPage/ProductPage.tsx create mode 100644 src/Components/ProductPage/productPage.module.scss diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 344c3b4..80a8ed8 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -1,9 +1,9 @@ import React from 'react'; import { Route, Routes } from 'react-router-dom'; import Header from '../../Components/header'; +import ProductPage from '../../Components/ProductPage/ProductPage'; import Cart from '../../Pages/Cart/cart'; import Main from '../../Pages/Main'; -import Other from '../../Pages/Other'; import PageNotFound from '../../Pages/PageNotFound'; import { TProductsItem, TProductPartialProps } from '../../types/types'; @@ -47,7 +47,7 @@ export default function RootRouter(props: TRootRouterProps) { /> )} /> - } /> + } /> - Details + Details
)) : 'No products found' diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx new file mode 100644 index 0000000..0582395 --- /dev/null +++ b/src/Components/ProductPage/ProductPage.tsx @@ -0,0 +1,121 @@ +/* eslint-disable no-unused-vars */ +import React, { useEffect, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import useFetching from '../../hooks/useFetching'; +import { TProductPartialProps, TProductsItemWithImages } from '../../types/types'; +import PostService from '../API/PostService'; +import ProductAddDropButton from '../UI/button/ProductAddDropButton'; +import styles from './productPage.module.scss'; + +interface IProductPage { + productsInCart: TProductPartialProps[] + // eslint-disable-next-line no-unused-vars + addToCart(id: number | undefined): void; + // eslint-disable-next-line no-unused-vars + dropFromCart(id: number | undefined): void; +} + +function ProductPage({ + productsInCart, addToCart, dropFromCart, +}: IProductPage) { + const params = useParams(); + const navigate = useNavigate(); + const id = Number(params.id); + console.log(id); + + useEffect(() => { + if (!id || id < 1 || id > 100) { + navigate('/*', { relative: 'path' }); + } + }, [id, navigate]); + + const [currentPage, setCurrentPage] = useState(null); + const [fetchProductById, isPending] = useFetching(async () => { + // вспомнить про ошибку, перекинуть на 404 страницу при неверных данных + const data = await PostService.getById(id); + setCurrentPage(data); + }); + + useEffect(() => { + fetchProductById(); + }, [id]); + + if (isPending) { + return ( +
+ Is loading... +
+ ); + } + + return ( +
+
+
home
+
{currentPage?.category}
+
{currentPage?.brand}
+
{currentPage?.title}
+
+
+

{currentPage?.title}

+
+
+ {currentPage?.title} +
+ +
+
+
+
+ Stock: + {' '} + {currentPage?.stock} +
+
+ Brand: + {' '} + {currentPage?.stock} +
+
+ Description: + {' '} + {currentPage?.description} +
+
+ Rating: + {' '} + {currentPage?.rating} +
+
+ Category: + {' '} + {currentPage?.category} +
+
+ Discount Percentage: + {' '} + {currentPage?.discountPercentage} +
+
+
+
+ Price € + {' '} + {currentPage?.price} + .00 +
+ + +
+
+
+
+ ); +} + +export default ProductPage; diff --git a/src/Components/ProductPage/productPage.module.scss b/src/Components/ProductPage/productPage.module.scss new file mode 100644 index 0000000..7661ab8 --- /dev/null +++ b/src/Components/ProductPage/productPage.module.scss @@ -0,0 +1,30 @@ +.wrapper { + max-width: 1220px; +} + +.breedsWrapper { + max-width: 800px; + margin: auto; +} + +.productWrapper { + display: block; +} + +.detailsWrapper { + display: flex; +} + +.imagesWrapper { + +} + +.imagesCarouselWrapper { + +} + +// styles for info + +.buttonsWrapper { + +} \ No newline at end of file diff --git a/src/types/types.ts b/src/types/types.ts index 300a801..74ec734 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -6,12 +6,15 @@ export type TProductsItem = { category: string; brand: string; discountPercentage: number; - images?: string[]; rating: number; stock: number; thumbnail: string; } +export type TProductsItemWithImages = TProductsItem & { + images: string[]; +} + export type TProductPartialProps = { id: number, count: number From 28bf0bed3530b6a375c5aa58f13fa11750970ff7 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sun, 8 Jan 2023 16:01:17 +0400 Subject: [PATCH 28/65] fix: fix total price in header --- src/Components/header/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 1d195e2..768f614 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -70,7 +70,7 @@ export default function Header(props: TProps) { {/* {cartTotal?.toFixed(2)} */} {cartTotal ? new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(cartTotal) - : new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(0)} + : '...'}

From a9c3ff09b2543d7a289c053857e63e5f630021a9 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sun, 8 Jan 2023 16:02:49 +0400 Subject: [PATCH 29/65] feat: add price and stock filters to main page --- src/Components/Main/DualSlider.module.scss | 67 ++++++++ src/Components/Main/DualSlider.tsx | 66 ++++++++ src/Components/Main/FiltersList.tsx | 58 ++++--- src/Components/Main/ProductsList.tsx | 2 +- src/Pages/Main/index.tsx | 185 +++++++++++++++------ 5 files changed, 304 insertions(+), 74 deletions(-) create mode 100644 src/Components/Main/DualSlider.module.scss create mode 100644 src/Components/Main/DualSlider.tsx diff --git a/src/Components/Main/DualSlider.module.scss b/src/Components/Main/DualSlider.module.scss new file mode 100644 index 0000000..1bbc496 --- /dev/null +++ b/src/Components/Main/DualSlider.module.scss @@ -0,0 +1,67 @@ +:root { + --spinner-color: black; +} + +.dualSlider { + position: relative; +} + +.slider { + -webkit-appearance: none; + width: 100%; + background: transparent; + height: 2px; + background: black; + position: absolute; + pointer-events: none; + + &:focus { + outline: none; + } +} + +.sliderMin { + height: 0; + z-index: 1; +} + +.slider::-ms-track { + width: 100%; + cursor: pointer; + background: transparent; + border-color: transparent; + color: transparent; +} + +.slider::-webkit-slider-runnable-track, +.slider::-moz-range-track, +.slider::-ms-track { + // background: black; + width: 100%; + height: 2px; +} + +.slider::-webkit-slider-thumb { + -webkit-appearance: none; + pointer-events: all; + width: 20px; + height: 20px; + border-radius: 50%; + background-color: black; + cursor: pointer; + + &:hover { + background-color: darkblue; + } +} + +.slider::-webkit-slider-thumb, +.slider::-moz-range-thumb, +.slider::-ms-thumb { + pointer-events: all; + width: 20px; + height: 20px; + border-radius: 50%; + background-color: black; + cursor: pointer; +} diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx new file mode 100644 index 0000000..5b16121 --- /dev/null +++ b/src/Components/Main/DualSlider.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import { TProductsItem } from '../../types/types'; +import styles from './DualSlider.module.scss'; + +type TDualSliderProps = { + sliderId: string; + filter: 'price' | 'stock'; + products: TProductsItem[]; + // eslint-disable-next-line no-unused-vars + handleSliderMinInput(event: React.ChangeEvent): void; + // eslint-disable-next-line no-unused-vars + handleSliderMaxInput(event: React.ChangeEvent): void + filteredSearchedProducts: TProductsItem[] | []; + searchParamsObject: Record; + // eslint-disable-next-line no-unused-vars + fillSlider(filter: 'price' | 'stock'): string; + } + +function DualSlider(props: TDualSliderProps) { + const { + sliderId, + filter, + products, + handleSliderMinInput, + handleSliderMaxInput, + filteredSearchedProducts, + searchParamsObject, + fillSlider, + } = props; + + return ( +
+ item[filter]))} + max={Math.max(...products.map((item) => item[filter]))} + value={searchParamsObject[`${filter}range`]?.split(',')[0] ?? Math.min(...filteredSearchedProducts.map((item) => item[filter]))} + onInput={handleSliderMinInput} + className={[styles.slider, styles.sliderMin].join(' ')} + /> + item[filter]))} + max={Math.max(...products.map((item) => item[filter]))} + value={searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? Math.max(...filteredSearchedProducts.map((item) => item[filter]))} + onInput={handleSliderMaxInput} + className={styles.slider} + style={{ background: `${fillSlider(filter)}` }} + /> +

{searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...filteredSearchedProducts.map((item) => item[filter])) : 0}

+

{searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...filteredSearchedProducts.map((item) => item[filter])) : 0}

+
+
+ ); +} + +export default DualSlider; diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index 93d6ab8..bac5b46 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -1,9 +1,6 @@ import React from 'react'; -// import { isTemplateExpression } from 'typescript'; -// import { useSearchParams } from 'react-router-dom'; -// import ProductsList from '../../Components/Main/ProductsList'; -// import { useLocation } from 'react-router-dom'; import { TProductsItem } from '../../types/types'; +import DualSlider from './DualSlider'; type TParamsObject = Record; @@ -20,7 +17,13 @@ type TFiltersListProps = { handleResetClick(): void; // eslint-disable-next-line no-unused-vars handleCopyClick(): void; + // eslint-disable-next-line no-unused-vars + handleSliderMinInput(event: React.ChangeEvent): void; + // eslint-disable-next-line no-unused-vars + handleSliderMaxInput(event: React.ChangeEvent): void copied: boolean; + // eslint-disable-next-line no-unused-vars + fillSlider(filter: 'price' | 'stock'): string; } function FiltersList(props: TFiltersListProps) { @@ -34,27 +37,12 @@ function FiltersList(props: TFiltersListProps) { handleCheckboxChange, handleResetClick, handleCopyClick, + handleSliderMinInput, + handleSliderMaxInput, copied, + fillSlider, } = props; - // const categoriesArray = categoriesList.map((category) => { - // const obj = { [category]: isInSearchParams('category', category, searchParamsObject) }; - // return obj; - // }); - // console.log(categoriesArray); - - // let arr = new Array(categoriesList.length).fill(false); - // console.log(arr); - // arr = arr.map((category) => isInSearchParams('category', category, searchParamsObject)); - // console.log(arr); - // const [checkedCategories] = useState( - // new Array(categoriesList.length).fill(arr), - // ); - // useEffect(() => console.log('checkedCategories'), []); - - // console.log('checkedCategories'); - // console.log(checkedCategories); - return (
@@ -99,6 +87,32 @@ function FiltersList(props: TFiltersListProps) { ))}
+
+ Price: + +
+
+ Stock: + +
); } diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx index d62e0be..03f02eb 100644 --- a/src/Components/Main/ProductsList.tsx +++ b/src/Components/Main/ProductsList.tsx @@ -24,7 +24,7 @@ export default function ProductsList(props: TProductsListProps) { { products.length ? products.map((product: TProductsItem) => ( -
+

{product.title}

{product.title}
diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 1777aa1..292784c 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,10 +1,10 @@ import React, { ChangeEvent, useEffect, useState } from 'react'; -// import { useLocation } from 'react-router-dom'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; // import TestForMain from '../../Components/TestForMain'; import { TProductPartialProps, TProductsItem } from '../../types/types'; import useSearchParamsObject from '../../hooks/useSearchParamsObject'; +import LoadingSpinner from '../../Components/UI/LoadingSpinner'; type TMainProps = { productsInCart: TProductPartialProps[]; @@ -16,22 +16,23 @@ type TMainProps = { type TParamsObject = Record; -// type TIsInSearchParams = { -// paramName: string; -// param: string | number; -// paramsObject: TParamsObject; -// } - type TFilterOptions = 'category' | 'brand' | 'price' | 'stock'; function Main(props: TMainProps) { - const { productsInCart, addToCart, dropFromCart } = props; + const { + productsInCart, + addToCart, + dropFromCart, + } = props; const [products, setProducts] = useState([]); + const [isPending, setIsPending] = useState(true); + const fetchProducts = async () => { const response = await fetch('https://dummyjson.com/products?limit=20'); const productsList = await response.json(); setProducts(productsList.products); + setIsPending(false); }; useEffect(() => { @@ -85,6 +86,57 @@ function Main(props: TMainProps) { } }; + // let filteredSearchedProducts: TProductsItem[] = products.slice(); + + const fillSlider = (filter: 'price' | 'stock') => { + const sliderColor = '#999999'; + const rangeColor = '#000000'; + const max = Math.max(...products.map((item) => item[filter])); + const min = Math.min(...products.map((item) => item[filter])); + const valueMin = Number(searchParamsObject[`${[filter]}range`]?.split(',')[0]); + const valueMax = Number(searchParamsObject[`${[filter]}range`]?.split(',')[1]); + const rangeDistance = max - min; + const fromPosition = valueMin - min; + const toPosition = valueMax - min; + return `linear-gradient( + to right, + ${sliderColor} 0%, + ${sliderColor} ${((fromPosition) / (rangeDistance)) * 100}%, + ${rangeColor} ${((fromPosition) / (rangeDistance)) * 100}%, + ${rangeColor} ${((toPosition) / (rangeDistance)) * 100}%, + ${sliderColor} ${((toPosition) / (rangeDistance)) * 100}%, + ${sliderColor} 100%)`; + }; + + const getMinPrice = (source: TProductsItem[], param: 'price' | 'stock') => { + if (source.length !== 0) { + return Math.min(...source.map((item) => item[param])); + } + return undefined; + }; + const getMaxPrice = (source: TProductsItem[], param: 'price' | 'stock') => { + if (source.length !== 0) { + return Math.max(...source.map((item) => item[param])); + } + return undefined; + }; + + const handleSliderMinInput = (event: React.ChangeEvent) => { + const param = (event.target.id === 'filter-price-min') ? 'price' : 'stock'; + const minValue = Number(event.target.value); + const maxValue = Number(searchParamsObject[`${param}range`]?.split(',')[1] ?? getMaxPrice(products, param)); + setSearchParamsObject({ ...searchParamsObject, [`${param}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); + fillSlider('price'); + }; + + const handleSliderMaxInput = (event: React.ChangeEvent) => { + const param = (event.target.id === 'filter-price-max') ? 'price' : 'stock'; + const minValue = Number(searchParamsObject[`${param}range`]?.split(',')[0] ?? getMinPrice(products, param)); + const maxValue = Number(event.target.value); + setSearchParamsObject({ ...searchParamsObject, [`${param}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); + fillSlider('stock'); + }; + const handleSearchChange = (event: React.ChangeEvent) => { if (event.target.value === '') { const copySearchParamsObject = { ...searchParamsObject }; @@ -94,11 +146,7 @@ function Main(props: TMainProps) { setSearchParamsObject({ ...searchParamsObject, search: event.target.value }); } }; - - // const [sortingBy, setSortingBy] = useState(''); - // console.log(sortingBy); const handleSortingChange = (event: ChangeEvent) => { - // setSortingBy(event.target.value); if (event.target.value === 'default') { const copySearchParamsObject = { ...searchParamsObject }; delete copySearchParamsObject.sortby; @@ -118,6 +166,20 @@ function Main(props: TMainProps) { const params = searchParamsObject.brand.split(','); arr = arr.filter((elem) => params.includes(elem.brand)); } + if (searchParamsObject.pricerange) { + const params = searchParamsObject.pricerange.split(',').map((elem) => Number(elem)); + arr = arr.filter((elem) => elem.price >= params[0] && elem.price <= params[1]); + } + if (searchParamsObject.stockrange) { + const params = searchParamsObject.stockrange.split(',').map((elem) => Number(elem)); + arr = arr.filter((elem) => elem.stock >= params[0] && elem.stock <= params[1]); + } + // const minValue = getMinPrice(filteredSearchedProducts) + // ?? searchParamsObject?.pricerange?.split(',')[0]; + // const maxValue = getMaxPrice(filteredSearchedProducts) + // ?? searchParamsObject?.pricerange?.split(',')[1]; + // setSearchParamsObject({ ...searchParamsObject, + // pricerange: [minValue, maxValue].join(',') }); return arr; }; @@ -166,7 +228,8 @@ function Main(props: TMainProps) { const handleResetClick = () => { setSearchParamsObject({}); - // handleSortingChange(); + fillSlider('price'); + fillSlider('stock'); }; const [copied, setCopied] = useState(false); @@ -178,44 +241,64 @@ function Main(props: TMainProps) { }; return ( -
- -
-
- -

- {'Found: '} - {filteredSearchedSortedProducts.length} -

- -
- -
-
+
+ {isPending + ? ( +
+ +
+ ) + : ( +
+ +
+
+ +

+ {'Found: '} + {filteredSearchedSortedProducts.length} +

+ +
+ +
+
+ )} +
+ ); } From 58dbaa167bee30cb73d2767f6dc183b1c7310765 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sun, 8 Jan 2023 18:28:11 +0400 Subject: [PATCH 30/65] feat: add footer --- src/App/RootRouter/index.tsx | 2 ++ src/Components/Footer/Footer.module.scss | 13 +++++++++++++ src/Components/Footer/index.tsx | 24 ++++++++++++++++++++++++ src/assets/images/rs_school_js.svg | 1 + 4 files changed, 40 insertions(+) create mode 100644 src/Components/Footer/Footer.module.scss create mode 100644 src/Components/Footer/index.tsx create mode 100644 src/assets/images/rs_school_js.svg diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 80a8ed8..61f4d50 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { Route, Routes } from 'react-router-dom'; +import Footer from '../../Components/Footer'; import Header from '../../Components/header'; import ProductPage from '../../Components/ProductPage/ProductPage'; import Cart from '../../Pages/Cart/cart'; @@ -63,6 +64,7 @@ export default function RootRouter(props: TRootRouterProps) { /> } /> +
); } diff --git a/src/Components/Footer/Footer.module.scss b/src/Components/Footer/Footer.module.scss new file mode 100644 index 0000000..e833f36 --- /dev/null +++ b/src/Components/Footer/Footer.module.scss @@ -0,0 +1,13 @@ +.footer { + width: 100%; + display: flex; + justify-content: center; +} + +.container { + width: 80%; + max-width: 800px; + display: flex; + justify-content: space-between; + align-items: center; +} \ No newline at end of file diff --git a/src/Components/Footer/index.tsx b/src/Components/Footer/index.tsx new file mode 100644 index 0000000..2153dd0 --- /dev/null +++ b/src/Components/Footer/index.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import styles from './Footer.module.scss'; +import logo from '../../assets/images/rs_school_js.svg'; + +function Footer() { + return ( +
+ ); +} + +export default Footer; diff --git a/src/assets/images/rs_school_js.svg b/src/assets/images/rs_school_js.svg new file mode 100644 index 0000000..3b80540 --- /dev/null +++ b/src/assets/images/rs_school_js.svg @@ -0,0 +1 @@ +rs_school_js \ No newline at end of file From 30c7bb645df20907e955dba5a3ced5f5a174a005 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Mon, 9 Jan 2023 13:06:50 +0300 Subject: [PATCH 31/65] Feat product page styling buy now logic (#13) * fix: routing * feat: add saving products to local storage * feat: add loading spinner * feat: add links from products in cart to product page * fix: correct credit card month validation * feat: add filter to images --- src/App/App.tsx | 16 ++- src/App/RootRouter/index.tsx | 17 ++- src/Components/API/PostService.ts | 15 ++- .../Cart/ApprovePerchase/ApprovePurchase.tsx | 18 ++- .../Cart/CartProduct/CartProduct.module.scss | 13 ++- .../Cart/CartProduct/CartProduct.tsx | 56 ++++++---- .../CarouselImages/CarouselImages.module.scss | 0 .../CarouselImages/CarouselImages.tsx | 20 ++++ .../ProductImagesCarousel.module.scss | 0 .../ProductImagesCarousel.tsx | 24 ++++ src/Components/ProductPage/ProductPage.tsx | 105 ++++++++++++++---- .../ProductPage/productPage.module.scss | 36 +++++- src/Components/utils/checkUniqueImgs.ts | 31 ++++++ src/Components/utils/handleLocalStorage.ts | 7 ++ src/Components/utils/setDataToLocalStorage.ts | 8 ++ src/Pages/Cart/cart.module.scss | 1 + src/Pages/Cart/cart.tsx | 33 ++++-- src/Pages/Main/index.tsx | 5 + src/hooks/useValidation.ts | 6 +- 19 files changed, 347 insertions(+), 64 deletions(-) create mode 100644 src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss create mode 100644 src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx create mode 100644 src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss create mode 100644 src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx create mode 100644 src/Components/utils/checkUniqueImgs.ts create mode 100644 src/Components/utils/handleLocalStorage.ts create mode 100644 src/Components/utils/setDataToLocalStorage.ts diff --git a/src/App/App.tsx b/src/App/App.tsx index 8ceac60..705e5d5 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -4,14 +4,16 @@ import RootRouter from './RootRouter'; import PostService from '../Components/API/PostService'; import useFetching from '../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../types/types'; -// import { isTemplateExpression } from 'typescript'; +import handleLocalStorage from '../Components/utils/handleLocalStorage'; +import setDataToLocalStorage from '../Components/utils/setDataToLocalStorage'; function App() { // eslint-disable-next-line max-len - const arr = [{ id: 1, count: 1 }, { id: 3, count: 1 }, { id: 4, count: 1 }, { id: 11, count: 1 }, { id: 15, count: 1 }, { id: 27, count: 1 }, { id: 37, count: 1 }]; - const [productsInCart, setProductsInCart] = useState(arr); - const [productsInCartCount, setProductsInCartCount] = useState(arr); + const [productsInCart, setProductsInCart] = useState(handleLocalStorage()); + // eslint-disable-next-line max-len + const [productsInCartCount, setProductsInCartCount] = useState(handleLocalStorage()); const [products, setProducts] = useState(null); + const [formVisible, setFormVisible] = useState(false); const [fetchProductsById, isPending] = useFetching(async () => { const response = await PostService.getCartItems(productsInCart) .then((items) => items.map((item) => item)); @@ -40,6 +42,7 @@ function App() { return product; }); setProductsInCartCount(result); + setDataToLocalStorage(result); }; const decreaseProductCount = (event: React.MouseEvent) => { @@ -57,6 +60,7 @@ function App() { return acc; }, []); setProductsInCartCount(result); + setDataToLocalStorage(result); }; const isProductInCart = (id?: number): boolean => { @@ -85,12 +89,16 @@ function App() { diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 61f4d50..97e30c4 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -11,7 +11,11 @@ import { TProductsItem, TProductPartialProps } from '../../types/types'; type TRootRouterProps = { isPending: boolean; productsInCart: TProductPartialProps[]; + // eslint-disable-next-line no-unused-vars + setProductsInCart(arr: TProductPartialProps[]): void; productsInCartCount: TProductPartialProps[]; + // eslint-disable-next-line no-unused-vars + setProductsInCartCount(arr: TProductPartialProps[]): void; products: TProductsItem[] | null; // eslint-disable-next-line no-unused-vars increaseProductCount(event: React.MouseEvent): void; @@ -21,18 +25,25 @@ type TRootRouterProps = { addToCart(id: number): void; // eslint-disable-next-line no-unused-vars dropFromCart(id: number): void; + formVisible: boolean; + // eslint-disable-next-line no-unused-vars + setFormVisible(bool:boolean): void; } export default function RootRouter(props: TRootRouterProps) { const { isPending, productsInCart, + setProductsInCart, productsInCartCount, + setProductsInCartCount, products, increaseProductCount, decreaseProductCount, addToCart, dropFromCart, + formVisible, + setFormVisible, } = props; return (
@@ -48,17 +59,21 @@ export default function RootRouter(props: TRootRouterProps) { /> )} /> - } /> + } /> )} /> diff --git a/src/Components/API/PostService.ts b/src/Components/API/PostService.ts index 772c512..f0d55b5 100644 --- a/src/Components/API/PostService.ts +++ b/src/Components/API/PostService.ts @@ -8,9 +8,20 @@ export default class PostService { } static async getCartItems(arr:TProductPartialProps[]) { - let itemRequests = []; - itemRequests = arr.map((item) => PostService.getById(item.id)); + const itemRequests = arr.map((item) => PostService.getById(item.id)); const promises = await Promise.all(itemRequests); return promises; } + + static async getImgByURL(URL: string) { + const response = await fetch(URL); + const contentLength = Number(response.headers.get('Content-Length')); + return contentLength; + } + + static async getAllSizes(arr: string[]) { + const imgSizes = arr.map((img) => PostService.getImgByURL(img)); + const promises = await Promise.all(imgSizes); + return promises; + } } diff --git a/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx b/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx index e50e8ea..75f0dce 100644 --- a/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx +++ b/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx @@ -1,17 +1,33 @@ import React, { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; +import { TProductPartialProps } from '../../../types/types'; import styles from './approvePurchase.module.css'; interface IApprovePurchase { showAffirmative: boolean + // eslint-disable-next-line no-unused-vars + setFormVisible(bool:boolean): void; + // eslint-disable-next-line no-unused-vars + setProductsInCart(arr: TProductPartialProps[]): void; + // eslint-disable-next-line no-unused-vars + setProductsInCartCount(arr: TProductPartialProps[]): void; } -function ApprovePurchase({ showAffirmative }: IApprovePurchase) { +function ApprovePurchase({ + showAffirmative, + setFormVisible, + setProductsInCart, + setProductsInCartCount, +}: IApprovePurchase) { const time = 3; if (showAffirmative) { + window.localStorage.clear(); const history = useNavigate(); useEffect(() => { setTimeout(() => { + setFormVisible(false); + setProductsInCart([]); + setProductsInCartCount([]); history('/', { replace: true }); }, 3000); }, []); diff --git a/src/Components/Cart/CartProduct/CartProduct.module.scss b/src/Components/Cart/CartProduct/CartProduct.module.scss index ad81806..9156545 100644 --- a/src/Components/Cart/CartProduct/CartProduct.module.scss +++ b/src/Components/Cart/CartProduct/CartProduct.module.scss @@ -10,6 +10,13 @@ justify-content: space-between; } +.dataLinkWrapper { + width: 90%; + display: flex; + text-decoration: none; + color: teal; +} + .infoWrapper { width: 100%; display: flex; @@ -19,17 +26,19 @@ padding: 0 15px; & hr { width: 100%; - height: 2px; + height: 1px; background-color: teal; + border: 1px solid teal; border-radius: 5px; } } .infoImg { - width: 30%; + max-width: 200px; height: auto; border: 2px solid teal; border-radius: 10px; + object-fit: cover; } .buttonsWrapper { diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index dd93c84..5e221cf 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -1,7 +1,9 @@ /* eslint-disable max-len */ import React from 'react'; +import { Link } from 'react-router-dom'; import { TProductsCart } from '../../../types/types'; import ProductCartButton from '../../UI/button/ProductCartButton'; +import LoadingSpinner from '../../UI/LoadingSpinner'; import styles from './CartProduct.module.scss'; function CartProduct(props:TProductsCart) { @@ -24,41 +26,51 @@ function CartProduct(props:TProductsCart) { } = props; if (!data) { return ( -
Is loading
+
+ +
); } return (
{productIndex}
- {title} -
-

{title}

-
-

{description}

+ + {title} +
+

{title}

+
+

{description}

-
- Category: - {' '} - {category} -
-
- Brand: - {' '} - {brand} -
-
- Rating: + Category: {' '} - {rating} + {category}
- Discount: + Brand: {' '} - {discountPercentage} + {brand} +
+
+
+ Rating: + {' '} + {rating} +
+
+ Discount: + {' '} + {discountPercentage} +
-
+
Available stock: diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx new file mode 100644 index 0000000..6441432 --- /dev/null +++ b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx @@ -0,0 +1,20 @@ +/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ +/* eslint-disable jsx-a11y/click-events-have-key-events */ +import React from 'react'; +import styles from './CarouselImages.module.scss'; + +interface ICarouselImages { + value: string + // eslint-disable-next-line no-unused-vars + setCurrentImg(str:string): void +} + +function CarouselImages({ value, setCurrentImg }: ICarouselImages) { + return ( +
+ setCurrentImg(value)} alt="product" /> +
+ ); +} + +export default CarouselImages; diff --git a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx new file mode 100644 index 0000000..5e86fca --- /dev/null +++ b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import CarouselImages from './CarouselImages/CarouselImages'; +import styles from './ProductImagesCarousel.module.scss'; + +interface IProductImagesCarousel { + cleanArrImg: string[] + // eslint-disable-next-line no-unused-vars + setCurrentImg(str:string): void +} + +function ProductImagesCarousel({ cleanArrImg, setCurrentImg }: IProductImagesCarousel) { + return ( +
+ { + cleanArrImg.map( + (img) => , + ) +} + +
+ ); +} + +export default ProductImagesCarousel; diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index 0582395..99d7056 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -1,10 +1,14 @@ /* eslint-disable no-unused-vars */ -import React, { useEffect, useState } from 'react'; -import { useNavigate, useParams } from 'react-router-dom'; +import React, { useEffect, useMemo, useState } from 'react'; +import { Link, useNavigate, useParams } from 'react-router-dom'; import useFetching from '../../hooks/useFetching'; import { TProductPartialProps, TProductsItemWithImages } from '../../types/types'; import PostService from '../API/PostService'; import ProductAddDropButton from '../UI/button/ProductAddDropButton'; +import LoadingSpinner from '../UI/LoadingSpinner'; +import checkUniqueImgs from '../utils/checkUniqueImgs'; +import setDataToLocalStorage from '../utils/setDataToLocalStorage'; +import ProductImagesCarousel from './ProductImagesCarousel/ProductImagesCarousel'; import styles from './productPage.module.scss'; interface IProductPage { @@ -13,37 +17,99 @@ interface IProductPage { addToCart(id: number | undefined): void; // eslint-disable-next-line no-unused-vars dropFromCart(id: number | undefined): void; + setFormVisible: (bool:boolean) => void } function ProductPage({ - productsInCart, addToCart, dropFromCart, + productsInCart, addToCart, dropFromCart, setFormVisible, }: IProductPage) { const params = useParams(); const navigate = useNavigate(); const id = Number(params.id); - console.log(id); - useEffect(() => { - if (!id || id < 1 || id > 100) { - navigate('/*', { relative: 'path' }); - } - }, [id, navigate]); + // const [goToCart, setGoToCart] = useState(false); + const [currentPage, setCurrentPage] = useState(); - const [currentPage, setCurrentPage] = useState(null); const [fetchProductById, isPending] = useFetching(async () => { - // вспомнить про ошибку, перекинуть на 404 страницу при неверных данных const data = await PostService.getById(id); setCurrentPage(data); }); + const [currentImg, setCurrentImg] = useState(''); + const [allImgsSizes, setAllImgsSizes] = useState([]); + const [arrImg, setArrImg] = useState([]); + const [cleanArrImg, setCleanArrImg] = useState([]); + + const [getImgSizes] = useFetching(async () => { + if (currentPage) { + const response = await PostService.getAllSizes(currentPage.images); + setAllImgsSizes(response); + } + }); + + useEffect(() => { + if (!id || id < 1 || id > 100) { + navigate('/*', { replace: true }); + } + }, [id, navigate]); + useEffect(() => { fetchProductById(); }, [id]); + useMemo( + () => { + console.log('render memo'); + if (currentPage && currentPage.images.length !== 0) { + setCurrentImg(currentPage.images[currentPage.images.length - 1]); + setArrImg(currentPage.images); + getImgSizes(); + } + }, + [currentPage], + ); + + // useEffect(() => { + // i; + // }, [currentPage]); + + useEffect(() => { + setDataToLocalStorage(productsInCart); + }, [productsInCart]); + + useMemo(() => { + if (allImgsSizes.length && allImgsSizes.length > 1) { + console.log('again'); + checkUniqueImgs(allImgsSizes, arrImg, setCleanArrImg); + } + }, [allImgsSizes]); + + const handleBuyButtonClick = () => { + const isProductInCart = productsInCart.reduce((acc, el) => { + if (el.id === id) { + // eslint-disable-next-line no-param-reassign + acc = true; + return acc; + } + return acc; + }, false); + if (!isProductInCart) { + addToCart(id); + } + setFormVisible(true); + navigate('/cart', { replace: true }); + }; + if (isPending) { return ( -
- Is loading... +
+
); } @@ -51,19 +117,20 @@ function ProductPage({ return (
-
home
+ Home + >>
{currentPage?.category}
+ >>
{currentPage?.brand}
+ >>
{currentPage?.title}

{currentPage?.title}

- {currentPage?.title} -
- -
+ {currentPage?.title} +
@@ -104,7 +171,7 @@ function ProductPage({ {currentPage?.price} .00
- + void, +) { + const result = arrImgSizes.reduce((acc, el, index) => { + // if (!acc.includes(arrImg[index])) { + // acc = [...acc, arrImg[index]]; + // } + if ( + arrImgSizes.indexOf(el) + !== arrImgSizes.lastIndexOf(el) + && !acc.includes(arrImg[index]) + && !acc.includes(arrImg[arrImgSizes.indexOf(el)]) + ) { + acc = [...acc, arrImg[arrImgSizes.indexOf(el)]]; + return acc; + } + if (arrImgSizes.indexOf(el) === arrImgSizes.lastIndexOf(el) && !acc.includes(arrImg[index])) { + acc = [...acc, arrImg[index]]; + return acc; + } + return acc; + }, []); + + callBack(result); +} + +export default checkUniqueImgs; diff --git a/src/Components/utils/handleLocalStorage.ts b/src/Components/utils/handleLocalStorage.ts new file mode 100644 index 0000000..4ef7953 --- /dev/null +++ b/src/Components/utils/handleLocalStorage.ts @@ -0,0 +1,7 @@ +function handleLocalStorage() { + const currentProducts = window.localStorage.getItem('productsByTeamDiBu'); + if (currentProducts) return JSON.parse(currentProducts); + return []; +} + +export default handleLocalStorage; diff --git a/src/Components/utils/setDataToLocalStorage.ts b/src/Components/utils/setDataToLocalStorage.ts new file mode 100644 index 0000000..4037801 --- /dev/null +++ b/src/Components/utils/setDataToLocalStorage.ts @@ -0,0 +1,8 @@ +import { TProductPartialProps } from '../../types/types'; + +function setDataToLocalStorage(data:TProductPartialProps[]) { + const localStorageData = JSON.stringify(data); + window.localStorage.setItem('productsByTeamDiBu', localStorageData); +} + +export default setDataToLocalStorage; diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index f45a599..aaa21d1 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -10,6 +10,7 @@ } .summaryWrapper { + margin-top: 91px; width: 30%; display: flex; flex-direction: column; diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index bd277d8..6633f6c 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -10,6 +10,7 @@ import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; import Promo from '../../Components/Cart/Promo/Promo'; import Modal from '../../Components/Cart/PurchaseModal/Modal'; import Purchase from '../../Components/Cart/PurchaseModal/Purchase/Purchase'; +import LoadingSpinner from '../../Components/UI/LoadingSpinner'; // eslint-disable-next-line no-unused-vars import countTotalCost from '../../Components/utils/countTotalCost'; import countTotalCount from '../../Components/utils/countTotalCount'; @@ -20,18 +21,25 @@ import styles from './cart.module.scss'; type TCartProps = { productsInCart: TProductPartialProps[] + // eslint-disable-next-line no-unused-vars + setProductsInCart(arr: TProductPartialProps[]): void; isPending: boolean; productsInCartCount: TProductPartialProps[]; + // eslint-disable-next-line no-unused-vars + setProductsInCartCount(arr: TProductPartialProps[]): void; products: TProductsItem[] | null; // eslint-disable-next-line no-unused-vars increaseProductCount(event: React.MouseEvent): void; // eslint-disable-next-line no-unused-vars decreaseProductCount(event: React.MouseEvent): void; + formVisible: boolean; + // eslint-disable-next-line no-unused-vars + setFormVisible(bool:boolean): void; } function Cart(props: TCartProps) { const { - productsInCart, isPending, productsInCartCount, products, increaseProductCount, decreaseProductCount, + productsInCart, setProductsInCart, isPending, productsInCartCount, setProductsInCartCount, products, increaseProductCount, decreaseProductCount, formVisible, setFormVisible, } = props; const [totalCount, setTotalCount] = useState(countTotalCount(productsInCartCount)); const [totalCost, setTotalCost] = useState(0); @@ -39,7 +47,6 @@ function Cart(props: TCartProps) { const [isCodeAdd, setIsCodeAdd] = useState(false); const [codeAdded, setCodeAdded] = useState([]); // Подтверждение покупки - const [formVisible, setFormVisible] = useState(false); const [showAffirmative, setShowAffirmative] = useState(false); // Блок с пагинацией @@ -122,23 +129,29 @@ function Cart(props: TCartProps) { if (isPending) { return ( -
- Is loading... +
+
); } - if (!products?.length) { + if (showAffirmative) { return ( -
- Cart is empty -
+ ); } - if (showAffirmative) { + if (!products?.length) { return ( - +
+ Cart is empty +
); } diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 292784c..329f23d 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -5,6 +5,7 @@ import ProductsList from '../../Components/Main/ProductsList'; import { TProductPartialProps, TProductsItem } from '../../types/types'; import useSearchParamsObject from '../../hooks/useSearchParamsObject'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; +import setDataToLocalStorage from '../../Components/utils/setDataToLocalStorage'; type TMainProps = { productsInCart: TProductPartialProps[]; @@ -240,6 +241,10 @@ function Main(props: TMainProps) { navigator.clipboard.writeText(window.location.href); }; + useEffect(() => { + setDataToLocalStorage(productsInCart); + }, [productsInCart]); + return (
{isPending diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts index 0c0042d..04ec52a 100644 --- a/src/hooks/useValidation.ts +++ b/src/hooks/useValidation.ts @@ -142,7 +142,11 @@ const useValidation = (value: string, validations:TValidations) => { break; case 'isCardDateMonthInvalid': - if (!/^(0[1-9]|1[0-2])$/.test(value)) { + if (value.trim().length === 1 && !/^(0[1-9])$/.test(value.trim())) { + setIsCardDateMonthInvalid(true); + } else setIsCardDateMonthInvalid(false); + + if (value.trim().length > 1 && !/^(0[1-9]|1[0-2])$/.test(value)) { setIsCardDateMonthInvalid(true); } else setIsCardDateMonthInvalid(false); break; From e925e219e3542bcee69afb10e3f8d5a31089d8df Mon Sep 17 00:00:00 2001 From: dinara-n <33234957+dinara-n@users.noreply.github.com> Date: Mon, 9 Jan 2023 14:24:34 +0400 Subject: [PATCH 32/65] Main, 404 and Cart Styles (#12) * feat: add styles for main page, 404 and cart * feat: add small changes to styles Co-authored-by: Buffik <62429354+Buffik@users.noreply.github.com> --- public/index.html | 2 +- src/App/RootRouter/RootRouter.module.scss | 5 + src/App/RootRouter/index.tsx | 3 +- .../Cart/CartProduct/CartProduct.module.scss | 33 +++-- .../Cart/CartProduct/CartProduct.tsx | 20 +-- .../Cart/Pagination/CartPagination.tsx | 2 +- .../Pagination/cartPagination.module.scss | 30 ++-- .../Cart/Promo/handleCodes/code.module.scss | 10 +- src/Components/Cart/Promo/promo.module.scss | 6 +- .../Cart/PurchaseModal/Purchase/Purchase.tsx | 4 +- .../Purchase/purchase.module.scss | 33 +++-- src/Components/Footer/Footer.module.scss | 12 +- src/Components/Footer/index.tsx | 4 +- src/Components/Main/DualSlider.module.scss | 28 ++-- src/Components/Main/DualSlider.tsx | 18 ++- src/Components/Main/FiltersList.module.scss | 35 +++++ src/Components/Main/FiltersList.tsx | 97 ++++++------ src/Components/Main/ProductsList.module.scss | 119 +++++++++++++++ src/Components/Main/ProductsList.tsx | 100 ++++++++----- src/Components/UI/LoadingSpinner.module.scss | 6 +- src/Components/UI/LoadingSpinner.tsx | 8 +- .../button/ProductAddDropButton.module.scss | 5 + .../UI/button/ProductAddDropButton.tsx | 7 +- .../UI/button/ProductCartButton.module.scss | 4 +- .../UI/container/SiteContainer.module.scss | 10 ++ src/Components/UI/container/SiteContainer.tsx | 15 ++ src/Components/header/index.tsx | 49 ++++--- src/Components/header/styles.module.scss | 91 +++++++++--- src/Pages/Cart/cart.module.scss | 37 ++--- src/Pages/Cart/cart.tsx | 138 +++++++++--------- src/Pages/Main/Main.module.scss | 12 ++ src/Pages/Main/index.tsx | 69 ++++++--- .../PageNotFound/PageNotFound.module.scss | 24 +++ src/Pages/PageNotFound/index.tsx | 23 ++- src/assets/images/cart.svg | 12 ++ src/assets/images/empty.png | Bin 0 -> 4904 bytes src/index.scss | 89 ++++++++++- 37 files changed, 830 insertions(+), 330 deletions(-) create mode 100644 src/App/RootRouter/RootRouter.module.scss create mode 100644 src/Components/Main/FiltersList.module.scss create mode 100644 src/Components/Main/ProductsList.module.scss create mode 100644 src/Components/UI/button/ProductAddDropButton.module.scss create mode 100644 src/Components/UI/container/SiteContainer.module.scss create mode 100644 src/Components/UI/container/SiteContainer.tsx create mode 100644 src/Pages/Main/Main.module.scss create mode 100644 src/Pages/PageNotFound/PageNotFound.module.scss create mode 100644 src/assets/images/cart.svg create mode 100644 src/assets/images/empty.png diff --git a/public/index.html b/public/index.html index 0d77b13..c30a56e 100644 --- a/public/index.html +++ b/public/index.html @@ -10,7 +10,7 @@ content="Web site created using create-react-app" /> - React App + Online Store
diff --git a/src/App/RootRouter/RootRouter.module.scss b/src/App/RootRouter/RootRouter.module.scss new file mode 100644 index 0000000..43d54bd --- /dev/null +++ b/src/App/RootRouter/RootRouter.module.scss @@ -0,0 +1,5 @@ +.container { + display: flex; + flex-direction: column; + min-height: 100vh; +} \ No newline at end of file diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 97e30c4..5d3478d 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -7,6 +7,7 @@ import Cart from '../../Pages/Cart/cart'; import Main from '../../Pages/Main'; import PageNotFound from '../../Pages/PageNotFound'; import { TProductsItem, TProductPartialProps } from '../../types/types'; +import styles from './RootRouter.module.scss'; type TRootRouterProps = { isPending: boolean; @@ -46,7 +47,7 @@ export default function RootRouter(props: TRootRouterProps) { setFormVisible, } = props; return ( -
+

{description}

+
Category: {' '} - {category} + {rating}
Brand: {' '} - {brand} -
-
-
- Rating: - {' '} - {rating} -
-
- Discount: - {' '} + {discountPercentage} -
+ % +
- Available stock: + {'Available stock: '} {stock}
+
diff --git a/src/Components/Cart/Pagination/CartPagination.tsx b/src/Components/Cart/Pagination/CartPagination.tsx index 762b5bb..1847849 100644 --- a/src/Components/Cart/Pagination/CartPagination.tsx +++ b/src/Components/Cart/Pagination/CartPagination.tsx @@ -21,7 +21,7 @@ function CartPagination({ }: ICartPagination) { return (
- Limit: + Items on a page: {' '} handleProductsPerPage(e)} />
diff --git a/src/Components/Cart/Pagination/cartPagination.module.scss b/src/Components/Cart/Pagination/cartPagination.module.scss index d4f2bff..b1521e3 100644 --- a/src/Components/Cart/Pagination/cartPagination.module.scss +++ b/src/Components/Cart/Pagination/cartPagination.module.scss @@ -6,36 +6,38 @@ margin: 20px 0; } .text { - font-size: 20px; - font-weight: bold; - color: teal; - margin-right: 20px; + // font-size: 20px; + // font-weight: bold; + // color: teal; + margin-right: 15px; } .input { - color: teal; + // color: var(--accent-color); width: 55px; text-align: center; outline: none; - border: 1px solid teal; + border: 1px solid var(--accent-color); border-radius: 0.2rem; - font-size: 140%; + // font-size: 140%; margin-right: 20px; + padding: 5px 10px; } .paginateButton { - padding: 5px 15px; - color: teal; - font-size: 1.5rem; + padding: 5px 10px; + color: var(--accent-color); + // font-size: 1.5rem; background: transparent; - border: 1px solid teal; + border: 1px solid var(--accent-color); border-radius: 5px; cursor: pointer; margin: 5px; } .paginateText { - font-size: 20px; - font-weight: bold; - color: teal; + // font-size: 20px; + // font-weight: bold; + margin-right: 5px; + // color: teal; } \ No newline at end of file diff --git a/src/Components/Cart/Promo/handleCodes/code.module.scss b/src/Components/Cart/Promo/handleCodes/code.module.scss index 5e4b947..ba13b21 100644 --- a/src/Components/Cart/Promo/handleCodes/code.module.scss +++ b/src/Components/Cart/Promo/handleCodes/code.module.scss @@ -4,24 +4,24 @@ .buttonCode { padding: 5px 15px; - background-color: teal; + background-color: var(--accent-color); color: white; font-size: 14px; - border: 1px solid teal; + border: 1px solid var(--accent-color); border-radius: 5px; cursor: pointer; margin: 5px; &:hover { transition: all 0.3s; - color: teal; - background-color: white; + // color: teal; + background-color: var(--accent-hover-color); } } .textSummary { font-size: 2rem; font-weight: bold; - color: rgb(26, 180, 180) + color: var(--accent-color); } diff --git a/src/Components/Cart/Promo/promo.module.scss b/src/Components/Cart/Promo/promo.module.scss index d9e8787..059b931 100644 --- a/src/Components/Cart/Promo/promo.module.scss +++ b/src/Components/Cart/Promo/promo.module.scss @@ -14,13 +14,13 @@ .input { padding: 5px 15px; margin: 5px 0; - border: 1px solid teal; + border: 1px solid var(--accent-color); border-radius: 5px; - margin-bottom: 10px; + margin-bottom: 15px; } .textSummary { font-size: 1rem; font-weight: bold; - color: rgb(26, 180, 180); + color: var(--unimportant-color); } diff --git a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx index d736b6b..8431fe7 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx +++ b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx @@ -55,7 +55,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { return (
-

Personal details

+

Personal details

{(name.isDirty) && (
@@ -101,7 +101,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { )} email.onChange(e)} type="text" name="Email" placeholder="E-mail" />
-

Credit card details

+

Credit card details

{(cardNumber.isDirty) && (
diff --git a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss index b3d304f..0c2cfe0 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss +++ b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss @@ -9,6 +9,11 @@ align-items: center; } +.title { + font-size: 1.5rem; + margin-bottom: 20px; +} + .myInput { margin-bottom: 20px; width: 60%; @@ -23,7 +28,7 @@ display: flex; align-items: center; flex-direction: column; - border: 2px solid teal; + border: 1px solid var(--unimportant-color); border-radius: 10px; margin-bottom: 20px; } @@ -46,7 +51,7 @@ .cardNumberInput { font-size: 1.5rem; - border: 2px solid teal; + border: 1px solid var(--accent-color); border-radius: 10px; width: 75%; margin: auto 0; @@ -63,15 +68,18 @@ } .otherDataCVV { - width: 35px; + width: 60px; border-radius: 0.3rem; font-size: 1rem; padding: 5px; - border: 2px solid teal; + border: 1px solid var(--accent-color); margin-bottom: 0; &:focus { outline: 0; } + &::placeholder { + font-size: 0.85rem; + } } .otherDataExpirationWrapper { @@ -86,11 +94,12 @@ .dataExpiration { margin-right: 5px; display: flex; - border: 2px solid teal; + border: 1px solid var(--accent-color); border-radius: 5px; + font-size: 0.9rem; & input { text-align: center; - width: 30px; + width: 35px; border: 0; font-size: 1rem; padding: 5px; @@ -103,16 +112,16 @@ .formButton { cursor: pointer; - font-size: 2rem; - padding: 10px 20px; - background-color: teal; + font-size: 1.5rem; + padding: 10px 25px; + background-color: var(--accent-color); color: white; - border: 2px solid teal; + border: 1px solid var(--accent-color); border-radius: 10px; &:hover { transition: 0.3s all; - color: teal; - background-color: white; + // color: teal; + background-color: var(--accent-hover-color); } } diff --git a/src/Components/Footer/Footer.module.scss b/src/Components/Footer/Footer.module.scss index e833f36..d563696 100644 --- a/src/Components/Footer/Footer.module.scss +++ b/src/Components/Footer/Footer.module.scss @@ -1,13 +1,23 @@ .footer { + padding: 35px 0; width: 100%; + background-color: var(--footer-bg-color); display: flex; justify-content: center; } +.footer p { + color: var(--unimportant-color); +} + .container { width: 80%; - max-width: 800px; + max-width: 1000px; display: flex; justify-content: space-between; align-items: center; +} + +.footer__link { + color: var(--primary-font-color); } \ No newline at end of file diff --git a/src/Components/Footer/index.tsx b/src/Components/Footer/index.tsx index 2153dd0..aed0bb3 100644 --- a/src/Components/Footer/index.tsx +++ b/src/Components/Footer/index.tsx @@ -8,9 +8,9 @@ function Footer() {

{'Developed by '} - Buffik + Buffik {', '} - dinara-n + dinara-n

© 2023

diff --git a/src/Components/Main/DualSlider.module.scss b/src/Components/Main/DualSlider.module.scss index 1bbc496..5b13671 100644 --- a/src/Components/Main/DualSlider.module.scss +++ b/src/Components/Main/DualSlider.module.scss @@ -1,7 +1,3 @@ -:root { - --spinner-color: black; -} - .dualSlider { position: relative; } @@ -10,9 +6,11 @@ -webkit-appearance: none; width: 100%; background: transparent; - height: 2px; - background: black; + height: 4px; + background: var(--unimportant-color); + border-radius: 5px; position: absolute; + top: 10px; pointer-events: none; &:focus { @@ -47,11 +45,12 @@ width: 20px; height: 20px; border-radius: 50%; - background-color: black; + background-color: var(--accent-color); cursor: pointer; + transition: all 0.4s; &:hover { - background-color: darkblue; + background-color: var(--accent-hover-color); } } @@ -62,6 +61,17 @@ width: 20px; height: 20px; border-radius: 50%; - background-color: black; + background-color: var(--accent-color); cursor: pointer; + transition: all 0.4s; + + &:hover { + background-color: var(--accent-hover-color); + } +} + +.dualSlider__labels { + padding: 35px 10px 0 10px; + display: flex; + justify-content: space-between; } diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx index 5b16121..0b36bcd 100644 --- a/src/Components/Main/DualSlider.tsx +++ b/src/Components/Main/DualSlider.tsx @@ -51,14 +51,16 @@ function DualSlider(props: TDualSliderProps) { className={styles.slider} style={{ background: `${fillSlider(filter)}` }} /> -

{searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...filteredSearchedProducts.map((item) => item[filter])) : 0}

-

{searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...filteredSearchedProducts.map((item) => item[filter])) : 0}

-
+
+

+ € + {searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...filteredSearchedProducts.map((item) => item[filter])) : 0} +

+

+ € + {searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...filteredSearchedProducts.map((item) => item[filter])) : 0} +

+
); } diff --git a/src/Components/Main/FiltersList.module.scss b/src/Components/Main/FiltersList.module.scss new file mode 100644 index 0000000..0e4c373 --- /dev/null +++ b/src/Components/Main/FiltersList.module.scss @@ -0,0 +1,35 @@ +.filters { + width: 290px; + flex: 0 0 auto; +} + +.filter__title { + font-size: 1.12rem; + border-top: 1px solid var(--border-color); + padding: 20px 0 0; +} + +.filter__section { + margin-bottom: 20px; +} + +.filter__buttons { + display: flex; + justify-content: space-between; +} + +.filter__button { + width: 140px; + padding: 9.5px 20px; + background-color: var(--unimportant-bg-color); + color: var(--primary-font-color); + + &:hover { + background-color: var(--accent-active-color); + } +} + +.filter__label { + display: flex; + gap: 5px; +} diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index bac5b46..e7f78e6 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { TProductsItem } from '../../types/types'; import DualSlider from './DualSlider'; +import styles from './FiltersList.module.scss'; type TParamsObject = Record; @@ -44,51 +45,57 @@ function FiltersList(props: TFiltersListProps) { } = props; return ( -
- - -
- Category: +
+
+ + +
+

Category

+
    {categoriesList.map((category) => ( - +
  • + +
  • ))} -
-
- Brand: + +

Brand

+
    {brandsList.map((brand) => ( - +
  • + +
  • ))} -
-
- Price: + +

Price

+
-
-
- Stock: +
+

Stock

+
- +
); } diff --git a/src/Components/Main/ProductsList.module.scss b/src/Components/Main/ProductsList.module.scss new file mode 100644 index 0000000..7d790d0 --- /dev/null +++ b/src/Components/Main/ProductsList.module.scss @@ -0,0 +1,119 @@ +.products { + padding: 50px 0 0; + display: grid; + gap: 30px; +} + +.products_grid { + grid-template-columns: 1fr 1fr 1fr; +} + +.product { + box-sizing: content-box; + width: 250px; + // border: 1px solid var(--unimportant-color); + box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); + border-radius: 10px; + padding: 20px; +} + +.product__image { + object-fit: contain; + background-color: white; + border-radius: 10px; +} + +.product__title { + font-size: 1rem; + // margin-left: 5px; + // margin-right: 5px; +} + +.product__parameter { + display: flex; + justify-content: space-between; + // gap: 5px; + font-size: 0.9rem; + // margin: 0 5px; +} + +.product__parameter__title { + color: var(--unimportant-color); +} + +.product__parameter_price { + display: flex; + justify-content: space-between; + // margin: 0 5px; + margin-top: 5px; + margin-bottom: 15px; + font-size: 1.2rem; +} + +.product__parameter_price__title { + color: var(--unimportant-color); + font-size: 0.9rem; +} + +.product__title__link { + text-decoration: none; +} + +.product__buttonsContainer { + display: flex; + justify-content: space-between; +} + +.product__link { + display: block; + padding: 9.5px 27px; + width: 100px; + background-color: var(--accent-color); + border-radius: 10px; + color: white; + font-size: 0.9rem; + text-decoration: none; + align-items: center; + transition: all 0.4s; + + &:hover { + background-color: var(--accent-hover-color); + } +} + +.products_list .product { + width: 100%; + margin: 0 auto; + display: flex; + gap: 20px; +} + +.products_list .product__title { + margin-top: 0; +} + +.products_list .product__parameter { + justify-content: flex-start; + gap: 10px; +} + +.products_list .product__thirdColumn { + margin-left: auto; + display: flex; + flex-direction: column; + justify-content: flex-end; + gap: 10px; +} + +.product__parameter_price { + flex-direction: column; + align-items: flex-end; + gap: 10px; + font-size: 1.5rem; +} + +.products_list .product__buttonsContainer { + flex-direction: column-reverse; + gap: 15px; + align-items: flex-end; +} diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx index 2adec34..15755a6 100644 --- a/src/Components/Main/ProductsList.tsx +++ b/src/Components/Main/ProductsList.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Link } from 'react-router-dom'; import ProductAddDropButton from '../UI/button/ProductAddDropButton'; import { TProductsItem, TProductPartialProps } from '../../types/types'; +import styles from './ProductsList.module.scss'; type TProductsListProps = { productsInCart: TProductPartialProps[]; @@ -10,6 +11,7 @@ type TProductsListProps = { // eslint-disable-next-line no-unused-vars dropFromCart(id: number): void; products: TProductsItem[]; + view: string; } export default function ProductsList(props: TProductsListProps) { @@ -18,51 +20,69 @@ export default function ProductsList(props: TProductsListProps) { addToCart, dropFromCart, products, + view, } = props; + const productsView = (view === 'list') ? styles.products_list : styles.products_grid; return ( -
+
{ products.length ? products.map((product: TProductsItem) => ( -
-

{product.title}

- {product.title} -
-
Category:
-
{product.category}
-
-
-
Brand:
-
{product.brand}
-
-
-
Price:
-
- {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)} -
-
-
-
Discount:
-
- {product.discountPercentage} - % -
-
-
-
Rating:
-
{product.rating}
-
-
-
Stock:
-
{product.stock}
-
- - Details +
+ + {product.title} + +
+

+ {product.title} +

+
+
Category:
+
{product.category}
+
+
+
Brand:
+
{product.brand}
+
+
+
Discount:
+
+ {product.discountPercentage} + % +
+
+
+
Rating:
+
{product.rating}
+
+
+
Stock:
+
{product.stock}
+
+
+
+
+
Price:
+
+ {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)} +
+
+
+ + Details +
+
)) : 'No products found' diff --git a/src/Components/UI/LoadingSpinner.module.scss b/src/Components/UI/LoadingSpinner.module.scss index e4255de..1248eb6 100644 --- a/src/Components/UI/LoadingSpinner.module.scss +++ b/src/Components/UI/LoadingSpinner.module.scss @@ -1,4 +1,8 @@ -.container { +:root { + --spinner-color: var(--accent-color); +} + +.box { width: 55px; height: 55px; display: flex; diff --git a/src/Components/UI/LoadingSpinner.tsx b/src/Components/UI/LoadingSpinner.tsx index 2c21046..7315900 100644 --- a/src/Components/UI/LoadingSpinner.tsx +++ b/src/Components/UI/LoadingSpinner.tsx @@ -3,9 +3,11 @@ import styles from './LoadingSpinner.module.scss'; function LoadingSpinner() { return ( -
-
-
+
+
+
+
+
); } diff --git a/src/Components/UI/button/ProductAddDropButton.module.scss b/src/Components/UI/button/ProductAddDropButton.module.scss new file mode 100644 index 0000000..4e56154 --- /dev/null +++ b/src/Components/UI/button/ProductAddDropButton.module.scss @@ -0,0 +1,5 @@ +.button { + width: 140px; + padding: 9.5px 10px; + font-size: 0.9rem; +} \ No newline at end of file diff --git a/src/Components/UI/button/ProductAddDropButton.tsx b/src/Components/UI/button/ProductAddDropButton.tsx index 1131acf..876f216 100644 --- a/src/Components/UI/button/ProductAddDropButton.tsx +++ b/src/Components/UI/button/ProductAddDropButton.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { TProductPartialProps } from '../../../types/types'; +import styles from './ProductAddDropButton.module.scss'; type ProductAddDropButtonProps = { productId: number | undefined; @@ -34,7 +35,11 @@ function ProductAddDropButton(props: ProductAddDropButtonProps) { }; return ( - ); diff --git a/src/Components/UI/button/ProductCartButton.module.scss b/src/Components/UI/button/ProductCartButton.module.scss index 5db3e9d..c6cb57d 100644 --- a/src/Components/UI/button/ProductCartButton.module.scss +++ b/src/Components/UI/button/ProductCartButton.module.scss @@ -1,9 +1,9 @@ .myBtn { padding: 5px 15px; - color: teal; + color: var(--accent-color); font-size: 14px; background: transparent; - border: 1px solid teal; + border: 1px solid var(--accent-color); border-radius: 5px; cursor: pointer; margin: 5px; diff --git a/src/Components/UI/container/SiteContainer.module.scss b/src/Components/UI/container/SiteContainer.module.scss new file mode 100644 index 0000000..d145adb --- /dev/null +++ b/src/Components/UI/container/SiteContainer.module.scss @@ -0,0 +1,10 @@ +.container { + width: 80%; + max-width: 1200px; + margin: 0 auto; + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} \ No newline at end of file diff --git a/src/Components/UI/container/SiteContainer.tsx b/src/Components/UI/container/SiteContainer.tsx new file mode 100644 index 0000000..7cdcc84 --- /dev/null +++ b/src/Components/UI/container/SiteContainer.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import styles from './SiteContainer.module.scss'; + +type TSiteContainer = { + children: React.ReactNode; +} + +function SiteContainer(props: TSiteContainer) { + const { children } = props; + return ( +
{children}
+ ); +} + +export default SiteContainer; diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 768f614..0fbec3c 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -1,10 +1,11 @@ -import React, { useMemo } from 'react'; +// import React, { useMemo } from 'react'; import { NavLink } from 'react-router-dom'; // тут стили импортированы при помощи модулей, это один из способов подключения стилей. // В таком случае в компонентах можно использовать повторяющиеся названия для стилей, // т.к. к ним присоединиться случайный хеш и на самом деле название стиля будет отличаться import styles from './styles.module.scss'; import { TProductsItem, TProductPartialProps } from '../../types/types'; +import cart from '../../assets/images/cart.svg'; type TProps = { // productsInCart: TProductPartialProps[]; @@ -26,12 +27,12 @@ export default function Header(props: TProps) { // ниже функция которая навешивает определенный стиль исходя их переменной isActive, // это встроенная переменная в элементе NavLink // NavLink мы взяли из react-router-dom - const activeStyles = useMemo( - () => (bool: boolean) => (bool - ? styles.header__navigation__link__active - : styles.header__navigation__link), - [], - ); + // const activeStyles = useMemo( + // () => (bool: boolean) => (bool + // ? styles.header__navigation__link__active + // : styles.header__navigation__link), + // [], + // ); const cartTotal = products?.reduce((acc, elem) => { const productInCart = productsInCart.find((item) => item.id === elem.id); @@ -42,12 +43,12 @@ export default function Header(props: TProps) { }, 0); return ( -
+
-
+ ); } diff --git a/src/Components/header/styles.module.scss b/src/Components/header/styles.module.scss index 47dbf1d..886259a 100644 --- a/src/Components/header/styles.module.scss +++ b/src/Components/header/styles.module.scss @@ -1,21 +1,72 @@ .header { - height: 100px; - background-color: red; - &__navigation { - display: flex; - height: 100%; - align-items: center; - &__link { - display: block; - margin-left: 50px; - color: white; - text-decoration: none; - &__active { - display: block; - text-decoration: underline; - margin-left: 50px; - color: black; - } - } - } -} \ No newline at end of file + // min-height: 100px; + padding: 35px 0; + display: flex; + justify-content: center; + align-items: center; +} + +.header__navigation { + width: 80%; + max-width: 1000px; + display: flex; + justify-content: space-between; + align-items: center; +} + +.header__navigation__logo { + text-decoration: none; + text-transform: uppercase; + font-size: 1.2rem; + color: var(--accent-color); + transition: all 0.4s; + + &:hover { + color: var(--accent-hover-color); + } +} + +.header__navigation__link { + display: block; + margin-left: 50px; + // color: white; + text-decoration: none; + &__active { + display: block; + text-decoration: underline; + margin-left: 50px; + // color: black; + } +} + +.header__navigation__total { + color: var(--unimportant-color); +} + +.header__navigation__total__price { + color: var(--accent-color); + // font-weight: bold; + font-size: 1.2rem; +} + +.header__navigation__cart { + position: relative; +} + +.header__navigation__cart__items { + position: absolute; + top: -5px; + left: 15px; + padding: 3px 5px 1px; + font-size: 0.8rem; + line-height: 0.8rem; + vertical-align: center; + background-color: var(--accent-color); + border-radius: 50%; + color: #ffffff; + transition: all 0.4s; +} + +.header__navigation__cart:hover .header__navigation__cart__items { + background-color: var(--accent-hover-color); +} diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index aaa21d1..600ec06 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -1,5 +1,5 @@ .wrapper { - width: 95%; + // width: 95%; margin: auto; display: flex; justify-content: space-between; @@ -15,55 +15,58 @@ display: flex; flex-direction: column; align-items: center; - border: 2px solid teal; + // border: 1px solid var(--accent-color); + box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); border-radius: 10px; height: 100%; - + margin-top: 25px; + padding: 15px 30px 30px; } .textSummary { - font-size: 2rem; + font-size: 1.5rem; font-weight: bold; - color: rgb(26, 180, 180); + color: var(--accent-color); + margin-top: 5px; margin-bottom: 10px; } .textSummaryLineThrough { - font-size: 2rem; + font-size: 1.5rem; font-weight: bold; - color: rgb(26, 180, 180); + color: var(--accent-color); margin-bottom: 10px; text-decoration: line-through; } .textSummaryWithDiscount { - font-size: 2.5rem; + font-size: 1.7rem; font-weight: bold; - color: rgb(26, 180, 180); + color: var(--accent-color); margin-bottom: 10px; } .textProducts, .textTotal { margin-bottom: 10px; - font-size: 2rem; + font-size: 1.5rem; font-weight: bold; - color: teal + // color: teal } .byuButton { - font-size: 2rem; - padding: 5px 15px; - background-color: teal; + font-size: 1.5rem; + padding: 10px 25px; + background-color: var(--accent-color); color: white; - border: 1px solid teal; + border: 1px solid var(--accent-color); border-radius: 5px; cursor: pointer; margin: 5px; &:hover { transition: all 0.3s; - color: teal; - background-color: white; + color: white; + background-color: var(--accent-hover-color); } } \ No newline at end of file diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 6633f6c..c3ec6a8 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -10,6 +10,7 @@ import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; import Promo from '../../Components/Cart/Promo/Promo'; import Modal from '../../Components/Cart/PurchaseModal/Modal'; import Purchase from '../../Components/Cart/PurchaseModal/Purchase/Purchase'; +import SiteContainer from '../../Components/UI/container/SiteContainer'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; // eslint-disable-next-line no-unused-vars import countTotalCost from '../../Components/utils/countTotalCost'; @@ -129,15 +130,9 @@ function Cart(props: TCartProps) { if (isPending) { return ( -
+ -
+ ); } @@ -149,77 +144,78 @@ function Cart(props: TCartProps) { if (!products?.length) { return ( -
- Cart is empty -
+ Cart is empty ); } return ( -
-
- - { currentProducts?.map((product: TProductsItem, index) => ( - - ))} -
-
-

Summary

-
- Products: - {' '} - {totalCount} + +
+
+ + { currentProducts?.map((product: TProductsItem, index) => ( + + ))}
-
- Total: - {' '} - € - {' '} - {totalCost} - .00 -
- {isCodeAdd ? ( -
-
- Total: - {' '} - € - {' '} - {countTotalSumWithDiscounts(totalCost, codeAdded)} -
-
Applied codes
+
+

Summary

+
+ Products: + {' '} + {totalCount} +
+
+ Total: + {' '} + € + {' '} + {totalCost} + .00 +
+ {isCodeAdd ? (
- {codeAdded.map((discount) => )} +
+ Total: + {' '} + € + {' '} + {countTotalSumWithDiscounts(totalCost, codeAdded)} +
+
Applied codes
+
+ {codeAdded.map((discount) => )} +
-
- ) :

No applied codes

} - - + ) :

No applied codes

} + + +
+ + + +
- - - - -
+ + ); } diff --git a/src/Pages/Main/Main.module.scss b/src/Pages/Main/Main.module.scss new file mode 100644 index 0000000..be8a7cb --- /dev/null +++ b/src/Pages/Main/Main.module.scss @@ -0,0 +1,12 @@ +.main { + margin: 10px 0 50px; + width: 100%; + display: flex; + gap: 50px; +} + +.findSortContainer { + display: flex; + justify-content: space-between; + align-items: center; +} diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index 329f23d..fcdfd58 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -5,8 +5,11 @@ import ProductsList from '../../Components/Main/ProductsList'; import { TProductPartialProps, TProductsItem } from '../../types/types'; import useSearchParamsObject from '../../hooks/useSearchParamsObject'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; +import SiteContainer from '../../Components/UI/container/SiteContainer'; +import styles from './Main.module.scss'; import setDataToLocalStorage from '../../Components/utils/setDataToLocalStorage'; + type TMainProps = { productsInCart: TProductPartialProps[]; // eslint-disable-next-line no-unused-vars @@ -90,8 +93,8 @@ function Main(props: TMainProps) { // let filteredSearchedProducts: TProductsItem[] = products.slice(); const fillSlider = (filter: 'price' | 'stock') => { - const sliderColor = '#999999'; - const rangeColor = '#000000'; + const sliderColor = '#b9b9b9'; + const rangeColor = '#2CB708'; const max = Math.max(...products.map((item) => item[filter])); const min = Math.min(...products.map((item) => item[filter])); const valueMin = Number(searchParamsObject[`${[filter]}range`]?.split(',')[0]); @@ -241,26 +244,31 @@ function Main(props: TMainProps) { navigator.clipboard.writeText(window.location.href); }; + + const handleViewChange = (event: React.ChangeEvent) => { + const param = (event.target.id === 'products-view-list') ? 'list' : 'grid'; + setSearchParamsObject({ ...searchParamsObject, view: param }); + }; + + const productsView = (searchParamsObject?.view === 'list' || searchParamsObject?.view === 'grid') ? searchParamsObject.view : 'grid'; + + useEffect(() => { + setSearchParamsObject({ ...searchParamsObject, view: 'grid' }); + }, []); + useEffect(() => { setDataToLocalStorage(productsInCart); }, [productsInCart]); + return ( -
+ {isPending ? ( -
- -
+ ) : ( -
+
-
-
- +
+
+

{'Found: '} {filteredSearchedSortedProducts.length} @@ -292,17 +306,38 @@ function Main(props: TMainProps) { + +

)} -
+ ); } diff --git a/src/Pages/PageNotFound/PageNotFound.module.scss b/src/Pages/PageNotFound/PageNotFound.module.scss new file mode 100644 index 0000000..8ec2a67 --- /dev/null +++ b/src/Pages/PageNotFound/PageNotFound.module.scss @@ -0,0 +1,24 @@ +.main { + flex-grow: 1; + display: flex; + flex-direction: column; + justify-content: center; +} + +.message { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.title { + margin-top: 30px; + margin-bottom: 50px; + font-size: 2rem; + color: var(--accent-color); +} + +.text { + margin-bottom: 10px; +} \ No newline at end of file diff --git a/src/Pages/PageNotFound/index.tsx b/src/Pages/PageNotFound/index.tsx index 95c1d94..538bce7 100644 --- a/src/Pages/PageNotFound/index.tsx +++ b/src/Pages/PageNotFound/index.tsx @@ -1,11 +1,26 @@ import React from 'react'; +import { NavLink } from 'react-router-dom'; +import SiteContainer from '../../Components/UI/container/SiteContainer'; +import styles from './PageNotFound.module.scss'; +import emptyBox from '../../assets/images/empty.png'; function PageNotFound() { return ( -
-

404 Page Not Found!

-

This page does not seem to exist.

-
+
+ +
+ +

404 Page Not Found!

+

This page does not seem to exist.

+ + Back to main + +
+
+
); } diff --git a/src/assets/images/cart.svg b/src/assets/images/cart.svg new file mode 100644 index 0000000..6c6d3ff --- /dev/null +++ b/src/assets/images/cart.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/images/empty.png b/src/assets/images/empty.png new file mode 100644 index 0000000000000000000000000000000000000000..ef25b1c51a4026044f37e40c0257cd7d8193db0b GIT binary patch literal 4904 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 a%>M(?_x#3ggE_MR0000 Date: Mon, 9 Jan 2023 13:29:16 +0300 Subject: [PATCH 33/65] fix: empty lines after merge --- src/Components/Cart/CartProduct/CartProduct.tsx | 3 +-- src/Pages/Main/index.tsx | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index 2172fec..18cf6d8 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-unused-vars */ /* eslint-disable max-len */ import React from 'react'; import { Link } from 'react-router-dom'; @@ -46,8 +47,6 @@ function CartProduct(props:TProductsCart) {

{title}


{description}

- -
Category: {' '} diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index fcdfd58..f26fa7e 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -9,7 +9,6 @@ import SiteContainer from '../../Components/UI/container/SiteContainer'; import styles from './Main.module.scss'; import setDataToLocalStorage from '../../Components/utils/setDataToLocalStorage'; - type TMainProps = { productsInCart: TProductPartialProps[]; // eslint-disable-next-line no-unused-vars @@ -244,7 +243,6 @@ function Main(props: TMainProps) { navigator.clipboard.writeText(window.location.href); }; - const handleViewChange = (event: React.ChangeEvent) => { const param = (event.target.id === 'products-view-list') ? 'list' : 'grid'; setSearchParamsObject({ ...searchParamsObject, view: param }); @@ -260,7 +258,6 @@ function Main(props: TMainProps) { setDataToLocalStorage(productsInCart); }, [productsInCart]); - return ( {isPending From 108d61e9fd9c204ab1b5b8c79db6c3c60706487a Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:45:42 +0300 Subject: [PATCH 34/65] Styling product page (#14) * feat: end styling product page * fix: top margin at cart and product page * feat: add new container to cart and product page * fix: styles in cart --- .../Cart/CartProduct/CartProduct.module.scss | 21 +++ .../Cart/CartProduct/CartProduct.tsx | 44 ++++-- .../Cart/Promo/handleCodes/AddCode.tsx | 2 +- .../CarouselImages/CarouselImages.module.scss | 10 ++ .../CarouselImages/CarouselImages.tsx | 4 +- .../ProductImagesCarousel.module.scss | 30 ++++ .../ProductImagesCarousel.tsx | 40 ++++-- src/Components/ProductPage/ProductPage.tsx | 130 +++++++++--------- .../ProductPage/productPage.module.scss | 64 +++++++-- .../container/CartContainer/CartContainer.tsx | 15 ++ .../CartContainer/cartContainer.module.scss | 9 ++ src/Pages/Cart/cart.module.scss | 3 +- src/Pages/Cart/cart.tsx | 7 +- 13 files changed, 278 insertions(+), 101 deletions(-) create mode 100644 src/Components/UI/container/CartContainer/CartContainer.tsx create mode 100644 src/Components/UI/container/CartContainer/cartContainer.module.scss diff --git a/src/Components/Cart/CartProduct/CartProduct.module.scss b/src/Components/Cart/CartProduct/CartProduct.module.scss index bbb2fdc..63bb050 100644 --- a/src/Components/Cart/CartProduct/CartProduct.module.scss +++ b/src/Components/Cart/CartProduct/CartProduct.module.scss @@ -33,10 +33,16 @@ width: 100%; height: 2px; background-color: var(--accent-color); + border-color: var(--accent-color); border-radius: 5px; } } +.infoHeader { + text-align: center; + line-height: 2rem; +} + .infoImg { max-width: 200px; height: auto; @@ -59,6 +65,21 @@ margin-bottom: 10px; } +.subtitlesWrapper { + width: 100%; + display: flex; + justify-content: space-between; +} + +.subtitlesWrapperFirstLine, +.subtitlesWrapperSecondLine { + max-width: 45%; +} + +.infoHeaders { + color: var(--accent-color); +} + .textStock { margin-bottom: 10px; } diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index 18cf6d8..adcf391 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -44,21 +44,39 @@ function CartProduct(props:TProductsCart) { {title}
-

{title}

+

{title}


{description}

-
- Category: - {' '} - {rating} -
-
- Brand: - {' '} - - {discountPercentage} - % - +
+
+
+ Category: + {' '} + {category} +
+
+ Brand: + {' '} + + {brand} + +
+
+
+
+ Rating: + {' '} + {rating} +
+
+ Discount: + {' '} + + {discountPercentage} + % + +
+
diff --git a/src/Components/Cart/Promo/handleCodes/AddCode.tsx b/src/Components/Cart/Promo/handleCodes/AddCode.tsx index bba7c97..2959486 100644 --- a/src/Components/Cart/Promo/handleCodes/AddCode.tsx +++ b/src/Components/Cart/Promo/handleCodes/AddCode.tsx @@ -7,7 +7,7 @@ function AddCode({ }: IAddHandler) { return (
- {`Code "${code}", discount - ${discount}%`} + {`Code "${code}" -${discount}%`}
); diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss index e69de29..abae571 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss +++ b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss @@ -0,0 +1,10 @@ +.carouselImg { + object-fit: contain; + min-width: 180px; + max-width: 180px; + max-height: 100px; + cursor: pointer; + margin: 5px; + border: 2px solid black; + border-radius: 5px; +} \ No newline at end of file diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx index 6441432..c61fa79 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx +++ b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx @@ -11,9 +11,7 @@ interface ICarouselImages { function CarouselImages({ value, setCurrentImg }: ICarouselImages) { return ( -
- setCurrentImg(value)} alt="product" /> -
+ setCurrentImg(value)} alt="product" /> ); } diff --git a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss index e69de29..e92e697 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss +++ b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss @@ -0,0 +1,30 @@ +.carouselWrapper { + max-width: 400px; + display: flex; + min-height: 100px; + align-items: center; +} + +.carouselButton { + padding: 12px; + &:last-of-type { + margin-left: 5px; + } +} + +.carousel { + width: 340px; + display: flex; + flex-wrap: nowrap; + overflow: hidden; + +} + +.carouselData { + display: flex; + flex-wrap: nowrap; + transition: translate; + transition-property: transform; + transition-duration: 0.3s; + transition-timing-function: ease-in-out; +} \ No newline at end of file diff --git a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx index 5e86fca..56c2a27 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx +++ b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import CarouselImages from './CarouselImages/CarouselImages'; import styles from './ProductImagesCarousel.module.scss'; @@ -9,14 +9,38 @@ interface IProductImagesCarousel { } function ProductImagesCarousel({ cleanArrImg, setCurrentImg }: IProductImagesCarousel) { - return ( -
- { - cleanArrImg.map( - (img) => , - ) -} + const amountOfImgs = cleanArrImg.length; + const IMAGE_WIDTH = 190; + + // eslint-disable-next-line no-unused-vars + const [currentOffset, setCurrentOffset] = useState(0); + const handleLeftArrowClick = (px: number) => { + const newOffset = px + IMAGE_WIDTH; + const result = Math.min(newOffset, 0); + setCurrentOffset(result); + }; + + const handleRightArrowClick = (px: number) => { + const newOffset = px - IMAGE_WIDTH; + const containerWidth = -(IMAGE_WIDTH * (amountOfImgs - 1)); + const result = Math.max(newOffset, containerWidth); + setCurrentOffset(result); + }; + + return ( +
+ +
+
+ { + cleanArrImg.map( + (img) => , + ) + } +
+
+
); } diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index 99d7056..47d5d7e 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -5,6 +5,8 @@ import useFetching from '../../hooks/useFetching'; import { TProductPartialProps, TProductsItemWithImages } from '../../types/types'; import PostService from '../API/PostService'; import ProductAddDropButton from '../UI/button/ProductAddDropButton'; +import CartContainer from '../UI/container/CartContainer/CartContainer'; +import SiteContainer from '../UI/container/SiteContainer'; import LoadingSpinner from '../UI/LoadingSpinner'; import checkUniqueImgs from '../utils/checkUniqueImgs'; import setDataToLocalStorage from '../utils/setDataToLocalStorage'; @@ -59,7 +61,6 @@ function ProductPage({ useMemo( () => { - console.log('render memo'); if (currentPage && currentPage.images.length !== 0) { setCurrentImg(currentPage.images[currentPage.images.length - 1]); setArrImg(currentPage.images); @@ -79,7 +80,6 @@ function ProductPage({ useMemo(() => { if (allImgsSizes.length && allImgsSizes.length > 1) { - console.log('again'); checkUniqueImgs(allImgsSizes, arrImg, setCleanArrImg); } }, [allImgsSizes]); @@ -115,73 +115,77 @@ function ProductPage({ } return ( -
-
- Home - >> -
{currentPage?.category}
- >> -
{currentPage?.brand}
- >> -
{currentPage?.title}
-
-
-

{currentPage?.title}

-
-
- {currentPage?.title} - -
-
-
- Stock: - {' '} - {currentPage?.stock} -
-
- Brand: - {' '} - {currentPage?.stock} -
-
- Description: - {' '} - {currentPage?.description} -
-
- Rating: - {' '} - {currentPage?.rating} -
-
- Category: - {' '} - {currentPage?.category} + +
+
+ Home + >> +
{currentPage?.category}
+ >> +
{currentPage?.brand}
+ >> +
{currentPage?.title}
+
+
+

{currentPage?.title}

+
+
+
+ {currentPage?.title} +
+ {cleanArrImg.length > 1 + && }
-
- Discount Percentage: - {' '} - {currentPage?.discountPercentage} +
+
+ Available stock: + {' '} + {currentPage?.stock} +
+
+ Brand: + {' '} + {currentPage?.brand} +
+
+ {currentPage?.description} +
+
+ Rating: + {' '} + {currentPage?.rating} +
+
+ Category: + {' '} + {currentPage?.category} +
+
+ Discount: + {' '} + {currentPage?.discountPercentage} + % +
-
-
-
- Price € - {' '} - {currentPage?.price} - .00 +
+
+ Price € + {' '} + {currentPage?.price} + .00 +
+ +
- -
-
+ ); } diff --git a/src/Components/ProductPage/productPage.module.scss b/src/Components/ProductPage/productPage.module.scss index 7226102..0e240de 100644 --- a/src/Components/ProductPage/productPage.module.scss +++ b/src/Components/ProductPage/productPage.module.scss @@ -1,5 +1,5 @@ .wrapper { - margin: auto; + margin: 0 auto; padding: 0 30px; max-width: 1220px; display: flex; @@ -10,7 +10,7 @@ .breedsWrapper { color:#B9B9B9; text-align: center; - margin: 0 auto; + margin: 0 auto 30px auto;; display: flex; max-width: 800px; justify-content: center; @@ -18,18 +18,17 @@ font-size: 20px; & a { text-decoration: none; - color:#333232; + color: var(--accent-color); &:hover { transition: all ease 0.3s; - color: teal; + color: var(--accent-hover-color); } } } .breedsItems { - color: teal; + color: var(--accent-color);; font-size: 25px; - font-weight: bold; margin: 0 30px; } @@ -51,12 +50,59 @@ margin-right: 20px; } -.imagesCarouselWrapper { +.mainImgWrapper { + width: 400px; + height: 400px; + display: flex; + align-items: center; + justify-content: center; + background-color: white; + border: 1px solid var(--unimportant-color); + border-radius: 10px; + margin-bottom: 20px; +} + +.mainImg { + width: 100%; + max-height: 100%; + object-fit:contain; + border-radius: 10px; +} +.infoWrapper { + width: 100%; + margin-right: 20px; } -// styles for info +.infoText { + margin-bottom: 20px; +} + +.infoHeaders { + color: var(--accent-color); +} + +.infoDescription { + margin-bottom: 20px; + text-align: center; + font-weight: bold; +} .buttonsWrapper { - + padding: 20px 25px; + min-width: 290px; + min-height: 165px; + max-height: 165px; + box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); + border-radius: 10px; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; +} + +.productPrice { + font-size: 1.5rem; + font-weight: bold; + color: var(--primary-font-color); } \ No newline at end of file diff --git a/src/Components/UI/container/CartContainer/CartContainer.tsx b/src/Components/UI/container/CartContainer/CartContainer.tsx new file mode 100644 index 0000000..18e0d43 --- /dev/null +++ b/src/Components/UI/container/CartContainer/CartContainer.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import styles from './cartContainer.module.scss'; + +type TSiteContainer = { + children: React.ReactNode; +} + +function CartContainer(props: TSiteContainer) { + const { children } = props; + return ( +
{children}
+ ); +} + +export default CartContainer; diff --git a/src/Components/UI/container/CartContainer/cartContainer.module.scss b/src/Components/UI/container/CartContainer/cartContainer.module.scss new file mode 100644 index 0000000..7512217 --- /dev/null +++ b/src/Components/UI/container/CartContainer/cartContainer.module.scss @@ -0,0 +1,9 @@ +.container { + width: 80%; + max-width: 1200px; + margin: 0 auto; + flex-grow: 1; + display: flex; + flex-direction: column; + align-items: center; +} \ No newline at end of file diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index 600ec06..be7d64d 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -1,6 +1,6 @@ .wrapper { // width: 95%; - margin: auto; + margin: 0 auto; display: flex; justify-content: space-between; } @@ -40,6 +40,7 @@ } .textSummaryWithDiscount { + text-align: center; font-size: 1.7rem; font-weight: bold; color: var(--accent-color); diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index c3ec6a8..ab8b4df 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -10,6 +10,7 @@ import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; import Promo from '../../Components/Cart/Promo/Promo'; import Modal from '../../Components/Cart/PurchaseModal/Modal'; import Purchase from '../../Components/Cart/PurchaseModal/Purchase/Purchase'; +import CartContainer from '../../Components/UI/container/CartContainer/CartContainer'; import SiteContainer from '../../Components/UI/container/SiteContainer'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; // eslint-disable-next-line no-unused-vars @@ -149,7 +150,7 @@ function Cart(props: TCartProps) { } return ( - +
@@ -197,7 +198,7 @@ function Cart(props: TCartProps) { {' '} {countTotalSumWithDiscounts(totalCost, codeAdded)}
-
Applied codes
+
Applied codes
{codeAdded.map((discount) => )}
@@ -214,7 +215,7 @@ function Cart(props: TCartProps) {
-
+ ); } From 8d8faaaaf4b0482fc7868752bf4c091c1d22a921 Mon Sep 17 00:00:00 2001 From: Buffik Date: Mon, 9 Jan 2023 20:12:44 +0300 Subject: [PATCH 35/65] feat: add styles to empty cart --- src/Pages/Cart/cart.module.scss | 19 +++++++++++++++++++ src/Pages/Cart/cart.tsx | 11 +++++++++-- src/assets/images/emptyCart.svg | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/assets/images/emptyCart.svg diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index be7d64d..87a7b2e 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -70,4 +70,23 @@ color: white; background-color: var(--accent-hover-color); } +} + +.emptyWrapper { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.emptyImg { + width: 140px; + transform: translateX(-12px); +} + +.emptyTitle { + margin-top: 30px; + margin-bottom: 50px; + font-size: 2rem; + color: var(--accent-color); } \ No newline at end of file diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index ab8b4df..a2d85d9 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,6 +1,6 @@ /* eslint-disable max-len */ import React, { useState, useEffect } from 'react'; -import { useSearchParams } from 'react-router-dom'; +import { useSearchParams, Link } from 'react-router-dom'; import ApprovePurchase from '../../Components/Cart/ApprovePerchase/ApprovePurchase'; // import React, { useEffect, useState } from 'react'; // import PostService from '../../Components/API/PostService'; @@ -20,6 +20,7 @@ import countTotalSumWithDiscounts from '../../Components/utils/countTotalSumWith // import useFetching from '../../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../../types/types'; import styles from './cart.module.scss'; +import emptyCartImg from '../../assets/images/emptyCart.svg'; type TCartProps = { productsInCart: TProductPartialProps[] @@ -145,7 +146,13 @@ function Cart(props: TCartProps) { if (!products?.length) { return ( - Cart is empty + +
+ +

Cart is empty

+ Back to main +
+
); } diff --git a/src/assets/images/emptyCart.svg b/src/assets/images/emptyCart.svg new file mode 100644 index 0000000..d5278c5 --- /dev/null +++ b/src/assets/images/emptyCart.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + \ No newline at end of file From 022e26e90887cd117dc5c8b18980bbd2b167c8e6 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Tue, 10 Jan 2023 02:04:26 +0300 Subject: [PATCH 36/65] Fix form bugs (#15) * fix: names of promocodes at promo block * fix: phone validation * fix: month & year & card number & cvv validation --- .../Cart/Promo/handleCodes/DeleteCode.tsx | 4 ++-- .../Cart/Promo/handleCodes/code.module.scss | 1 + .../Cart/PurchaseModal/Purchase/Purchase.tsx | 16 ++++++++-------- .../PurchaseModal/Purchase/purchase.module.scss | 17 ++++++++++++++++- src/Components/utils/handleInputPhone.ts | 16 ++++++++++++++++ src/Pages/Cart/cart.tsx | 2 +- src/hooks/useInput.ts | 6 +++--- src/hooks/useValidation.ts | 9 ++++++--- src/index.scss | 1 + src/types/types.ts | 1 + 10 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 src/Components/utils/handleInputPhone.ts diff --git a/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx b/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx index 123ebcc..d7e201e 100644 --- a/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx +++ b/src/Components/Cart/Promo/handleCodes/DeleteCode.tsx @@ -3,11 +3,11 @@ import { IPromoCodeHandler } from '../../../../types/types'; import styles from './code.module.scss'; function DeleteCode({ - todo, discount, setCode, + todo, code, discount, setCode, }: IPromoCodeHandler) { return (
- {`Your discount - ${discount}%!`} + {`"${code}" discount - ${discount}%!`}
); diff --git a/src/Components/Cart/Promo/handleCodes/code.module.scss b/src/Components/Cart/Promo/handleCodes/code.module.scss index ba13b21..78f292d 100644 --- a/src/Components/Cart/Promo/handleCodes/code.module.scss +++ b/src/Components/Cart/Promo/handleCodes/code.module.scss @@ -1,5 +1,6 @@ .textCode { font-size: 1rem; + text-align: center; } .buttonCode { diff --git a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx index 8431fe7..ba3670a 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx +++ b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx @@ -68,7 +68,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { )}
)} - name.onChange(e)} value={name.value} type="text" name="Name" placeholder="Name" /> + name.onChange(e.currentTarget.value)} value={name.value} type="text" name="Name" placeholder="Name" /> {(phone.isDirty) && (
@@ -78,7 +78,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { {phone.isPhoneInvalid &&
!! Should contains only digits !!
}
)} - phone.onChange(e)} value={phone.value} type="text" name="Phone" placeholder="Phone" /> + phone.onChange(e.currentTarget.value)} value={phone.value} type="text" name="Phone" placeholder="Phone" /> {(address.isDirty) && (
@@ -91,7 +91,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { )}
)} - address.onChange(e)} type="text" name="Address" placeholder="Delivery address" /> + address.onChange(e.currentTarget.value)} type="text" name="Address" placeholder="Delivery address" /> {(email.isDirty) && (
@@ -99,7 +99,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { {email.isMailInvalid &&
!! E-mail should be correct !!
}
)} - email.onChange(e)} type="text" name="Email" placeholder="E-mail" /> + email.onChange(e.currentTarget.value)} type="text" name="Email" placeholder="E-mail" />

Credit card details

{(cardNumber.isDirty) @@ -120,7 +120,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { )}
- cardNumber.onChange(e)} type="text" name="cardNumber" placeholder="Card number" className={styles.cardNumberInput} /> + cardNumber.onChange(e.currentTarget.value)} type="number" name="cardNumber" placeholder="Card number" className={styles.cardNumberInput} />
{(cardMonth.isDirty) && ( @@ -136,16 +136,16 @@ function Purchase({ setShowAffirmative }: IPurchase) {
Date:
- cardMonth.onChange(e)} type="text" name="month" placeholder="MM" /> + cardMonth.onChange(e.currentTarget.value)} type="number" name="month" placeholder="MM" /> / - cardYear.onChange(e)} type="text" name="year" placeholder="YY" /> + cardYear.onChange(e.currentTarget.value)} type="number" name="year" placeholder="YY" />
{' '} CVV: {' '} - cardCVV.onChange(e)} type="text" name="cardCVV" placeholder="CVV" className={styles.otherDataCVV} /> + cardCVV.onChange(e.currentTarget.value)} type="number" name="cardCVV" placeholder="CVV" className={styles.otherDataCVV} />
diff --git a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss index 0c2cfe0..6f3373b 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss +++ b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss @@ -58,8 +58,21 @@ &:focus { outline: 0; } + } +.cardNumberInput::-webkit-inner-spin-button, +.cardNumberInput::-webkit-outer-spin-button, +.dataExpirationMonth::-webkit-inner-spin-button, +.dataExpirationMonth::-webkit-outer-spin-button, +.dataExpirationYear::-webkit-inner-spin-button, +.dataExpirationYear::-webkit-outer-spin-button, +.otherDataCVV::-webkit-inner-spin-button, +.otherDataCVV::-webkit-outer-spin-button { + -webkit-appearance: none; +} + + .otherData { display: flex; width: 300px; @@ -94,6 +107,7 @@ .dataExpiration { margin-right: 5px; display: flex; + align-items: center; border: 1px solid var(--accent-color); border-radius: 5px; font-size: 0.9rem; @@ -101,6 +115,7 @@ text-align: center; width: 35px; border: 0; + border-radius: 5px; font-size: 1rem; padding: 5px; margin-bottom: 0; @@ -126,12 +141,12 @@ } .errorTextWrapper { - color: red; width: 75%; display: flex; flex-wrap: wrap; justify-content: center; & > div { padding: 0 10px 5px 10px; + color: var(--error-color) } } diff --git a/src/Components/utils/handleInputPhone.ts b/src/Components/utils/handleInputPhone.ts new file mode 100644 index 0000000..7db0541 --- /dev/null +++ b/src/Components/utils/handleInputPhone.ts @@ -0,0 +1,16 @@ +function handleInputPhone(data: string) { + if (data.length > 0) { + const checkedStr = data.slice(0, 1); + if (checkedStr === '+' && data.length > 2) { + const lastChar = checkedStr.slice(-1); + if (/[0-9]/.test(lastChar)) { + console.log(true); + return data; + } + return data.slice(0, data.length - 1); + } + } + return data; +} + +export default handleInputPhone; diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index a2d85d9..6d80d64 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -207,7 +207,7 @@ function Cart(props: TCartProps) {
Applied codes
- {codeAdded.map((discount) => )} + {codeAdded.map((discount) => )}
) :

No applied codes

} diff --git a/src/hooks/useInput.ts b/src/hooks/useInput.ts index 4162920..34764bd 100644 --- a/src/hooks/useInput.ts +++ b/src/hooks/useInput.ts @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { TValidations } from '../types/types'; import useValidation from './useValidation'; @@ -13,8 +13,8 @@ const useInput = (initialValue: string, runValidate: boolean, validations: TVali } else setIsDirty(false); }, [runValidate]); - const onChange = (e: React.FormEvent) => { - setValue(e.currentTarget.value); + const onChange = (data: string) => { + setValue(data); }; return { diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts index 04ec52a..f52f1e9 100644 --- a/src/hooks/useValidation.ts +++ b/src/hooks/useValidation.ts @@ -93,7 +93,7 @@ const useValidation = (value: string, validations:TValidations) => { case 'isPhoneInvalid': value.split('').forEach((char, index) => { if (index !== 0) { - if (!/[0-9]/.test(char)) { + if (!/^\+?([0-9]{2})\)?[-. ]?([0-9]{4})[-. ]?([0-9]{4})$/.test(value)) { setIsPhoneInvalid(true); } else setIsPhoneInvalid(false); } @@ -142,11 +142,14 @@ const useValidation = (value: string, validations:TValidations) => { break; case 'isCardDateMonthInvalid': - if (value.trim().length === 1 && !/^(0[1-9])$/.test(value.trim())) { + if (value.trim().length === 1 && !/^([1-9])$/.test(value.trim())) { + console.log('here'); setIsCardDateMonthInvalid(true); + break; } else setIsCardDateMonthInvalid(false); - if (value.trim().length > 1 && !/^(0[1-9]|1[0-2])$/.test(value)) { + if (value.trim().length > 1 && !/^(1[012]|0?[1-9])$/.test(value)) { + console.log('there'); setIsCardDateMonthInvalid(true); } else setIsCardDateMonthInvalid(false); break; diff --git a/src/index.scss b/src/index.scss index 4a86c47..3c5735d 100644 --- a/src/index.scss +++ b/src/index.scss @@ -8,6 +8,7 @@ --footer-bg-color: #EEF1F2; --border-color: #EAEAEA; --unimportant-bg-color: #EFEFEF; + --error-color: #EB8528; } * { diff --git a/src/types/types.ts b/src/types/types.ts index 74ec734..941777c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -42,6 +42,7 @@ export type TPromoCodesArr = { export interface IPromoCodeHandler { todo: string + code: string discount: number // eslint-disable-next-line no-unused-vars, no-undef setCode: (event: React.MouseEvent, isAdd: boolean) => void From e480e2fc2d2b5653826f1d12bb68e88f958e9c18 Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 10 Jan 2023 03:13:25 +0400 Subject: [PATCH 37/65] feat: add some styles and icons --- public/apple-touch-icon.png | Bin 0 -> 9015 bytes public/favicon.ico | Bin 3870 -> 15406 bytes public/index.html | 5 ++- public/logo192.png | Bin 5347 -> 0 bytes public/logo512.png | Bin 9664 -> 0 bytes src/Components/Main/ProductsList.module.scss | 34 +++++++++++++----- src/Components/Main/ProductsList.tsx | 4 +-- .../button/ProductAddDropButton.module.scss | 13 ++++++- .../UI/button/ProductAddDropButton.tsx | 8 +++-- src/Components/header/styles.module.scss | 13 +++++++ src/Pages/Main/index.tsx | 6 ++-- src/assets/images/logo-icon.png | Bin 0 -> 4612 bytes 12 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 public/apple-touch-icon.png delete mode 100644 public/logo192.png delete mode 100644 public/logo512.png create mode 100644 src/assets/images/logo-icon.png diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..446f45c4ab0c10d6f85bbc0c36e7f420a77c578f GIT binary patch literal 9015 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 literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ diff --git a/public/index.html b/public/index.html index c30a56e..074536b 100644 --- a/public/index.html +++ b/public/index.html @@ -3,13 +3,16 @@ + + + - + Online Store diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5347 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/src/Components/Main/ProductsList.module.scss b/src/Components/Main/ProductsList.module.scss index 7d790d0..a196ddd 100644 --- a/src/Components/Main/ProductsList.module.scss +++ b/src/Components/Main/ProductsList.module.scss @@ -1,24 +1,37 @@ .products { padding: 50px 0 0; - display: grid; + box-sizing: content-box; + // display: grid; + display: flex; + flex-direction: column; gap: 30px; } .products_grid { - grid-template-columns: 1fr 1fr 1fr; + // grid-template-columns: 1fr 1fr 1fr; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-evenly; + + @media (max-width: 999px) { + // grid-template-columns: 1fr 1fr; + } } .product { box-sizing: content-box; - width: 250px; + width: 200px; // border: 1px solid var(--unimportant-color); box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); border-radius: 10px; padding: 20px; + display: flex; + flex-direction: column; + justify-content: space-between; } .product__image { - object-fit: contain; + object-fit: cover; background-color: white; border-radius: 10px; } @@ -64,10 +77,14 @@ justify-content: space-between; } +.product__buttonsContainer button { + width: 120px; +} + .product__link { display: block; - padding: 9.5px 27px; - width: 100px; + padding: 9.5px 13px; + width: 70px; background-color: var(--accent-color); border-radius: 10px; color: white; @@ -82,9 +99,10 @@ } .products_list .product { - width: 100%; + width: 90%; margin: 0 auto; - display: flex; + // display: flex; + flex-direction: row; gap: 20px; } diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx index 15755a6..2e442a5 100644 --- a/src/Components/Main/ProductsList.tsx +++ b/src/Components/Main/ProductsList.tsx @@ -34,8 +34,8 @@ export default function ProductsList(props: TProductsListProps) { className={styles.product__image} src={product.thumbnail} alt={product.title} - width={250} - height={187.5} + width={200} + height={150} />
diff --git a/src/Components/UI/button/ProductAddDropButton.module.scss b/src/Components/UI/button/ProductAddDropButton.module.scss index 4e56154..8088edb 100644 --- a/src/Components/UI/button/ProductAddDropButton.module.scss +++ b/src/Components/UI/button/ProductAddDropButton.module.scss @@ -1,5 +1,16 @@ .button { width: 140px; - padding: 9.5px 10px; + padding: 7.5px 9px; font-size: 0.9rem; + border: 1px solid var(--accent-color); +} + +.button_drop { + background-color: transparent; + color: var(--accent-color); + + &:hover { + background-color: var(--accent-color); + color: white; + } } \ No newline at end of file diff --git a/src/Components/UI/button/ProductAddDropButton.tsx b/src/Components/UI/button/ProductAddDropButton.tsx index 876f216..6fb0217 100644 --- a/src/Components/UI/button/ProductAddDropButton.tsx +++ b/src/Components/UI/button/ProductAddDropButton.tsx @@ -26,8 +26,10 @@ function ProductAddDropButton(props: ProductAddDropButtonProps) { return false; }; + const inCart = isProductInCart(productId); + const handleClick = (): void => { - if (isProductInCart(productId)) { + if (inCart) { dropFromCart(productId); } else { addToCart(productId); @@ -36,11 +38,11 @@ function ProductAddDropButton(props: ProductAddDropButtonProps) { return ( ); } diff --git a/src/Components/header/styles.module.scss b/src/Components/header/styles.module.scss index 886259a..d4e3497 100644 --- a/src/Components/header/styles.module.scss +++ b/src/Components/header/styles.module.scss @@ -20,10 +20,23 @@ font-size: 1.2rem; color: var(--accent-color); transition: all 0.4s; + display: flex; + gap: 5px; + align-items: center; &:hover { color: var(--accent-hover-color); } + + &::before { + content: ""; + background-image: url("../../assets/images/logo-icon.png"); + background-repeat: no-repeat; + background-position: center center; + background-size: contain; + width: 30px; + height: 30px; + } } .header__navigation__link { diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index f26fa7e..b852f41 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -250,9 +250,9 @@ function Main(props: TMainProps) { const productsView = (searchParamsObject?.view === 'list' || searchParamsObject?.view === 'grid') ? searchParamsObject.view : 'grid'; - useEffect(() => { - setSearchParamsObject({ ...searchParamsObject, view: 'grid' }); - }, []); + // useEffect(() => { + // setSearchParamsObject({ ...searchParamsObject, view: 'grid' }); + // }, []); useEffect(() => { setDataToLocalStorage(productsInCart); diff --git a/src/assets/images/logo-icon.png b/src/assets/images/logo-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..434f5342fd74a4138158756a64917fe0bcfb5fc0 GIT binary patch literal 4612 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 Date: Tue, 10 Jan 2023 02:52:06 +0300 Subject: [PATCH 38/65] Fix val phone number (#17) * fix: validating phone number * fix: styles at ApprovePurchase component --- .../Cart/ApprovePerchase/ApprovePurchase.tsx | 21 ++++++++++++------- ...module.css => approvePurchase.module.scss} | 4 ++-- src/hooks/useValidation.ts | 10 +++------ 3 files changed, 18 insertions(+), 17 deletions(-) rename src/Components/Cart/ApprovePerchase/{approvePurchase.module.css => approvePurchase.module.scss} (69%) diff --git a/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx b/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx index 75f0dce..3100acf 100644 --- a/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx +++ b/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx @@ -1,7 +1,9 @@ import React, { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { TProductPartialProps } from '../../../types/types'; -import styles from './approvePurchase.module.css'; +import SiteContainer from '../../UI/container/SiteContainer'; +import LoadingSpinner from '../../UI/LoadingSpinner'; +import styles from './approvePurchase.module.scss'; interface IApprovePurchase { showAffirmative: boolean @@ -29,16 +31,19 @@ function ApprovePurchase({ setProductsInCart([]); setProductsInCartCount([]); history('/', { replace: true }); - }, 3000); + }, 5000); }, []); } return ( -

- Thank you dor order! redirecting in - {' '} - {time} - s... -

+ +

+ Thank you for the order! Redirecting in + {' '} + {time} + s... +

+ +
); } diff --git a/src/Components/Cart/ApprovePerchase/approvePurchase.module.css b/src/Components/Cart/ApprovePerchase/approvePurchase.module.scss similarity index 69% rename from src/Components/Cart/ApprovePerchase/approvePurchase.module.css rename to src/Components/Cart/ApprovePerchase/approvePurchase.module.scss index 204ce83..865dac0 100644 --- a/src/Components/Cart/ApprovePerchase/approvePurchase.module.css +++ b/src/Components/Cart/ApprovePerchase/approvePurchase.module.scss @@ -1,11 +1,11 @@ .text { - color: teal; + color: var(--accent-color); display: flex; justify-content: center; align-items: center; - position: fixed; top: 0; bottom: 0; right: 0; left: 0; + margin-bottom: 30px; } \ No newline at end of file diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts index f52f1e9..6464af7 100644 --- a/src/hooks/useValidation.ts +++ b/src/hooks/useValidation.ts @@ -91,13 +91,9 @@ const useValidation = (value: string, validations:TValidations) => { break; case 'isPhoneInvalid': - value.split('').forEach((char, index) => { - if (index !== 0) { - if (!/^\+?([0-9]{2})\)?[-. ]?([0-9]{4})[-. ]?([0-9]{4})$/.test(value)) { - setIsPhoneInvalid(true); - } else setIsPhoneInvalid(false); - } - }); + if (!/^[\s()+-]*([0-9][\s()+-]*){6,20}$/.test(value)) { + setIsPhoneInvalid(true); + } else setIsPhoneInvalid(false); break; case 'minLengthAddress': From 2f42391f95455359a33c727e605121ba3c9de9f0 Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 10 Jan 2023 13:50:15 +0400 Subject: [PATCH 39/65] fix: fix filters on main page --- src/Components/Main/DualSlider.module.scss | 2 +- src/Components/Main/DualSlider.tsx | 17 +++--- src/Components/Main/FiltersList.module.scss | 38 +++++++++++- src/Components/Main/FiltersList.tsx | 47 ++++++++------- src/Components/Main/ProductsList.module.scss | 24 +++++++- src/Pages/Main/Main.module.scss | 2 +- src/Pages/Main/index.tsx | 59 ++++++++++--------- src/Pages/PageNotFound/index.tsx | 2 +- src/assets/images/checkmark.png | Bin 0 -> 447 bytes 9 files changed, 129 insertions(+), 62 deletions(-) create mode 100644 src/assets/images/checkmark.png diff --git a/src/Components/Main/DualSlider.module.scss b/src/Components/Main/DualSlider.module.scss index 5b13671..2f6c066 100644 --- a/src/Components/Main/DualSlider.module.scss +++ b/src/Components/Main/DualSlider.module.scss @@ -7,7 +7,7 @@ width: 100%; background: transparent; height: 4px; - background: var(--unimportant-color); + background: var(--accent-color); border-radius: 5px; position: absolute; top: 10px; diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx index 0b36bcd..12c1bd1 100644 --- a/src/Components/Main/DualSlider.tsx +++ b/src/Components/Main/DualSlider.tsx @@ -13,7 +13,7 @@ type TDualSliderProps = { filteredSearchedProducts: TProductsItem[] | []; searchParamsObject: Record; // eslint-disable-next-line no-unused-vars - fillSlider(filter: 'price' | 'stock'): string; + // fillSlider(filter: 'price' | 'stock'): string; } function DualSlider(props: TDualSliderProps) { @@ -25,9 +25,12 @@ function DualSlider(props: TDualSliderProps) { handleSliderMaxInput, filteredSearchedProducts, searchParamsObject, - fillSlider, + // fillSlider, } = props; + const filtered = filteredSearchedProducts.map((item) => item[filter]); + const arr = (filtered.length > 0) ? filtered : [0]; + return (
item[filter]))} max={Math.max(...products.map((item) => item[filter]))} - value={searchParamsObject[`${filter}range`]?.split(',')[0] ?? Math.min(...filteredSearchedProducts.map((item) => item[filter]))} + value={searchParamsObject[`${filter}range`]?.split(',')[0] ?? Math.min(...arr)} onInput={handleSliderMinInput} className={[styles.slider, styles.sliderMin].join(' ')} /> @@ -46,19 +49,19 @@ function DualSlider(props: TDualSliderProps) { id={`${sliderId}-max`} min={Math.min(...products.map((item) => item[filter]))} max={Math.max(...products.map((item) => item[filter]))} - value={searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? Math.max(...filteredSearchedProducts.map((item) => item[filter]))} + value={searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? Math.max(...arr)} onInput={handleSliderMaxInput} className={styles.slider} - style={{ background: `${fillSlider(filter)}` }} + // style={{ background: `${fillSlider(filter)}` }} />

€ - {searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...filteredSearchedProducts.map((item) => item[filter])) : 0} + {searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...arr) : 0}

€ - {searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...filteredSearchedProducts.map((item) => item[filter])) : 0} + {searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...arr) : 0}

diff --git a/src/Components/Main/FiltersList.module.scss b/src/Components/Main/FiltersList.module.scss index 0e4c373..1b3a5b9 100644 --- a/src/Components/Main/FiltersList.module.scss +++ b/src/Components/Main/FiltersList.module.scss @@ -1,6 +1,10 @@ .filters { width: 290px; flex: 0 0 auto; + + @media (max-width: 1199px) { + width: 220px; + } } .filter__title { @@ -13,6 +17,11 @@ margin-bottom: 20px; } +ul.filter__section { + max-height: 250px; + overflow-y: auto; +} + .filter__buttons { display: flex; justify-content: space-between; @@ -27,9 +36,36 @@ &:hover { background-color: var(--accent-active-color); } + + @media (max-width: 1199px) { + width: 100px; + } } .filter__label { display: flex; - gap: 5px; + align-items: center; + gap: 10px; + // margin-bottom: 5px; + margin-top: -10px; + cursor: pointer; + + &::before { + content: ""; + width: 20px; + height: 20px; + border: 1px solid var(--unimportant-color); + border-radius: 2px; + background-image: url("../../assets/images/checkmark.png"); + background-repeat: no-repeat; + background-position: -100px -100px; + } } + +input[type="checkbox"] { + appearance: none; +} + +input[type="checkbox"]:checked + .filter__label::before { + background-position: center center; +} \ No newline at end of file diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index e7f78e6..173b666 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -24,7 +24,7 @@ type TFiltersListProps = { handleSliderMaxInput(event: React.ChangeEvent): void copied: boolean; // eslint-disable-next-line no-unused-vars - fillSlider(filter: 'price' | 'stock'): string; + // fillSlider(filter: 'price' | 'stock'): string; } function FiltersList(props: TFiltersListProps) { @@ -41,7 +41,7 @@ function FiltersList(props: TFiltersListProps) { handleSliderMinInput, handleSliderMaxInput, copied, - fillSlider, + // fillSlider, } = props; return ( @@ -54,7 +54,7 @@ function FiltersList(props: TFiltersListProps) {
    {categoriesList.map((category) => (
  • -
  • ))}
@@ -76,7 +79,7 @@ function FiltersList(props: TFiltersListProps) {
    {brandsList.map((brand) => (
  • -
  • ))}
@@ -104,7 +111,7 @@ function FiltersList(props: TFiltersListProps) { handleSliderMaxInput={handleSliderMaxInput} searchParamsObject={searchParamsObject} filteredSearchedProducts={filteredSearchedProducts} - fillSlider={fillSlider} + // fillSlider={fillSlider} />

Stock

@@ -117,7 +124,7 @@ function FiltersList(props: TFiltersListProps) { handleSliderMaxInput={handleSliderMaxInput} searchParamsObject={searchParamsObject} filteredSearchedProducts={filteredSearchedProducts} - fillSlider={fillSlider} + // fillSlider={fillSlider} />
diff --git a/src/Components/Main/ProductsList.module.scss b/src/Components/Main/ProductsList.module.scss index a196ddd..88ba7d7 100644 --- a/src/Components/Main/ProductsList.module.scss +++ b/src/Components/Main/ProductsList.module.scss @@ -11,7 +11,8 @@ // grid-template-columns: 1fr 1fr 1fr; flex-direction: row; flex-wrap: wrap; - justify-content: space-evenly; + // justify-content: space-evenly; + padding-left: 40px; @media (max-width: 999px) { // grid-template-columns: 1fr 1fr; @@ -98,14 +99,26 @@ } } +.products.products_list { + + // @media (max-width: 1199px) { + // padding-left: 0; + // } +} + .products_list .product { - width: 90%; + width: 85%; margin: 0 auto; // display: flex; flex-direction: row; gap: 20px; } +.products_list .product__image { + // width: 250px; + height: 175px; +} + .products_list .product__title { margin-top: 0; } @@ -130,6 +143,13 @@ font-size: 1.5rem; } +// .products_list .product__parameter_price { + +// @media (max-width: 1199px) { +// font-size: 1.2rem; +// } +// } + .products_list .product__buttonsContainer { flex-direction: column-reverse; gap: 15px; diff --git a/src/Pages/Main/Main.module.scss b/src/Pages/Main/Main.module.scss index be8a7cb..446645b 100644 --- a/src/Pages/Main/Main.module.scss +++ b/src/Pages/Main/Main.module.scss @@ -9,4 +9,4 @@ display: flex; justify-content: space-between; align-items: center; -} +} \ No newline at end of file diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index b852f41..c0aa7d1 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -48,7 +48,7 @@ function Main(props: TMainProps) { paramsObject: TParamsObject, ) => { if (typeof param === 'number') { - return false; + return paramsObject[paramName] !== undefined; } if (!paramsObject[paramName]) { return false; @@ -58,7 +58,8 @@ function Main(props: TMainProps) { const getFilterParams = (source: TProductsItem[], paramName: TFilterOptions) => { if (paramName === 'price' || paramName === 'stock') { - const arr = source.map((item) => item[paramName]); + let arr = source.map((item) => item[paramName]); + arr = (arr.length > 0) ? arr : [0]; return [Math.min(...arr), Math.max(...arr)]; } const set = new Set(source.map((item) => item[paramName])); @@ -91,37 +92,37 @@ function Main(props: TMainProps) { // let filteredSearchedProducts: TProductsItem[] = products.slice(); - const fillSlider = (filter: 'price' | 'stock') => { - const sliderColor = '#b9b9b9'; - const rangeColor = '#2CB708'; - const max = Math.max(...products.map((item) => item[filter])); - const min = Math.min(...products.map((item) => item[filter])); - const valueMin = Number(searchParamsObject[`${[filter]}range`]?.split(',')[0]); - const valueMax = Number(searchParamsObject[`${[filter]}range`]?.split(',')[1]); - const rangeDistance = max - min; - const fromPosition = valueMin - min; - const toPosition = valueMax - min; - return `linear-gradient( - to right, - ${sliderColor} 0%, - ${sliderColor} ${((fromPosition) / (rangeDistance)) * 100}%, - ${rangeColor} ${((fromPosition) / (rangeDistance)) * 100}%, - ${rangeColor} ${((toPosition) / (rangeDistance)) * 100}%, - ${sliderColor} ${((toPosition) / (rangeDistance)) * 100}%, - ${sliderColor} 100%)`; - }; + // const fillSlider = (filter: 'price' | 'stock') => { + // const sliderColor = '#b9b9b9'; + // const rangeColor = '#2CB708'; + // const max = Math.max(...products.map((item) => item[filter])); + // const min = Math.min(...products.map((item) => item[filter])); + // const valueMin = Number(searchParamsObject[`${[filter]}range`]?.split(',')[0]); + // const valueMax = Number(searchParamsObject[`${[filter]}range`]?.split(',')[1]); + // const rangeDistance = max - min; + // const fromPosition = valueMin - min; + // const toPosition = valueMax - min; + // return `linear-gradient( + // to right, + // ${sliderColor} 0%, + // ${sliderColor} ${((fromPosition) / (rangeDistance)) * 100}%, + // ${rangeColor} ${((fromPosition) / (rangeDistance)) * 100}%, + // ${rangeColor} ${((toPosition) / (rangeDistance)) * 100}%, + // ${sliderColor} ${((toPosition) / (rangeDistance)) * 100}%, + // ${sliderColor} 100%)`; + // }; const getMinPrice = (source: TProductsItem[], param: 'price' | 'stock') => { if (source.length !== 0) { return Math.min(...source.map((item) => item[param])); } - return undefined; + return [0]; }; const getMaxPrice = (source: TProductsItem[], param: 'price' | 'stock') => { if (source.length !== 0) { return Math.max(...source.map((item) => item[param])); } - return undefined; + return [0]; }; const handleSliderMinInput = (event: React.ChangeEvent) => { @@ -129,7 +130,7 @@ function Main(props: TMainProps) { const minValue = Number(event.target.value); const maxValue = Number(searchParamsObject[`${param}range`]?.split(',')[1] ?? getMaxPrice(products, param)); setSearchParamsObject({ ...searchParamsObject, [`${param}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); - fillSlider('price'); + // fillSlider('price'); }; const handleSliderMaxInput = (event: React.ChangeEvent) => { @@ -137,7 +138,7 @@ function Main(props: TMainProps) { const minValue = Number(searchParamsObject[`${param}range`]?.split(',')[0] ?? getMinPrice(products, param)); const maxValue = Number(event.target.value); setSearchParamsObject({ ...searchParamsObject, [`${param}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); - fillSlider('stock'); + // fillSlider('stock'); }; const handleSearchChange = (event: React.ChangeEvent) => { @@ -231,8 +232,8 @@ function Main(props: TMainProps) { const handleResetClick = () => { setSearchParamsObject({}); - fillSlider('price'); - fillSlider('stock'); + // fillSlider('price'); + // fillSlider('stock'); }; const [copied, setCopied] = useState(false); @@ -279,7 +280,7 @@ function Main(props: TMainProps) { handleSliderMinInput={handleSliderMinInput} handleSliderMaxInput={handleSliderMaxInput} copied={copied} - fillSlider={fillSlider} + // fillSlider={fillSlider} />
@@ -290,7 +291,7 @@ function Main(props: TMainProps) { placeholder="Find products..." aria-label="Find products." /> -

+

{'Found: '} {filteredSearchedSortedProducts.length}

diff --git a/src/Pages/PageNotFound/index.tsx b/src/Pages/PageNotFound/index.tsx index 538bce7..87398f4 100644 --- a/src/Pages/PageNotFound/index.tsx +++ b/src/Pages/PageNotFound/index.tsx @@ -10,7 +10,7 @@ function PageNotFound() {
-

404 Page Not Found!

+

Error 404: Page Not Found!

This page does not seem to exist.

Px$c}YY;R5(wilRHZTK^(;ApVQpKLPRS;un{3%K(J6m5Q|72ih^SA7tj=fjimuW zMDqaztpp#1sCULfB-jWF1}_1{I*pYU$z6=Qk~5LSym8B8=Ev;L9O0jbn)UZzDc#O2 zn_>hj?lbqB0;mzu14ah`Izb2-UURKsfO;t|gVPoOp{xC$WG`3BYv-XKS0-8w*%3#g96m$w4B%o&WasDL4k7CsWB{ zjh#T%#A6W609fym%+SpQvTjY8<-|?^IPB!arwy-l@wYV_;MT<>4w|=967CqM9RlA4 zpx6dZVZ)yeR;v65aNgd*1uF)ir(8ralc$GY{jjP6Y=|a}bHa5#azXnA<`^*osrzb! zD``R1;d7HuvPsoYwnS pDh|n|OJfP2d0Wri@RVzTz5#8QcM%n9FjD{k002ovPDHLkV1jCRyiouE literal 0 HcmV?d00001 From f814686fe5764763dac4e1d74be9d1bb267171fe Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 10 Jan 2023 20:23:51 +0400 Subject: [PATCH 40/65] fix: upgrade footer --- src/Components/Footer/Footer.module.scss | 18 ++++++++++++++++++ src/Components/Footer/index.tsx | 4 ++-- src/assets/images/github-mark.svg | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 src/assets/images/github-mark.svg diff --git a/src/Components/Footer/Footer.module.scss b/src/Components/Footer/Footer.module.scss index d563696..3d951b4 100644 --- a/src/Components/Footer/Footer.module.scss +++ b/src/Components/Footer/Footer.module.scss @@ -18,6 +18,24 @@ align-items: center; } +.linksContainer { + display: flex; + align-items: center; +} + .footer__link { color: var(--primary-font-color); + margin-left: 8px; + display: flex; + align-items: center; + gap: 4px; + + &::before { + content: ""; + width: 18px; + height: 18px; + background-image: url("../../assets/images/github-mark.svg"); + background-repeat: no-repeat; + background-size: contain; + } } \ No newline at end of file diff --git a/src/Components/Footer/index.tsx b/src/Components/Footer/index.tsx index aed0bb3..fe58151 100644 --- a/src/Components/Footer/index.tsx +++ b/src/Components/Footer/index.tsx @@ -6,13 +6,13 @@ function Footer() { return (
-

+

{'Developed by '} Buffik {', '} dinara-n

-

© 2023

+

Online Store © 2023

diff --git a/src/assets/images/github-mark.svg b/src/assets/images/github-mark.svg new file mode 100644 index 0000000..37fa923 --- /dev/null +++ b/src/assets/images/github-mark.svg @@ -0,0 +1 @@ + \ No newline at end of file From 059b753c99571cdd7180dedff9f7d263fe9c5239 Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 10 Jan 2023 21:15:23 +0400 Subject: [PATCH 41/65] feat: add styles to products view options on main page --- src/Pages/Main/Main.module.scss | 46 ++++++++++++++++++++++++++++++- src/Pages/Main/index.tsx | 29 ++++++++++++------- src/assets/images/grid-green.png | Bin 0 -> 196 bytes src/assets/images/grid-grey.png | Bin 0 -> 201 bytes src/assets/images/list-green.png | Bin 0 -> 192 bytes src/assets/images/list-grey.png | Bin 0 -> 193 bytes 6 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 src/assets/images/grid-green.png create mode 100644 src/assets/images/grid-grey.png create mode 100644 src/assets/images/list-green.png create mode 100644 src/assets/images/list-grey.png diff --git a/src/Pages/Main/Main.module.scss b/src/Pages/Main/Main.module.scss index 446645b..019e389 100644 --- a/src/Pages/Main/Main.module.scss +++ b/src/Pages/Main/Main.module.scss @@ -9,4 +9,48 @@ display: flex; justify-content: space-between; align-items: center; -} \ No newline at end of file +} + +.productsView { + display: flex; + gap: 5px; + align-items: center; +} + +.productsView input[type="radio"] { + appearance: none; +} + +.productsView label { + display: block; + width: 24px; + height: 24px; + background-repeat: no-repeat; + background-size: contain; + background-position: center; + cursor: pointer; +} + +.productsView__label_grid { + background-image: url("../../assets/images/grid-grey.png"); + + &::before { + background-image: url("../../assets/images/grid-green.png"); + } +} + +.productsView input[type="radio"]:checked + .productsView__label_grid { + background-image: url("../../assets/images/grid-green.png"); +} + +.productsView__label_list { + background-image: url("../../assets/images/list-grey.png"); + + &::before { + background-image: url("../../assets/images/list-green.png"); + } +} + +.productsView input[type="radio"]:checked + .productsView__label_list { + background-image: url("../../assets/images/list-green.png"); +} diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index c0aa7d1..be69d0c 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/label-has-associated-control */ import React, { ChangeEvent, useEffect, useState } from 'react'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; @@ -304,26 +305,34 @@ function Main(props: TMainProps) { -
O5T>Lp;2b zuiQLWIHj@iU>BpP%+5zY4~wa}bV|9+eJk_-A`g4<`ig%EE}I&1Oc#p@@VEsC$fhME zY;f#r|IfqIzP{?;2Ins3O;-=ZHs~%|sc6Qdvp_{yaI&QPXU4#v4R4CtW_-#rSuA+w t&6e{g7fbdAY_+oK;@Xt0os?zEz&rJfyy_{}wLq6Jc)I$ztaD0e0s#K6NB;l- literal 0 HcmV?d00001 diff --git a/src/assets/images/grid-grey.png b/src/assets/images/grid-grey.png new file mode 100644 index 0000000000000000000000000000000000000000..690348996dd755736bb4d846128adf5463bb02db GIT binary patch literal 201 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|nmt_{Lp;3S zPQA$0pupo=Ua!6C`p=W^ZvI;5+Nc<)c{a{v{u86J)Y~%!CQj{O^XglrcW$Sq*EETa zj%6nw&z(6@qNeX9+fAcG)$$BI)9qN&<}FU^w2Uvf{z58>nN6(2E8&gI6U!g9;*knk yjT;&Hvequ#;}#pE6Dny&qhw;9U6e3>cJJ*frg90pHUKbLh*2~7Z9(oC=b literal 0 HcmV?d00001 diff --git a/src/assets/images/list-green.png b/src/assets/images/list-green.png new file mode 100644 index 0000000000000000000000000000000000000000..0bce1adb1cbd9fc51539f6730b217d77866fedaa GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|sytmBLp;2b zuiQLWIHj@iU>BpP%+5zY4~wa^ILrB3`n?l$oBLMg|3=UFkADtwY-Lz&v(c<4%E4fX zgJa1IpnA5*r}b=Yhr?~_Z#X_?aGtkdWdN%}@c}_kZv!43iL)6kLMJ|)IJsDoH{a&6 noqB)TmWw@XS=$0a7Be!i@>I(^HZzz3UBTe#>gTe~DWM4f-%CUM literal 0 HcmV?d00001 diff --git a/src/assets/images/list-grey.png b/src/assets/images/list-grey.png new file mode 100644 index 0000000000000000000000000000000000000000..5fbda6710d685ddd082fe85ec9b3aaa06eaa5a3c GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|sy$sCLp;3S zhB|T`FyOeH- Date: Tue, 10 Jan 2023 21:28:47 +0400 Subject: [PATCH 42/65] fix: adjust header styles and margins --- src/Components/Main/FiltersList.module.scss | 1 + src/Components/ProductPage/productPage.module.scss | 2 +- src/Components/header/styles.module.scss | 3 ++- src/Pages/Cart/cart.module.scss | 2 +- src/Pages/Main/Main.module.scss | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Components/Main/FiltersList.module.scss b/src/Components/Main/FiltersList.module.scss index 1b3a5b9..5f77861 100644 --- a/src/Components/Main/FiltersList.module.scss +++ b/src/Components/Main/FiltersList.module.scss @@ -25,6 +25,7 @@ ul.filter__section { .filter__buttons { display: flex; justify-content: space-between; + margin-bottom: 20px; } .filter__button { diff --git a/src/Components/ProductPage/productPage.module.scss b/src/Components/ProductPage/productPage.module.scss index 0e240de..ca3f633 100644 --- a/src/Components/ProductPage/productPage.module.scss +++ b/src/Components/ProductPage/productPage.module.scss @@ -1,5 +1,5 @@ .wrapper { - margin: 0 auto; + margin: 40px auto; padding: 0 30px; max-width: 1220px; display: flex; diff --git a/src/Components/header/styles.module.scss b/src/Components/header/styles.module.scss index d4e3497..7ca4996 100644 --- a/src/Components/header/styles.module.scss +++ b/src/Components/header/styles.module.scss @@ -1,9 +1,10 @@ .header { // min-height: 100px; - padding: 35px 0; + padding: 30px 0; display: flex; justify-content: center; align-items: center; + border-bottom: 1px solid var(--accent-color); } .header__navigation { diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index be7d64d..0995884 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -1,6 +1,6 @@ .wrapper { // width: 95%; - margin: 0 auto; + margin: 20px auto; display: flex; justify-content: space-between; } diff --git a/src/Pages/Main/Main.module.scss b/src/Pages/Main/Main.module.scss index 019e389..e5b4005 100644 --- a/src/Pages/Main/Main.module.scss +++ b/src/Pages/Main/Main.module.scss @@ -1,5 +1,5 @@ .main { - margin: 10px 0 50px; + margin: 40px 0 50px; width: 100%; display: flex; gap: 50px; From a3c5860c52970e74bfb23ea8bceb0cbb42fd87c8 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Tue, 10 Jan 2023 20:49:13 +0300 Subject: [PATCH 43/65] fix: card number validation (#20) --- src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx | 2 +- src/hooks/useValidation.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx index ba3670a..da32856 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx +++ b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx @@ -113,7 +113,7 @@ function Purchase({ setShowAffirmative }: IPurchase) { )} {cardNumber.isCardNumberLengthInvalid && (
- !! Card number length should be at least 16 !! + !! Card number length should be 16 !!
)}
diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts index 6464af7..3006109 100644 --- a/src/hooks/useValidation.ts +++ b/src/hooks/useValidation.ts @@ -132,7 +132,7 @@ const useValidation = (value: string, validations:TValidations) => { break; case 'isCardNumberLengthInvalid': - if (value.length < 16) { + if (value.length < 16 || value.length > 16) { setIsCardNumberLengthInvalid(true); } else setIsCardNumberLengthInvalid(false); break; From 0fe4e981a0ab576e23c0eeec51625c67e966806f Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 10 Jan 2023 22:32:01 +0400 Subject: [PATCH 44/65] fix: adjust product page styles --- .../CarouselImages/CarouselImages.module.scss | 3 +- .../ProductImagesCarousel.module.scss | 8 +++- src/Components/ProductPage/ProductPage.tsx | 35 +++++++------- .../ProductPage/productPage.module.scss | 48 +++++++++++++------ 4 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss index abae571..562c8ab 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss +++ b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.module.scss @@ -1,10 +1,11 @@ .carouselImg { object-fit: contain; + background-color: white; min-width: 180px; max-width: 180px; max-height: 100px; cursor: pointer; margin: 5px; - border: 2px solid black; + border: 1px solid var(--unimportant-color); border-radius: 5px; } \ No newline at end of file diff --git a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss index e92e697..8900dad 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss +++ b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.module.scss @@ -3,10 +3,16 @@ display: flex; min-height: 100px; align-items: center; + gap: 10px; } .carouselButton { - padding: 12px; + padding: 8px 12px; + background-color: transparent; + border: 1px solid var(--accent-color); + border-radius: 5px; + color: var(--accent-color); + font-size: 1.2rem; &:last-of-type { margin-left: 5px; } diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index 47d5d7e..28a29bb 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -102,15 +102,17 @@ function ProductPage({ if (isPending) { return ( -
- -
+ +
+ +
+
); } @@ -147,9 +149,6 @@ function ProductPage({ {' '} {currentPage?.brand}
-
- {currentPage?.description} -
Rating: {' '} @@ -166,13 +165,17 @@ function ProductPage({ {currentPage?.discountPercentage} %
+
Description:
+
+ {currentPage?.description} +
- Price € - {' '} - {currentPage?.price} - .00 + Price: + {currentPage + ? new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(currentPage?.price) + : 0}
Date: Tue, 10 Jan 2023 22:51:13 +0400 Subject: [PATCH 45/65] fix: adjust links in footer styles --- src/Components/Cart/Pagination/cartPagination.module.scss | 2 +- src/Components/Footer/Footer.module.scss | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Components/Cart/Pagination/cartPagination.module.scss b/src/Components/Cart/Pagination/cartPagination.module.scss index b1521e3..628afe3 100644 --- a/src/Components/Cart/Pagination/cartPagination.module.scss +++ b/src/Components/Cart/Pagination/cartPagination.module.scss @@ -17,7 +17,7 @@ margin: 20px 0; width: 55px; text-align: center; outline: none; - border: 1px solid var(--accent-color); + border: 1px solid var(--unimportant-color); border-radius: 0.2rem; // font-size: 140%; margin-right: 20px; diff --git a/src/Components/Footer/Footer.module.scss b/src/Components/Footer/Footer.module.scss index 3d951b4..397b912 100644 --- a/src/Components/Footer/Footer.module.scss +++ b/src/Components/Footer/Footer.module.scss @@ -25,15 +25,16 @@ .footer__link { color: var(--primary-font-color); + text-decoration: none; margin-left: 8px; display: flex; align-items: center; - gap: 4px; + gap: 3px; &::before { content: ""; - width: 18px; - height: 18px; + width: 15px; + height: 15px; background-image: url("../../assets/images/github-mark.svg"); background-repeat: no-repeat; background-size: contain; From c18e4ec56d773d2493735d4547cd82366d791126 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 11 Jan 2023 03:15:04 +0400 Subject: [PATCH 46/65] fix: fix bug with currency signs on wrong filter --- src/Components/Main/DualSlider.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx index 12c1bd1..96f212d 100644 --- a/src/Components/Main/DualSlider.tsx +++ b/src/Components/Main/DualSlider.tsx @@ -56,11 +56,11 @@ function DualSlider(props: TDualSliderProps) { />

- € + {(sliderId === 'filter-price') ? '€' : ''} {searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...arr) : 0}

- € + {(sliderId === 'filter-price') ? '€' : ''} {searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...arr) : 0}

From 0f61c201caa2f4949425888ba47497c44e921a27 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 11 Jan 2023 13:03:00 +0400 Subject: [PATCH 47/65] fix: format prices in cart with Intl.NumberFormat --- src/Components/Cart/CartProduct/CartProduct.tsx | 4 +--- src/Pages/Cart/cart.tsx | 15 ++++----------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index adcf391..f1169ea 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -89,9 +89,7 @@ function CartProduct(props:TProductsCart) {
{data.count}
{data.count === 1 ? 'Delete from cart' : '-'}
- € - {price * data.count} - .00 + {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(price * data.count)}
diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 6d80d64..6da12b8 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -189,21 +189,14 @@ function Cart(props: TCartProps) { {totalCount}
- Total: - {' '} - € - {' '} - {totalCost} - .00 + Total: + {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(totalCost)}
{isCodeAdd ? (
- Total: - {' '} - € - {' '} - {countTotalSumWithDiscounts(totalCost, codeAdded)} + Total: + {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(Number(countTotalSumWithDiscounts(totalCost, codeAdded)))}
Applied codes
From 317a56dadac84a2677c9e41ecf37b751e93e9a93 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 11 Jan 2023 13:56:33 +0400 Subject: [PATCH 48/65] change breadcrumbs into links --- src/Components/ProductPage/ProductPage.tsx | 12 ++++++++++-- src/Components/ProductPage/productPage.module.scss | 5 +++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index 28a29bb..fba465e 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -116,15 +116,23 @@ function ProductPage({ ); } + const linkToCategories = `/?category=${currentPage?.category}`; + const linkToBrands = `/?brand=${currentPage?.brand}`; + return (
Home >> -
{currentPage?.category}
+ + {currentPage?.category} + >> -
{currentPage?.brand}
+ {currentPage?.brand} >>
{currentPage?.title}
diff --git a/src/Components/ProductPage/productPage.module.scss b/src/Components/ProductPage/productPage.module.scss index 2a22829..bc0a22a 100644 --- a/src/Components/ProductPage/productPage.module.scss +++ b/src/Components/ProductPage/productPage.module.scss @@ -29,6 +29,10 @@ } } +.breedsCategory { + text-transform: capitalize; +} + .breedsItems { color: var(--unimportant-color); font-size: 1.2rem; @@ -85,6 +89,7 @@ .infoHeaders { color: var(--accent-color); + // font-weight: bold; } .infoDescription { From 82ea218b469ae97c34edf5a1df74cbc01811d361 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 14 Jan 2023 16:10:52 +0400 Subject: [PATCH 49/65] feat: make site keyboard-accessible --- src/Components/Main/DualSlider.module.scss | 20 +++++++++++-------- src/Components/Main/DualSlider.tsx | 8 ++++---- src/Components/Main/FiltersList.module.scss | 11 +++++++++- src/Components/Main/ProductsList.module.scss | 6 +++++- .../button/ProductAddDropButton.module.scss | 4 ++++ src/Pages/Main/Main.module.scss | 10 ++++++++++ src/index.scss | 18 ++++++++++++++--- 7 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/Components/Main/DualSlider.module.scss b/src/Components/Main/DualSlider.module.scss index 2f6c066..d672f28 100644 --- a/src/Components/Main/DualSlider.module.scss +++ b/src/Components/Main/DualSlider.module.scss @@ -8,6 +8,7 @@ background: transparent; height: 4px; background: var(--accent-color); + border: 1px solid transparent; border-radius: 5px; position: absolute; top: 10px; @@ -16,11 +17,10 @@ &:focus { outline: none; } -} -.sliderMin { - height: 0; - z-index: 1; + &:hover { + z-index: 1; + } } .slider::-ms-track { @@ -34,7 +34,6 @@ .slider::-webkit-slider-runnable-track, .slider::-moz-range-track, .slider::-ms-track { - // background: black; width: 100%; height: 2px; } @@ -47,7 +46,7 @@ border-radius: 50%; background-color: var(--accent-color); cursor: pointer; - transition: all 0.4s; + // transition: all 0.4s; &:hover { background-color: var(--accent-hover-color); @@ -63,15 +62,20 @@ border-radius: 50%; background-color: var(--accent-color); cursor: pointer; - transition: all 0.4s; + // transition: all 0.4s; &:hover { background-color: var(--accent-hover-color); } } -.dualSlider__labels { +.slider__labels { padding: 35px 10px 0 10px; display: flex; justify-content: space-between; } + +.sliderMin:focus ~ .slider__labels .slider__labelMin, +.sliderMax:focus ~ .slider__labels .slider__labelMax { + font-weight: bold; +} diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx index 96f212d..d9bce6f 100644 --- a/src/Components/Main/DualSlider.tsx +++ b/src/Components/Main/DualSlider.tsx @@ -51,15 +51,15 @@ function DualSlider(props: TDualSliderProps) { max={Math.max(...products.map((item) => item[filter]))} value={searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? Math.max(...arr)} onInput={handleSliderMaxInput} - className={styles.slider} + className={[styles.slider, styles.sliderMax].join(' ')} // style={{ background: `${fillSlider(filter)}` }} /> -
-

+

+

{(sliderId === 'filter-price') ? '€' : ''} {searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...arr) : 0}

-

+

{(sliderId === 'filter-price') ? '€' : ''} {searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...arr) : 0}

diff --git a/src/Components/Main/FiltersList.module.scss b/src/Components/Main/FiltersList.module.scss index 5f77861..40aa12e 100644 --- a/src/Components/Main/FiltersList.module.scss +++ b/src/Components/Main/FiltersList.module.scss @@ -15,6 +15,7 @@ .filter__section { margin-bottom: 20px; + padding: 0 2px; } ul.filter__section { @@ -38,6 +39,10 @@ ul.filter__section { background-color: var(--accent-active-color); } + &:focus { + outline-color: var(--accent-color); + } + @media (max-width: 1199px) { width: 100px; } @@ -69,4 +74,8 @@ input[type="checkbox"] { input[type="checkbox"]:checked + .filter__label::before { background-position: center center; -} \ No newline at end of file +} + +input[type="checkbox"]:focus + .filter__label::before { + outline: 1px solid var(--accent-color); +} diff --git a/src/Components/Main/ProductsList.module.scss b/src/Components/Main/ProductsList.module.scss index 88ba7d7..6248ff2 100644 --- a/src/Components/Main/ProductsList.module.scss +++ b/src/Components/Main/ProductsList.module.scss @@ -92,11 +92,15 @@ font-size: 0.9rem; text-decoration: none; align-items: center; - transition: all 0.4s; + transition: background-color 0.4s; &:hover { background-color: var(--accent-hover-color); } + + &:focus { + outline-color: var(--primary-font-color); + } } .products.products_list { diff --git a/src/Components/UI/button/ProductAddDropButton.module.scss b/src/Components/UI/button/ProductAddDropButton.module.scss index 8088edb..142bc45 100644 --- a/src/Components/UI/button/ProductAddDropButton.module.scss +++ b/src/Components/UI/button/ProductAddDropButton.module.scss @@ -13,4 +13,8 @@ background-color: var(--accent-color); color: white; } + + &:focus { + outline-color: var(--accent-color); + } } \ No newline at end of file diff --git a/src/Pages/Main/Main.module.scss b/src/Pages/Main/Main.module.scss index e5b4005..19cc1df 100644 --- a/src/Pages/Main/Main.module.scss +++ b/src/Pages/Main/Main.module.scss @@ -5,6 +5,10 @@ gap: 50px; } +.rightColumnWrapper { + width: 100%; +} + .findSortContainer { display: flex; justify-content: space-between; @@ -54,3 +58,9 @@ .productsView input[type="radio"]:checked + .productsView__label_list { background-image: url("../../assets/images/list-green.png"); } + +.productsView input[type="radio"]:focus + .productsView__label_grid, +.productsView input[type="radio"]:focus + .productsView__label_list { + outline: 1px solid var(--accent-color); + outline-offset: 2px; +} diff --git a/src/index.scss b/src/index.scss index 3c5735d..fc7b6c5 100644 --- a/src/index.scss +++ b/src/index.scss @@ -67,15 +67,15 @@ button { } } -input[type='text'], +input[type="text"], select { border-radius: 10px; font-size: 1rem; padding: 5px; } -input[type='text'] { - border: 1px solid var(--accent-color); +input[type="text"] { + border: 1px solid var(--unimportant-color); padding: 9.5px 15px; } @@ -87,6 +87,18 @@ option { line-height: 25px; } +a:focus, +button:focus, +input[type="text"]:focus, +select:focus, +option:focus { + outline: 1px solid var(--accent-color); +} + +button:focus { + outline-color: var(--primary-font-color); +} + code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; From 968f050c38e49c7c1d34eb687b7793beb379b54f Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 14 Jan 2023 21:51:45 +0400 Subject: [PATCH 50/65] refactor: clean up and refactor the code --- .eslintrc.json | 6 +- src/App/App.tsx | 21 +- src/App/RootRouter/index.tsx | 29 ++- .../Cart/CartProduct/CartProduct.tsx | 3 +- src/Components/Footer/index.tsx | 2 +- src/Components/Main/DualSlider.tsx | 57 +++-- src/Components/Main/FiltersList.module.scss | 6 + src/Components/Main/FiltersList.tsx | 75 +++--- src/Components/Main/ProductsList.tsx | 17 +- src/Components/ProductPage/ProductPage.tsx | 7 +- .../ProductPage/productPage.module.scss | 4 +- .../UI/button/ProductAddDropButton.tsx | 19 +- src/Components/header/index.tsx | 48 +--- src/Components/utils/filterProducts.ts | 29 +++ src/Components/utils/formatPrice.ts | 3 + src/Components/utils/getFilterOptions.ts | 8 + src/Components/utils/handleCheckboxChange.ts | 40 +++ src/Components/utils/isInSearchParams.ts | 16 ++ src/Components/utils/searchInProducts.ts | 24 ++ src/Components/utils/sortProducts.ts | 47 ++++ src/Pages/Cart/cart.tsx | 6 +- src/Pages/Main/index.tsx | 236 +++++------------- src/index.scss | 14 ++ src/types/types.ts | 15 ++ 24 files changed, 402 insertions(+), 330 deletions(-) create mode 100644 src/Components/utils/filterProducts.ts create mode 100644 src/Components/utils/formatPrice.ts create mode 100644 src/Components/utils/getFilterOptions.ts create mode 100644 src/Components/utils/handleCheckboxChange.ts create mode 100644 src/Components/utils/isInSearchParams.ts create mode 100644 src/Components/utils/searchInProducts.ts create mode 100644 src/Components/utils/sortProducts.ts diff --git a/.eslintrc.json b/.eslintrc.json index e0b3f64..0b6687a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,7 +23,11 @@ "react/jsx-filename-extension": [ 1, { "extensions": [".js", ".jsx", "ts", "tsx"] } - ] + ], + "no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": "error", + "no-shadow": "off", + "@typescript-eslint/no-shadow": "error" }, "settings": { "import/resolver": { diff --git a/src/App/App.tsx b/src/App/App.tsx index 705e5d5..c50a2a4 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -8,10 +8,12 @@ import handleLocalStorage from '../Components/utils/handleLocalStorage'; import setDataToLocalStorage from '../Components/utils/setDataToLocalStorage'; function App() { - // eslint-disable-next-line max-len - const [productsInCart, setProductsInCart] = useState(handleLocalStorage()); - // eslint-disable-next-line max-len - const [productsInCartCount, setProductsInCartCount] = useState(handleLocalStorage()); + const [ + productsInCart, setProductsInCart, + ] = useState(handleLocalStorage()); + const [ + productsInCartCount, setProductsInCartCount, + ] = useState(handleLocalStorage()); const [products, setProducts] = useState(null); const [formVisible, setFormVisible] = useState(false); const [fetchProductsById, isPending] = useFetching(async () => { @@ -24,6 +26,10 @@ function App() { fetchProductsById(); }, [productsInCart]); + useEffect(() => { + setDataToLocalStorage(productsInCart); + }, [productsInCart]); + const increaseProductCount = (event: React.MouseEvent) => { const cur = Number(event.currentTarget.value); const maxCount = products?.reduce((acc, product) => { @@ -63,12 +69,7 @@ function App() { setDataToLocalStorage(result); }; - const isProductInCart = (id?: number): boolean => { - if (productsInCart.find((item) => item.id === id)) { - return true; - } - return false; - }; + const isProductInCart = (id?: number): boolean => productsInCart.some((item) => item.id === id); const addToCart = (id: number) => { if (!isProductInCart(id)) { diff --git a/src/App/RootRouter/index.tsx b/src/App/RootRouter/index.tsx index 5d3478d..acd4626 100644 --- a/src/App/RootRouter/index.tsx +++ b/src/App/RootRouter/index.tsx @@ -12,22 +12,15 @@ import styles from './RootRouter.module.scss'; type TRootRouterProps = { isPending: boolean; productsInCart: TProductPartialProps[]; - // eslint-disable-next-line no-unused-vars setProductsInCart(arr: TProductPartialProps[]): void; productsInCartCount: TProductPartialProps[]; - // eslint-disable-next-line no-unused-vars setProductsInCartCount(arr: TProductPartialProps[]): void; products: TProductsItem[] | null; - // eslint-disable-next-line no-unused-vars increaseProductCount(event: React.MouseEvent): void; - // eslint-disable-next-line no-unused-vars decreaseProductCount(event: React.MouseEvent): void; - // eslint-disable-next-line no-unused-vars addToCart(id: number): void; - // eslint-disable-next-line no-unused-vars dropFromCart(id: number): void; formVisible: boolean; - // eslint-disable-next-line no-unused-vars setFormVisible(bool:boolean): void; } @@ -48,7 +41,10 @@ export default function RootRouter(props: TRootRouterProps) { } = props; return (
-
+
)} /> - } /> + + )} + /> )} /> - } /> + } + />
diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index f1169ea..8391c96 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -5,6 +5,7 @@ import { Link } from 'react-router-dom'; import { TProductsCart } from '../../../types/types'; import ProductCartButton from '../../UI/button/ProductCartButton'; import LoadingSpinner from '../../UI/LoadingSpinner'; +import formatPrice from '../../utils/formatPrice'; import styles from './CartProduct.module.scss'; function CartProduct(props:TProductsCart) { @@ -89,7 +90,7 @@ function CartProduct(props:TProductsCart) {
{data.count}
{data.count === 1 ? 'Delete from cart' : '-'}
- {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(price * data.count)} + {formatPrice(price * data.count)}
diff --git a/src/Components/Footer/index.tsx b/src/Components/Footer/index.tsx index fe58151..ebaa10d 100644 --- a/src/Components/Footer/index.tsx +++ b/src/Components/Footer/index.tsx @@ -14,7 +14,7 @@ function Footer() {

Online Store © 2023

- + Rolling Scopes School frontend course
diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx index d9bce6f..8b9f82f 100644 --- a/src/Components/Main/DualSlider.tsx +++ b/src/Components/Main/DualSlider.tsx @@ -1,18 +1,15 @@ import React from 'react'; -import { TProductsItem } from '../../types/types'; +import { TProductsItem, TSearchParamsObject, TFilterRangeTypes } from '../../types/types'; +import formatPrice from '../utils/formatPrice'; import styles from './DualSlider.module.scss'; type TDualSliderProps = { sliderId: string; - filter: 'price' | 'stock'; + filter: TFilterRangeTypes; products: TProductsItem[]; - // eslint-disable-next-line no-unused-vars - handleSliderMinInput(event: React.ChangeEvent): void; - // eslint-disable-next-line no-unused-vars - handleSliderMaxInput(event: React.ChangeEvent): void + handleSliderFilter(event: React.ChangeEvent): void; filteredSearchedProducts: TProductsItem[] | []; - searchParamsObject: Record; - // eslint-disable-next-line no-unused-vars + searchParamsObject: TSearchParamsObject; // fillSlider(filter: 'price' | 'stock'): string; } @@ -21,15 +18,25 @@ function DualSlider(props: TDualSliderProps) { sliderId, filter, products, - handleSliderMinInput, - handleSliderMaxInput, + handleSliderFilter, filteredSearchedProducts, searchParamsObject, // fillSlider, } = props; - const filtered = filteredSearchedProducts.map((item) => item[filter]); - const arr = (filtered.length > 0) ? filtered : [0]; + const filterValuesTotal = (products.length > 0) + ? products.map((item) => item[filter]) + : [0]; + + const minTotalFilterValue = Math.min(...filterValuesTotal); + const maxTotalFilterValue = Math.max(...filterValuesTotal); + + const filterValues = (filteredSearchedProducts.length > 0) + ? filteredSearchedProducts.map((item) => item[filter]) + : [0]; + + const [minFilterValue, maxFilterValue] = searchParamsObject[`${filter}range`]?.split(',') + ?? [Math.min(...filterValues), Math.max(...filterValues)]; return (
@@ -37,31 +44,33 @@ function DualSlider(props: TDualSliderProps) { type="range" name={`${sliderId}-min`} id={`${sliderId}-min`} - min={Math.min(...products.map((item) => item[filter]))} - max={Math.max(...products.map((item) => item[filter]))} - value={searchParamsObject[`${filter}range`]?.split(',')[0] ?? Math.min(...arr)} - onInput={handleSliderMinInput} + min={minTotalFilterValue} + max={maxTotalFilterValue} + value={minFilterValue} + onInput={handleSliderFilter} className={[styles.slider, styles.sliderMin].join(' ')} /> item[filter]))} - max={Math.max(...products.map((item) => item[filter]))} - value={searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? Math.max(...arr)} - onInput={handleSliderMaxInput} + min={minTotalFilterValue} + max={maxTotalFilterValue} + value={maxFilterValue} + onInput={handleSliderFilter} className={[styles.slider, styles.sliderMax].join(' ')} // style={{ background: `${fillSlider(filter)}` }} />

- {(sliderId === 'filter-price') ? '€' : ''} - {searchParamsObject[`${filter}range`]?.split(',')[0] ?? filteredSearchedProducts.length ? Math.min(...arr) : 0} + {sliderId === 'filter-price' + ? formatPrice(Number(minFilterValue)) + : minFilterValue}

- {(sliderId === 'filter-price') ? '€' : ''} - {searchParamsObject[`${[filter]}range`]?.split(',')[1] ?? filteredSearchedProducts.length ? Math.max(...arr) : 0} + {sliderId === 'filter-price' + ? formatPrice(Number(maxFilterValue)) + : maxFilterValue}

diff --git a/src/Components/Main/FiltersList.module.scss b/src/Components/Main/FiltersList.module.scss index 40aa12e..6fae4bb 100644 --- a/src/Components/Main/FiltersList.module.scss +++ b/src/Components/Main/FiltersList.module.scss @@ -79,3 +79,9 @@ input[type="checkbox"]:checked + .filter__label::before { input[type="checkbox"]:focus + .filter__label::before { outline: 1px solid var(--accent-color); } + +.filter__label__count { + margin-left: auto; + margin-right: 2px; + color: var(--unimportant-color); +} diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index 173b666..2decaa1 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -1,29 +1,22 @@ import React from 'react'; -import { TProductsItem } from '../../types/types'; import DualSlider from './DualSlider'; +import isInSearchParams from '../utils/isInSearchParams'; import styles from './FiltersList.module.scss'; - -type TParamsObject = Record; +import handleCheckboxFilter from '../utils/handleCheckboxChange'; +import getFilterOptions from '../utils/getFilterOptions'; +import { + TProductsItem, TSearchParamsObject, TSetSearchParamsObject, TFilterSelectionTypes, +} from '../../types/types'; type TFiltersListProps = { products: TProductsItem[]; filteredSearchedProducts: TProductsItem[] | []; - categoriesList: number[] | string[]; - brandsList: number[] | string[]; - searchParamsObject: Record; - // eslint-disable-next-line no-unused-vars - isInSearchParams(paramName: string, param: string | number, paramsObject: TParamsObject): boolean; - // eslint-disable-next-line no-unused-vars - handleCheckboxChange(filterName: string, filter: string | number): void; + searchParamsObject: TSearchParamsObject; + setSearchParamsObject: TSetSearchParamsObject; handleResetClick(): void; - // eslint-disable-next-line no-unused-vars handleCopyClick(): void; - // eslint-disable-next-line no-unused-vars - handleSliderMinInput(event: React.ChangeEvent): void; - // eslint-disable-next-line no-unused-vars - handleSliderMaxInput(event: React.ChangeEvent): void + handleSliderFilter(event: React.ChangeEvent): void; copied: boolean; - // eslint-disable-next-line no-unused-vars // fillSlider(filter: 'price' | 'stock'): string; } @@ -31,21 +24,25 @@ function FiltersList(props: TFiltersListProps) { const { products, filteredSearchedProducts, - categoriesList, - brandsList, searchParamsObject, - isInSearchParams, - handleCheckboxChange, + setSearchParamsObject, handleResetClick, handleCopyClick, - handleSliderMinInput, - handleSliderMaxInput, + handleSliderFilter, copied, // fillSlider, } = props; + const categoriesList = getFilterOptions(products, 'category'); + const brandsList = getFilterOptions(products, 'brand'); + + type TItemsCount = (items: TProductsItem[], key: TFilterSelectionTypes, value: string) => number; + const itemsCount: + TItemsCount = (items, key, value) => items.filter((product) => product[key] === value).length; + return (
+

Filters

@@ -59,17 +56,17 @@ function FiltersList(props: TFiltersListProps) { type="checkbox" id={`filter-category-${category}`} name="category" - checked={isInSearchParams('category', category, searchParamsObject)} - onChange={() => handleCheckboxChange('category', category)} + checked={isInSearchParams('category', category.toString(), searchParamsObject)} + onChange={() => handleCheckboxFilter('category', category.toString(), searchParamsObject, setSearchParamsObject)} />
@@ -84,17 +81,17 @@ function FiltersList(props: TFiltersListProps) { type="checkbox" id={`filter-brand-${brand}`} name="brand" - checked={isInSearchParams('brand', brand, searchParamsObject)} - onChange={() => handleCheckboxChange('brand', brand)} + checked={isInSearchParams('brand', brand.toString(), searchParamsObject)} + onChange={() => handleCheckboxFilter('brand', brand.toString(), searchParamsObject, setSearchParamsObject)} />
@@ -107,8 +104,7 @@ function FiltersList(props: TFiltersListProps) { sliderId="filter-price" filter="price" products={products} - handleSliderMinInput={handleSliderMinInput} - handleSliderMaxInput={handleSliderMaxInput} + handleSliderFilter={handleSliderFilter} searchParamsObject={searchParamsObject} filteredSearchedProducts={filteredSearchedProducts} // fillSlider={fillSlider} @@ -120,8 +116,7 @@ function FiltersList(props: TFiltersListProps) { sliderId="filter-stock" filter="stock" products={products} - handleSliderMinInput={handleSliderMinInput} - handleSliderMaxInput={handleSliderMaxInput} + handleSliderFilter={handleSliderFilter} searchParamsObject={searchParamsObject} filteredSearchedProducts={filteredSearchedProducts} // fillSlider={fillSlider} diff --git a/src/Components/Main/ProductsList.tsx b/src/Components/Main/ProductsList.tsx index 2e442a5..16972e9 100644 --- a/src/Components/Main/ProductsList.tsx +++ b/src/Components/Main/ProductsList.tsx @@ -1,14 +1,13 @@ import React from 'react'; import { Link } from 'react-router-dom'; import ProductAddDropButton from '../UI/button/ProductAddDropButton'; +import formatPrice from '../utils/formatPrice'; import { TProductsItem, TProductPartialProps } from '../../types/types'; import styles from './ProductsList.module.scss'; type TProductsListProps = { productsInCart: TProductPartialProps[]; - // eslint-disable-next-line no-unused-vars addToCart(id: number): void; - // eslint-disable-next-line no-unused-vars dropFromCart(id: number): void; products: TProductsItem[]; view: string; @@ -26,9 +25,10 @@ export default function ProductsList(props: TProductsListProps) { return (
{ - products.length - ? products.map((product: TProductsItem) => ( -
+ (!products.length) + ? 'No products found' + : products.map((product) => ( +
Price:
-
- {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(product.price)} -
+
{formatPrice(product.price)}
Details
-
+ )) - : 'No products found' } ); diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index fba465e..8510012 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -6,11 +6,12 @@ import { TProductPartialProps, TProductsItemWithImages } from '../../types/types import PostService from '../API/PostService'; import ProductAddDropButton from '../UI/button/ProductAddDropButton'; import CartContainer from '../UI/container/CartContainer/CartContainer'; -import SiteContainer from '../UI/container/SiteContainer'; +// import SiteContainer from '../UI/container/SiteContainer'; import LoadingSpinner from '../UI/LoadingSpinner'; import checkUniqueImgs from '../utils/checkUniqueImgs'; import setDataToLocalStorage from '../utils/setDataToLocalStorage'; import ProductImagesCarousel from './ProductImagesCarousel/ProductImagesCarousel'; +import formatPrice from '../utils/formatPrice'; import styles from './productPage.module.scss'; interface IProductPage { @@ -137,7 +138,7 @@ function ProductPage({
{currentPage?.title}
-

{currentPage?.title}

+

{currentPage?.title}

@@ -182,7 +183,7 @@ function ProductPage({
Price: {currentPage - ? new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(currentPage?.price) + ? formatPrice(currentPage?.price) : 0}
diff --git a/src/Components/ProductPage/productPage.module.scss b/src/Components/ProductPage/productPage.module.scss index bc0a22a..aa5985c 100644 --- a/src/Components/ProductPage/productPage.module.scss +++ b/src/Components/ProductPage/productPage.module.scss @@ -11,7 +11,7 @@ color: var(--unimportant-color); text-align: center; // margin: 0 auto 30px auto; - margin-bottom: 10px; + margin-bottom: 30px; align-self: flex-start; display: flex; // max-width: 800px; @@ -42,7 +42,7 @@ .productWrapper { display: block; - & h2 { + & h1 { text-align: center; font-size: 30px; margin-bottom: 50px; diff --git a/src/Components/UI/button/ProductAddDropButton.tsx b/src/Components/UI/button/ProductAddDropButton.tsx index 6fb0217..161e42a 100644 --- a/src/Components/UI/button/ProductAddDropButton.tsx +++ b/src/Components/UI/button/ProductAddDropButton.tsx @@ -5,9 +5,7 @@ import styles from './ProductAddDropButton.module.scss'; type ProductAddDropButtonProps = { productId: number | undefined; productsInCart: TProductPartialProps[]; - // eslint-disable-next-line no-unused-vars addToCart(id: number | undefined): void; - // eslint-disable-next-line no-unused-vars dropFromCart(id: number | undefined): void; } @@ -19,17 +17,10 @@ function ProductAddDropButton(props: ProductAddDropButtonProps) { dropFromCart, } = props; - const isProductInCart = (id?: number): boolean => { - if (productsInCart.find((item) => item.id === id)) { - return true; - } - return false; - }; - - const inCart = isProductInCart(productId); + const isInCart = productsInCart.some((item) => item.id === productId); const handleClick = (): void => { - if (inCart) { + if (isInCart) { dropFromCart(productId); } else { addToCart(productId); @@ -38,11 +29,13 @@ function ProductAddDropButton(props: ProductAddDropButtonProps) { return ( ); } diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 0fbec3c..47a407b 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -1,40 +1,22 @@ // import React, { useMemo } from 'react'; import { NavLink } from 'react-router-dom'; -// тут стили импортированы при помощи модулей, это один из способов подключения стилей. -// В таком случае в компонентах можно использовать повторяющиеся названия для стилей, -// т.к. к ним присоединиться случайный хеш и на самом деле название стиля будет отличаться import styles from './styles.module.scss'; import { TProductsItem, TProductPartialProps } from '../../types/types'; +import formatPrice from '../utils/formatPrice'; import cart from '../../assets/images/cart.svg'; type TProps = { - // productsInCart: TProductPartialProps[]; productsInCart: TProductPartialProps[]; products: TProductsItem[] | null; - // eslint-disable-next-line no-unused-vars - // increaseProductCount(event: React.MouseEvent): void; - // eslint-disable-next-line no-unused-vars - // decreaseProductCount(event: React.MouseEvent): void; } -// компонент созданный при помощи function declaration, -// можно писать и используя expression. В другом компоненте будет пример export default function Header(props: TProps) { - const { productsInCart, products } = props; - // console.log(`header: ${productsInCartCount.reduce((acc, elem) => acc + elem.count, 0)}`); - // const { cartItems } = props; - // можно не обращать внимание на useMemo, это уже более продвинутый уровень - // ниже функция которая навешивает определенный стиль исходя их переменной isActive, - // это встроенная переменная в элементе NavLink - // NavLink мы взяли из react-router-dom - // const activeStyles = useMemo( - // () => (bool: boolean) => (bool - // ? styles.header__navigation__link__active - // : styles.header__navigation__link), - // [], - // ); + const { + productsInCart, + products, + } = props; - const cartTotal = products?.reduce((acc, elem) => { + const cartTotalItems = products?.reduce((acc, elem) => { const productInCart = productsInCart.find((item) => item.id === elem.id); if (productInCart === undefined) { return 0; @@ -42,35 +24,27 @@ export default function Header(props: TProps) { return acc + elem.price * productInCart.count; }, 0); + const cartTotalPrice = productsInCart.reduce((acc, elem) => acc + elem.count, 0); + return (
diff --git a/src/Components/utils/filterProducts.ts b/src/Components/utils/filterProducts.ts new file mode 100644 index 0000000..c5bdfca --- /dev/null +++ b/src/Components/utils/filterProducts.ts @@ -0,0 +1,29 @@ +import { TProductsItem, TSearchParamsObject } from '../../types/types'; + +type TFilterProducts = ( + productsArray: TProductsItem[] | [], + searchParamsObject: TSearchParamsObject +) => TProductsItem[] | []; + +const filterProducts: TFilterProducts = (productsArray, searchParamsObject) => { + let copy = productsArray.slice(); + if (searchParamsObject.category) { + const params = searchParamsObject.category.split(','); + copy = copy.filter((elem) => params.includes(elem.category)); + } + if (searchParamsObject.brand) { + const params = searchParamsObject.brand.split(','); + copy = copy.filter((elem) => params.includes(elem.brand)); + } + if (searchParamsObject.pricerange) { + const [min, max] = searchParamsObject.pricerange.split(',').map((elem) => Number(elem)); + copy = copy.filter((elem) => elem.price >= min && elem.price <= max); + } + if (searchParamsObject.stockrange) { + const [min, max] = searchParamsObject.stockrange.split(',').map((elem) => Number(elem)); + copy = copy.filter((elem) => elem.stock >= min && elem.stock <= max); + } + return copy; +}; + +export default filterProducts; diff --git a/src/Components/utils/formatPrice.ts b/src/Components/utils/formatPrice.ts new file mode 100644 index 0000000..39fa6ec --- /dev/null +++ b/src/Components/utils/formatPrice.ts @@ -0,0 +1,3 @@ +const formatPrice = (price: number) => new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(price); + +export default formatPrice; diff --git a/src/Components/utils/getFilterOptions.ts b/src/Components/utils/getFilterOptions.ts new file mode 100644 index 0000000..f82d5cd --- /dev/null +++ b/src/Components/utils/getFilterOptions.ts @@ -0,0 +1,8 @@ +import { TProductsItem, TFilterSelectionTypes } from '../../types/types'; + +const getFilterOptions = (source: TProductsItem[], filterType: TFilterSelectionTypes) => { + const set = new Set(source.map((item) => item[filterType])); + return Array.from(set).sort(); +}; + +export default getFilterOptions; diff --git a/src/Components/utils/handleCheckboxChange.ts b/src/Components/utils/handleCheckboxChange.ts new file mode 100644 index 0000000..2b2b0d3 --- /dev/null +++ b/src/Components/utils/handleCheckboxChange.ts @@ -0,0 +1,40 @@ +import isInSearchParams from './isInSearchParams'; +import { TFilterSelectionTypes, TSearchParamsObject, TSetSearchParamsObject } from '../../types/types'; + +type THandleCheckboxFilter = ( + filterName: TFilterSelectionTypes, + filterValue: string, + searchParamsObject: TSearchParamsObject, + setSearchParamsObject: TSetSearchParamsObject +) => void; + +const handleCheckboxFilter: +THandleCheckboxFilter = (filterName, filterValue, searchParamsObject, setSearchParamsObject) => { + const addToSearchParams = () => { + if (searchParamsObject[filterName] !== undefined) { + setSearchParamsObject({ ...searchParamsObject, [filterName]: `${searchParamsObject[filterName]},${filterValue}` }); + } else { + setSearchParamsObject({ ...searchParamsObject, [filterName]: filterValue }); + } + }; + + const removeFromSearchParams = () => { + let filterArr = searchParamsObject[filterName].split(','); + if (filterArr.length === 1) { + const copiedSearchParamsObject = { ...searchParamsObject }; + delete copiedSearchParamsObject[filterName]; + setSearchParamsObject(copiedSearchParamsObject); + } else { + filterArr = filterArr.filter((item) => item !== filterValue); + setSearchParamsObject({ ...searchParamsObject, [filterName]: filterArr.join(',') }); + } + }; + + if (isInSearchParams(filterName, filterValue, searchParamsObject)) { + removeFromSearchParams(); + } else { + addToSearchParams(); + } +}; + +export default handleCheckboxFilter; diff --git a/src/Components/utils/isInSearchParams.ts b/src/Components/utils/isInSearchParams.ts new file mode 100644 index 0000000..7c8e210 --- /dev/null +++ b/src/Components/utils/isInSearchParams.ts @@ -0,0 +1,16 @@ +import { TFilterSelectionTypes } from '../../types/types'; + +type TIsInSearchParams = ( + paramKey: TFilterSelectionTypes, + paramValue: string, + paramsObject: Record, +) => boolean; + +const isInSearchParams: TIsInSearchParams = (paramKey, paramValue, paramsObject) => { + if (!paramsObject[paramKey]) { + return false; + } + return paramsObject[paramKey].split(',').includes(paramValue); +}; + +export default isInSearchParams; diff --git a/src/Components/utils/searchInProducts.ts b/src/Components/utils/searchInProducts.ts new file mode 100644 index 0000000..18b23b1 --- /dev/null +++ b/src/Components/utils/searchInProducts.ts @@ -0,0 +1,24 @@ +import { TProductsItem, TSearchParamsObject } from '../../types/types'; + +type TSearchInProducts = ( + productsArray: TProductsItem[] | [], + searchParamsObject: TSearchParamsObject +) => TProductsItem[] | []; + +const searchInProducts: TSearchInProducts = (productsArray, searchParamsObject) => { + let copy = productsArray.slice(); + if (searchParamsObject.search) { + const query = searchParamsObject.search.trim().toLowerCase(); + copy = copy.filter((elem) => elem.title.toLowerCase().includes(query) + || elem.category.toLowerCase().includes(query) + || elem.brand.toLowerCase().includes(query) + || elem.description.toLowerCase().includes(query) + || elem.price.toString().includes(query) + || elem.discountPercentage.toString().includes(query) + || elem.rating.toString().includes(query) + || elem.stock.toString().includes(query)); + } + return copy; +}; + +export default searchInProducts; diff --git a/src/Components/utils/sortProducts.ts b/src/Components/utils/sortProducts.ts new file mode 100644 index 0000000..2cf55e2 --- /dev/null +++ b/src/Components/utils/sortProducts.ts @@ -0,0 +1,47 @@ +import { TProductsItem, TSearchParamsObject } from '../../types/types'; + +type TsortProducts = ( + productsArray: TProductsItem[] | [], + searchParamsObject: TSearchParamsObject +) => TProductsItem[] | []; + +const sortProducts: TsortProducts = (productsArray, searchParamsObject) => { + const { sortby } = searchParamsObject; + switch (sortby) { + case 'price-ascending': + return productsArray.sort((a, b) => a.price - b.price); + case 'price-descending': + return productsArray.sort((a, b) => b.price - a.price); + case 'rating-ascending': + return productsArray.sort((a, b) => a.rating - b.rating); + case 'rating-descending': + return productsArray.sort((a, b) => b.rating - a.rating); + case 'discount-ascending': + return productsArray.sort((a, b) => a.discountPercentage - b.discountPercentage); + case 'discount-descending': + return productsArray.sort((a, b) => b.discountPercentage - a.discountPercentage); + default: + return productsArray; + } + // if (sortby === 'price-ascending') { + // return productsArray.sort((a, b) => a.price - b.price); + // } + // if (sortby === 'price-descending') { + // return productsArray.sort((a, b) => b.price - a.price); + // } + // if (sortby === 'rating-ascending') { + // return productsArray.sort((a, b) => a.rating - b.rating); + // } + // if (sortby === 'rating-descending') { + // return productsArray.sort((a, b) => b.rating - a.rating); + // } + // if (sortby === 'discount-ascending') { + // return productsArray.sort((a, b) => a.discountPercentage - b.discountPercentage); + // } + // if (sortby === 'discount-descending') { + // return productsArray.sort((a, b) => b.discountPercentage - a.discountPercentage); + // } + // return productsArray; +}; + +export default sortProducts; diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 6da12b8..8a27c24 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -19,6 +19,7 @@ import countTotalCount from '../../Components/utils/countTotalCount'; import countTotalSumWithDiscounts from '../../Components/utils/countTotalSumWithDiscounts'; // import useFetching from '../../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../../types/types'; +import formatPrice from '../../Components/utils/formatPrice'; import styles from './cart.module.scss'; import emptyCartImg from '../../assets/images/emptyCart.svg'; @@ -159,6 +160,7 @@ function Cart(props: TCartProps) { return (
+

Cart

{ currentProducts?.map((product: TProductsItem, index) => ( @@ -190,13 +192,13 @@ function Cart(props: TCartProps) {
Total: - {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(totalCost)} + {formatPrice(totalCost)}
{isCodeAdd ? (
Total: - {new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'EUR' }).format(Number(countTotalSumWithDiscounts(totalCost, codeAdded)))} + {formatPrice(Number(countTotalSumWithDiscounts(totalCost, codeAdded)))}
Applied codes
diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index be69d0c..a50cc16 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -3,96 +3,52 @@ import React, { ChangeEvent, useEffect, useState } from 'react'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; // import TestForMain from '../../Components/TestForMain'; -import { TProductPartialProps, TProductsItem } from '../../types/types'; import useSearchParamsObject from '../../hooks/useSearchParamsObject'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; import SiteContainer from '../../Components/UI/container/SiteContainer'; import styles from './Main.module.scss'; -import setDataToLocalStorage from '../../Components/utils/setDataToLocalStorage'; +import filterProducts from '../../Components/utils/filterProducts'; +import searchInProducts from '../../Components/utils/searchInProducts'; +import sortProducts from '../../Components/utils/sortProducts'; +import { + TProductPartialProps, TProductsItem, TFilterRangeTypes, +} from '../../types/types'; type TMainProps = { productsInCart: TProductPartialProps[]; - // eslint-disable-next-line no-unused-vars addToCart(id: number): void; - // eslint-disable-next-line no-unused-vars dropFromCart(id: number): void; } -type TParamsObject = Record; - -type TFilterOptions = 'category' | 'brand' | 'price' | 'stock'; - function Main(props: TMainProps) { const { productsInCart, addToCart, dropFromCart, } = props; + const [products, setProducts] = useState([]); const [isPending, setIsPending] = useState(true); - const fetchProducts = async () => { - const response = await fetch('https://dummyjson.com/products?limit=20'); - const productsList = await response.json(); - setProducts(productsList.products); - setIsPending(false); + const fetchProducts = async (source: string) => { + try { + const response = await fetch(source); + const productsList = await response.json(); + return productsList.products; + } catch (err) { + throw new Error('Error: Could not fetch products'); + } }; useEffect(() => { - fetchProducts(); + fetchProducts('https://dummyjson.com/products?limit=20') + .then((result) => setProducts(result)) + .then(() => setIsPending(false)); }, []); - const isInSearchParams = ( - paramName: string, - param: string | number, - paramsObject: TParamsObject, - ) => { - if (typeof param === 'number') { - return paramsObject[paramName] !== undefined; - } - if (!paramsObject[paramName]) { - return false; - } - return paramsObject[paramName].split(',').includes(param); - }; - - const getFilterParams = (source: TProductsItem[], paramName: TFilterOptions) => { - if (paramName === 'price' || paramName === 'stock') { - let arr = source.map((item) => item[paramName]); - arr = (arr.length > 0) ? arr : [0]; - return [Math.min(...arr), Math.max(...arr)]; - } - const set = new Set(source.map((item) => item[paramName])); - return Array.from(set).sort(); - }; - const [searchParamsObject, setSearchParamsObject] = useSearchParamsObject(); - const categoriesList = getFilterParams(products, 'category'); - - const brandsList = getFilterParams(products, 'brand'); - - const handleCheckboxChange = (filterName: string, filter: string | number) => { - if (isInSearchParams(filterName, filter, searchParamsObject)) { - let filterArr = searchParamsObject[filterName].split(','); - if (filterArr.length === 1) { - const copySearchParamsObject = { ...searchParamsObject }; - delete copySearchParamsObject[filterName]; - setSearchParamsObject(copySearchParamsObject); - } else { - filterArr = filterArr.filter((item) => item !== filter); - setSearchParamsObject({ ...searchParamsObject, [filterName]: filterArr.join(',') }); - } - } else if (searchParamsObject[filterName]) { - setSearchParamsObject({ ...searchParamsObject, [filterName]: `${searchParamsObject[filterName]},${filter}` }); - } else { - setSearchParamsObject({ ...searchParamsObject, [filterName]: filter.toString() }); - } - }; - - // let filteredSearchedProducts: TProductsItem[] = products.slice(); - // const fillSlider = (filter: 'price' | 'stock') => { // const sliderColor = '#b9b9b9'; // const rangeColor = '#2CB708'; @@ -113,123 +69,62 @@ function Main(props: TMainProps) { // ${sliderColor} 100%)`; // }; - const getMinPrice = (source: TProductsItem[], param: 'price' | 'stock') => { + const getMinPrice = (source: TProductsItem[], paramName: TFilterRangeTypes) => { if (source.length !== 0) { - return Math.min(...source.map((item) => item[param])); + return Math.min(...source.map((item) => item[paramName])); } - return [0]; + return 0; }; - const getMaxPrice = (source: TProductsItem[], param: 'price' | 'stock') => { + const getMaxPrice = (source: TProductsItem[], paramName: TFilterRangeTypes) => { if (source.length !== 0) { - return Math.max(...source.map((item) => item[param])); + return Math.max(...source.map((item) => item[paramName])); } - return [0]; + return 0; }; - const handleSliderMinInput = (event: React.ChangeEvent) => { - const param = (event.target.id === 'filter-price-min') ? 'price' : 'stock'; - const minValue = Number(event.target.value); - const maxValue = Number(searchParamsObject[`${param}range`]?.split(',')[1] ?? getMaxPrice(products, param)); - setSearchParamsObject({ ...searchParamsObject, [`${param}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); + const handleSliderFilter = (event: React.ChangeEvent) => { + const [, filterName, minOrMax] = event.target.id.split('-'); // event.target.id example: filter-price-min + const param = (filterName === 'price' || filterName === 'stock') ? filterName : 'price'; + let minValue; + let maxValue; + if (minOrMax === 'min') { + minValue = Number(event.target.value); + maxValue = Number(searchParamsObject[`${filterName}range`]?.split(',')[1] ?? getMaxPrice(products, param)); + } + if (minOrMax === 'max') { + minValue = Number(searchParamsObject[`${param}range`]?.split(',')[0] ?? getMinPrice(products, param)); + maxValue = Number(event.target.value); + } + if (minValue === undefined || maxValue === undefined) { + return; + } + setSearchParamsObject({ ...searchParamsObject, [`${filterName}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); // fillSlider('price'); }; - const handleSliderMaxInput = (event: React.ChangeEvent) => { - const param = (event.target.id === 'filter-price-max') ? 'price' : 'stock'; - const minValue = Number(searchParamsObject[`${param}range`]?.split(',')[0] ?? getMinPrice(products, param)); - const maxValue = Number(event.target.value); - setSearchParamsObject({ ...searchParamsObject, [`${param}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); - // fillSlider('stock'); - }; - const handleSearchChange = (event: React.ChangeEvent) => { if (event.target.value === '') { - const copySearchParamsObject = { ...searchParamsObject }; - delete copySearchParamsObject.search; - setSearchParamsObject(copySearchParamsObject); + const copiedSearchParamsObject = { ...searchParamsObject }; + delete copiedSearchParamsObject.search; + setSearchParamsObject(copiedSearchParamsObject); } else { setSearchParamsObject({ ...searchParamsObject, search: event.target.value }); } }; + const handleSortingChange = (event: ChangeEvent) => { if (event.target.value === 'default') { - const copySearchParamsObject = { ...searchParamsObject }; - delete copySearchParamsObject.sortby; - setSearchParamsObject(copySearchParamsObject); + const copiedSearchParamsObject = { ...searchParamsObject }; + delete copiedSearchParamsObject.sortby; + setSearchParamsObject(copiedSearchParamsObject); } else { setSearchParamsObject({ ...searchParamsObject, sortby: event.target.value }); } }; - const filterProducts = (productsArray: TProductsItem[] | []) => { - let arr = productsArray.slice(); - if (searchParamsObject.category) { - const params = searchParamsObject.category.split(','); - arr = arr.filter((elem) => params.includes(elem.category)); - } - if (searchParamsObject.brand) { - const params = searchParamsObject.brand.split(','); - arr = arr.filter((elem) => params.includes(elem.brand)); - } - if (searchParamsObject.pricerange) { - const params = searchParamsObject.pricerange.split(',').map((elem) => Number(elem)); - arr = arr.filter((elem) => elem.price >= params[0] && elem.price <= params[1]); - } - if (searchParamsObject.stockrange) { - const params = searchParamsObject.stockrange.split(',').map((elem) => Number(elem)); - arr = arr.filter((elem) => elem.stock >= params[0] && elem.stock <= params[1]); - } - // const minValue = getMinPrice(filteredSearchedProducts) - // ?? searchParamsObject?.pricerange?.split(',')[0]; - // const maxValue = getMaxPrice(filteredSearchedProducts) - // ?? searchParamsObject?.pricerange?.split(',')[1]; - // setSearchParamsObject({ ...searchParamsObject, - // pricerange: [minValue, maxValue].join(',') }); - return arr; - }; - - const searchInProducts = (productsArray: TProductsItem[] | []) => { - let arr = productsArray.slice(); - if (searchParamsObject.search) { - const query = searchParamsObject.search.trim().toLowerCase(); - arr = arr.filter((elem) => elem.title.toLowerCase().includes(query) - || elem.category.toLowerCase().includes(query) - || elem.brand.toLowerCase().includes(query) - || elem.description.toLowerCase().includes(query) - || elem.price.toString().includes(query) - || elem.discountPercentage.toString().includes(query) - || elem.rating.toString().includes(query) - || elem.stock.toString().includes(query)); - } - return arr; - }; - - const sortProducts = (productsArray: TProductsItem[] | []) => { - const { sortby } = searchParamsObject; - if (sortby === 'price-ascending') { - return productsArray.sort((a, b) => a.price - b.price); - } - if (sortby === 'price-descending') { - return productsArray.sort((a, b) => b.price - a.price); - } - if (sortby === 'rating-ascending') { - return productsArray.sort((a, b) => a.rating - b.rating); - } - if (sortby === 'rating-descending') { - return productsArray.sort((a, b) => b.rating - a.rating); - } - if (sortby === 'discount-ascending') { - return productsArray.sort((a, b) => a.discountPercentage - b.discountPercentage); - } - if (sortby === 'discount-descending') { - return productsArray.sort((a, b) => b.discountPercentage - a.discountPercentage); - } - return productsArray; - }; - - const filteredProducts = filterProducts(products); - const filteredSearchedProducts = searchInProducts(filteredProducts); - const filteredSearchedSortedProducts = sortProducts(filteredSearchedProducts); + const filteredProducts = filterProducts(products, searchParamsObject); + const filteredSearchedProducts = searchInProducts(filteredProducts, searchParamsObject); + const filteredSearchedSortedProducts = sortProducts(filteredSearchedProducts, searchParamsObject); const handleResetClick = () => { setSearchParamsObject({}); @@ -246,20 +141,12 @@ function Main(props: TMainProps) { }; const handleViewChange = (event: React.ChangeEvent) => { - const param = (event.target.id === 'products-view-list') ? 'list' : 'grid'; - setSearchParamsObject({ ...searchParamsObject, view: param }); + const viewValue = (event.target.id === 'products-view-list') ? 'list' : 'grid'; + setSearchParamsObject({ ...searchParamsObject, view: viewValue }); }; const productsView = (searchParamsObject?.view === 'list' || searchParamsObject?.view === 'grid') ? searchParamsObject.view : 'grid'; - // useEffect(() => { - // setSearchParamsObject({ ...searchParamsObject, view: 'grid' }); - // }, []); - - useEffect(() => { - setDataToLocalStorage(productsInCart); - }, [productsInCart]); - return ( {isPending @@ -268,22 +155,19 @@ function Main(props: TMainProps) { ) : (
+

Catalog

-
+
- @@ -317,7 +201,7 @@ function Main(props: TMainProps) { className={styles.productsView__label_grid} htmlFor="products-view-grid" title="View products as a grid" - aria-label="View products as a grid" + aria-label="View products as a grid." />
diff --git a/src/index.scss b/src/index.scss index fc7b6c5..3482787 100644 --- a/src/index.scss +++ b/src/index.scss @@ -114,3 +114,17 @@ h3 { font-size: 1.8rem; margin: 10px 0; } + + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + border: 0; + padding: 0; + white-space: nowrap; + clip-path: inset(100%); + clip: rect(0 0 0 0); + overflow: hidden; +} diff --git a/src/types/types.ts b/src/types/types.ts index 941777c..e425fcf 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -57,3 +57,18 @@ export interface IAddHandler extends IPromoCodeHandler{ export type TValidations = { [key:string]: boolean }; + +export type TSearchParamsObject = Record; + +export type TSetSearchParamsObject = (searchParamsObject: TSearchParamsObject) => void; + +export enum filterTypes { + category = 'category', + brand = 'brand', + price = 'price', + stock = 'stock', +} + +export type TFilterSelectionTypes = 'category' | 'brand'; + +export type TFilterRangeTypes = 'price' | 'stock'; From 5653fc7ac71478fda1ff4092d1b6e3e932bfe71a Mon Sep 17 00:00:00 2001 From: Dinara Date: Sat, 14 Jan 2023 22:40:08 +0400 Subject: [PATCH 51/65] fix: remove enum type and change back no-shadow eslint rule --- .eslintrc.json | 4 +--- src/types/types.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 0b6687a..a30a73d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -25,9 +25,7 @@ { "extensions": [".js", ".jsx", "ts", "tsx"] } ], "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "error", - "no-shadow": "off", - "@typescript-eslint/no-shadow": "error" + "@typescript-eslint/no-unused-vars": "error" }, "settings": { "import/resolver": { diff --git a/src/types/types.ts b/src/types/types.ts index e425fcf..d881298 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -62,12 +62,12 @@ export type TSearchParamsObject = Record; export type TSetSearchParamsObject = (searchParamsObject: TSearchParamsObject) => void; -export enum filterTypes { - category = 'category', - brand = 'brand', - price = 'price', - stock = 'stock', -} +// export enum filterTypes { +// category = 'category', +// brand = 'brand', +// price = 'price', +// stock = 'stock', +// } export type TFilterSelectionTypes = 'category' | 'brand'; From 6d91bc7ee1d59d87e89676027226197124144781 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sun, 15 Jan 2023 03:19:18 +0400 Subject: [PATCH 52/65] fix: fix header and 404 --- src/Components/header/index.tsx | 10 +++++----- src/Pages/PageNotFound/index.tsx | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 47a407b..008e6c9 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -1,5 +1,5 @@ // import React, { useMemo } from 'react'; -import { NavLink } from 'react-router-dom'; +import { Link } from 'react-router-dom'; import styles from './styles.module.scss'; import { TProductsItem, TProductPartialProps } from '../../types/types'; import formatPrice from '../utils/formatPrice'; @@ -29,12 +29,12 @@ export default function Header(props: TProps) { return (
); diff --git a/src/Pages/PageNotFound/index.tsx b/src/Pages/PageNotFound/index.tsx index 87398f4..9888180 100644 --- a/src/Pages/PageNotFound/index.tsx +++ b/src/Pages/PageNotFound/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { NavLink } from 'react-router-dom'; +import { Link } from 'react-router-dom'; import SiteContainer from '../../Components/UI/container/SiteContainer'; import styles from './PageNotFound.module.scss'; import emptyBox from '../../assets/images/empty.png'; @@ -9,15 +9,15 @@ function PageNotFound() {
- + A confused person inside a box

Error 404: Page Not Found!

This page does not seem to exist.

- Back to main - +
From 645ba039cabf97edc07d1d00dbb837a12949b1c8 Mon Sep 17 00:00:00 2001 From: Dinara Date: Sun, 15 Jan 2023 03:21:45 +0400 Subject: [PATCH 53/65] feat: add tests --- .../utils/test/getFilterOptions.test.tsx | 37 +++++ .../utils/test/isInSearchParams.test.tsx | 38 +++++ .../utils/test/searchInProducts.test.tsx | 128 ++++++++++++++++ .../utils/test/sortProducts.test.tsx | 139 ++++++++++++++++++ src/Pages/Main/test/main.test.tsx | 3 +- .../PageNotFound/test/PageNotFound.test.tsx | 13 ++ 6 files changed, 357 insertions(+), 1 deletion(-) create mode 100644 src/Components/utils/test/getFilterOptions.test.tsx create mode 100644 src/Components/utils/test/isInSearchParams.test.tsx create mode 100644 src/Components/utils/test/searchInProducts.test.tsx create mode 100644 src/Components/utils/test/sortProducts.test.tsx create mode 100644 src/Pages/PageNotFound/test/PageNotFound.test.tsx diff --git a/src/Components/utils/test/getFilterOptions.test.tsx b/src/Components/utils/test/getFilterOptions.test.tsx new file mode 100644 index 0000000..375497a --- /dev/null +++ b/src/Components/utils/test/getFilterOptions.test.tsx @@ -0,0 +1,37 @@ +import getFilterOptions from '../getFilterOptions'; + +const array1 = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, { + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}]; + +const array2 = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, { + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}, { + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, { + id: 11, title: 'perfume Oil', description: 'Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil', price: 13, discountPercentage: 8.4, rating: 4.26, stock: 65, brand: 'Impression of Acqua Di Gio', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/11/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/11/1.jpg', 'https://i.dummyjson.com/data/products/11/2.jpg', 'https://i.dummyjson.com/data/products/11/3.jpg', 'https://i.dummyjson.com/data/products/11/thumbnail.jpg'], +}, { + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +const result1 = ['smartphones']; + +const result2 = ['fragrances', 'laptops', 'smartphones']; + +const result3 = ['Apple', 'HP Pavilion', 'Impression of Acqua Di Gio', 'Royal_Mirage']; + +describe('getFilterOptions', () => { + test('Gets a single category', () => { + expect(getFilterOptions(array1, 'category')).toEqual(result1); + }); + test('Gets all categories in the correct order', () => { + expect(getFilterOptions(array2, 'category')).toEqual(result2); + }); + test('Gets all brands in the correct order', () => { + expect(getFilterOptions(array2, 'brand')).toEqual(result3); + }); +}); diff --git a/src/Components/utils/test/isInSearchParams.test.tsx b/src/Components/utils/test/isInSearchParams.test.tsx new file mode 100644 index 0000000..7eda6f6 --- /dev/null +++ b/src/Components/utils/test/isInSearchParams.test.tsx @@ -0,0 +1,38 @@ +import isInSearchParams from '../isInSearchParams'; + +const paramsObject = { + category: 'laptops', + brand: 'Apple', + lala: 'la', +}; + +const paramsObjectMultipleValues = { + category: 'smartphones,laptops', + brand: 'Apple,Royal_Mirage,HP Pavilion', + lala: 'la,la,la', +}; + +const paramsObjectEmpty = {}; + +describe('isInSearchParams', () => { + test('Gets correct results from an object with single values', () => { + expect(isInSearchParams('category', 'smartphones', paramsObject)).toBe(false); + expect(isInSearchParams('category', 'laptops', paramsObject)).toBe(true); + expect(isInSearchParams('brand', 'Apple', paramsObject)).toBe(true); + expect(isInSearchParams('brand', 'HP Pavilion', paramsObject)).toBe(false); + }); + test('Gets correct results from an object with multiple values', () => { + expect(isInSearchParams('category', 'smartphones', paramsObjectMultipleValues)).toBe(true); + expect(isInSearchParams('category', 'laptops', paramsObjectMultipleValues)).toBe(true); + expect(isInSearchParams('category', 'fragrance', paramsObjectMultipleValues)).toBe(false); + expect(isInSearchParams('brand', 'Apple', paramsObjectMultipleValues)).toBe(true); + expect(isInSearchParams('brand', 'HP Pavilion', paramsObjectMultipleValues)).toBe(true); + expect(isInSearchParams('brand', 'HP', paramsObjectMultipleValues)).toBe(false); + }); + test('Gets correct results from an empty object', () => { + expect(isInSearchParams('category', 'smartphones', paramsObjectEmpty)).toBe(false); + expect(isInSearchParams('category', 'laptops', paramsObjectEmpty)).toBe(false); + expect(isInSearchParams('brand', 'Apple', paramsObjectEmpty)).toBe(false); + expect(isInSearchParams('brand', 'HP Pavilion', paramsObjectEmpty)).toBe(false); + }); +}); diff --git a/src/Components/utils/test/searchInProducts.test.tsx b/src/Components/utils/test/searchInProducts.test.tsx new file mode 100644 index 0000000..6251bc2 --- /dev/null +++ b/src/Components/utils/test/searchInProducts.test.tsx @@ -0,0 +1,128 @@ +import searchInProducts from '../searchInProducts'; + +const array = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, { + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}, { + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, { + id: 11, title: 'perfume Oil', description: 'Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil', price: 13, discountPercentage: 8.4, rating: 4.26, stock: 65, brand: 'Impression of Acqua Di Gio', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/11/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/11/1.jpg', 'https://i.dummyjson.com/data/products/11/2.jpg', 'https://i.dummyjson.com/data/products/11/3.jpg', 'https://i.dummyjson.com/data/products/11/thumbnail.jpg'], +}, { + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +const paramsObjectTitleIph = { + search: 'iph', +}; + +const paramsObjectDescriptionAni = { + search: 'ani', +}; + +const paramsObjectPrice109 = { + search: '109', +}; + +const paramsObjectDiscount96 = { + search: '96', +}; + +const paramsObjectRating4Dot = { + search: '4.', +}; + +const paramsObjectStock34 = { + search: '34', +}; + +const paramsObjectBrandApple = { + search: 'Apple', +}; + +const paramsObjectCategoryFra = { + search: 'fra', +}; + +const paramsObjectNoOverlap = { + search: 'all', +}; + +const paramsObjectEmpty = {}; + +const resultTitleIph = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, { + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}]; + +const resultDescriptionAni = [{ + id: 11, title: 'perfume Oil', description: 'Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil', price: 13, discountPercentage: 8.4, rating: 4.26, stock: 65, brand: 'Impression of Acqua Di Gio', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/11/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/11/1.jpg', 'https://i.dummyjson.com/data/products/11/2.jpg', 'https://i.dummyjson.com/data/products/11/3.jpg', 'https://i.dummyjson.com/data/products/11/thumbnail.jpg'], +}]; + +const resultPrice109 = [{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}]; + +const resultDiscount96 = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}]; + +const resultRating4Dot = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, { + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}, { + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, { + id: 11, title: 'perfume Oil', description: 'Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil', price: 13, discountPercentage: 8.4, rating: 4.26, stock: 65, brand: 'Impression of Acqua Di Gio', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/11/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/11/1.jpg', 'https://i.dummyjson.com/data/products/11/2.jpg', 'https://i.dummyjson.com/data/products/11/3.jpg', 'https://i.dummyjson.com/data/products/11/thumbnail.jpg'], +}]; + +const resultStock34 = [{ + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}]; + +const resultBrandApple = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, { + id: 2, title: 'iPhone X', description: 'SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...', price: 899, discountPercentage: 17.94, rating: 4.44, stock: 34, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/2/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/2/1.jpg', 'https://i.dummyjson.com/data/products/2/2.jpg', 'https://i.dummyjson.com/data/products/2/3.jpg', 'https://i.dummyjson.com/data/products/2/thumbnail.jpg'], +}]; + +const resultCategoryFra = [{ + id: 11, title: 'perfume Oil', description: 'Mega Discount, Impression of Acqua Di Gio by GiorgioArmani concentrated attar perfume Oil', price: 13, discountPercentage: 8.4, rating: 4.26, stock: 65, brand: 'Impression of Acqua Di Gio', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/11/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/11/1.jpg', 'https://i.dummyjson.com/data/products/11/2.jpg', 'https://i.dummyjson.com/data/products/11/3.jpg', 'https://i.dummyjson.com/data/products/11/thumbnail.jpg'], +}, { + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +describe('searchInProducts', () => { + test('Correctly searches by title', () => { + expect(searchInProducts(array, paramsObjectTitleIph)).toEqual(resultTitleIph); + }); + test('Correctly searches by description', () => { + expect(searchInProducts(array, paramsObjectDescriptionAni)).toEqual(resultDescriptionAni); + }); + test('Correctly searches by price', () => { + expect(searchInProducts(array, paramsObjectPrice109)).toEqual(resultPrice109); + }); + test('Correctly searches by discount', () => { + expect(searchInProducts(array, paramsObjectDiscount96)).toEqual(resultDiscount96); + }); + test('Correctly searches by rating', () => { + expect(searchInProducts(array, paramsObjectRating4Dot)).toEqual(resultRating4Dot); + }); + test('Correctly searches by stock', () => { + expect(searchInProducts(array, paramsObjectStock34)).toEqual(resultStock34); + }); + test('Correctly searches by brand', () => { + expect(searchInProducts(array, paramsObjectBrandApple)).toEqual(resultBrandApple); + }); + test('Correctly searches by category', () => { + expect(searchInProducts(array, paramsObjectCategoryFra)).toEqual(resultCategoryFra); + }); + test('Returns correct results when there is no overlap', () => { + expect(searchInProducts(array, paramsObjectNoOverlap)).toEqual([]); + }); + test('Returns correct results when no search query is passed', () => { + expect(searchInProducts(array, paramsObjectEmpty)).toEqual(array); + }); +}); diff --git a/src/Components/utils/test/sortProducts.test.tsx b/src/Components/utils/test/sortProducts.test.tsx new file mode 100644 index 0000000..d92adaa --- /dev/null +++ b/src/Components/utils/test/sortProducts.test.tsx @@ -0,0 +1,139 @@ +import sortProducts from '../sortProducts'; + +const array = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, +{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, { + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +const paramsObjectPriceAscending = { + category: 'laptops', + lala: 'la', + sortby: 'price-ascending', +}; + +const paramsObjectPriceDescending = { + category: 'laptops', + lala: 'la', + sortby: 'price-descending', +}; + +const paramsObjectRatingAscending = { + category: 'laptops', + lala: 'la', + sortby: 'rating-ascending', +}; + +const paramsObjectRatingDescending = { + category: 'laptops', + lala: 'la', + sortby: 'rating-descending', +}; + +const paramsObjectDiscountAscending = { + category: 'laptops', + lala: 'la', + sortby: 'discount-ascending', +}; + +const paramsObjectDiscountDescending = { + category: 'laptops', + lala: 'la', + sortby: 'discount-descending', +}; + +const paramsObjectEmpty = {}; + +const paramsObjectIncorrectSortingValue = { + category: 'laptops', + lala: 'la', + sortby: 'discount-d', +}; + +const resultPriceAscending = [{ + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}, +{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, +{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}]; + +const resultPriceDescending = [{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, +{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, +{ + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +const resultRatingAscending = [{ + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}, +{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, +{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}]; + +const resultRatingDescending = [{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, +{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, +{ + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +const resultDiscountAscending = [{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}, +{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, +{ + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}]; + +const resultDiscountDescending = [{ + id: 12, title: 'Brown Perfume', description: 'Royal_Mirage Sport Brown Perfume for Men & Women - 120ml', price: 40, discountPercentage: 15.66, rating: 4, stock: 52, brand: 'Royal_Mirage', category: 'fragrances', thumbnail: 'https://i.dummyjson.com/data/products/12/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/12/1.jpg', 'https://i.dummyjson.com/data/products/12/2.jpg', 'https://i.dummyjson.com/data/products/12/3.png', 'https://i.dummyjson.com/data/products/12/4.jpg', 'https://i.dummyjson.com/data/products/12/thumbnail.jpg'], +}, +{ + id: 1, title: 'iPhone 9', description: 'An apple mobile which is nothing like apple', price: 549, discountPercentage: 12.96, rating: 4.69, stock: 94, brand: 'Apple', category: 'smartphones', thumbnail: 'https://i.dummyjson.com/data/products/1/thumbnail.jpg', images: ['https://i.dummyjson.com/data/products/1/1.jpg', 'https://i.dummyjson.com/data/products/1/2.jpg', 'https://i.dummyjson.com/data/products/1/3.jpg', 'https://i.dummyjson.com/data/products/1/4.jpg', 'https://i.dummyjson.com/data/products/1/thumbnail.jpg'], +}, +{ + id: 10, title: 'HP Pavilion 15-DK1056WM', description: 'HP Pavilion 15-DK1056WM Gaming Laptop 10th Gen Core i5, 8GB, 256GB SSD, GTX 1650 4GB, Windows 10', price: 1099, discountPercentage: 6.18, rating: 4.43, stock: 89, brand: 'HP Pavilion', category: 'laptops', thumbnail: 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg', images: ['https://i.dummyjson.com/data/products/10/1.jpg', 'https://i.dummyjson.com/data/products/10/2.jpg', 'https://i.dummyjson.com/data/products/10/3.jpg', 'https://i.dummyjson.com/data/products/10/thumbnail.jpeg'], +}]; + +describe('sortProducts', () => { + test('Correctly sorts by price, ascending', () => { + expect(sortProducts(array, paramsObjectPriceAscending)).toEqual(resultPriceAscending); + }); + test('Correctly sorts by price, descending', () => { + expect(sortProducts(array, paramsObjectPriceDescending)).toEqual(resultPriceDescending); + }); + test('Correctly sorts by rating, ascending', () => { + expect(sortProducts(array, paramsObjectRatingAscending)).toEqual(resultRatingAscending); + }); + test('Correctly sorts by rating, descending', () => { + expect(sortProducts(array, paramsObjectRatingDescending)).toEqual(resultRatingDescending); + }); + test('Correctly sorts by discount, ascending', () => { + expect(sortProducts(array, paramsObjectDiscountAscending)).toEqual(resultDiscountAscending); + }); + test('Correctly sorts by discount, descending', () => { + expect(sortProducts(array, paramsObjectDiscountDescending)).toEqual(resultDiscountDescending); + }); + test('Does not change array if sorting is not specified or has incorrect value', () => { + expect(sortProducts(array, paramsObjectEmpty)).toEqual(array); + expect(sortProducts(array, paramsObjectIncorrectSortingValue)).toEqual(array); + }); +}); diff --git a/src/Pages/Main/test/main.test.tsx b/src/Pages/Main/test/main.test.tsx index 51430cd..5063c7a 100644 --- a/src/Pages/Main/test/main.test.tsx +++ b/src/Pages/Main/test/main.test.tsx @@ -1,8 +1,9 @@ import { render, screen } from '@testing-library/react'; import Main from '../index'; // Тест. Проверяем зарендерилась страница с теми блоками которые мы ожидаем на ней увидеть -test('renders main page', () => { +test('renders main page - test not done!', () => { // render(
); // const textElement = screen.getByText(/Main page component №1/i); // expect(textElement).toBeInTheDocument(); + expect(true).toBe(true); }); diff --git a/src/Pages/PageNotFound/test/PageNotFound.test.tsx b/src/Pages/PageNotFound/test/PageNotFound.test.tsx new file mode 100644 index 0000000..f2b9051 --- /dev/null +++ b/src/Pages/PageNotFound/test/PageNotFound.test.tsx @@ -0,0 +1,13 @@ +import { render, screen } from '@testing-library/react'; +import { HashRouter } from 'react-router-dom'; +import PageNotFound from '../index'; + +test('Correctly renders page 404', () => { + render(); + const title = screen.getByText(/Error 404: Page Not Found!/i); + const image = screen.getByAltText(/A confused person inside a box/i) as HTMLImageElement; + const link = screen.getByText(/Back to main/i); + expect(title).toBeInTheDocument(); + expect(image.src).toContain('empty.png'); + expect(link).toBeInTheDocument(); +}); From 1c1b63fa71298f5d933c151c68fa981e4ac30cc4 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Tue, 17 Jan 2023 14:12:23 +0300 Subject: [PATCH 54/65] fix: delete type any from custom hook useFetching. feat: add react test to the component ProductCartButton.tsx, add test to utils functions (#25) --- src/App/App.tsx | 21 +++---- src/App/RootRouter/index.tsx | 12 ++-- .../Cart/ApprovePerchase/ApprovePurchase.tsx | 4 +- .../UI/button/ProductCartButton.test.tsx | 8 +++ src/Components/utils/checkUniqueImgs.ts | 3 - .../utils/test/countTotalCount.test.tsx | 56 +++++++++++++++++++ .../test/countTotalSumWithDiscounts.test.tsx | 25 +++++++++ .../utils/test/isFormValidHandle.test.tsx | 22 ++++++++ .../utils/test/isPromoCodeTrue.test.tsx | 45 +++++++++++++++ src/Pages/Cart/cart.tsx | 13 +---- src/hooks/useFetching.ts | 2 +- 11 files changed, 173 insertions(+), 38 deletions(-) create mode 100644 src/Components/UI/button/ProductCartButton.test.tsx create mode 100644 src/Components/utils/test/countTotalCount.test.tsx create mode 100644 src/Components/utils/test/countTotalSumWithDiscounts.test.tsx create mode 100644 src/Components/utils/test/isFormValidHandle.test.tsx create mode 100644 src/Components/utils/test/isPromoCodeTrue.test.tsx diff --git a/src/App/App.tsx b/src/App/App.tsx index c50a2a4..6edc6db 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -8,27 +8,24 @@ import handleLocalStorage from '../Components/utils/handleLocalStorage'; import setDataToLocalStorage from '../Components/utils/setDataToLocalStorage'; function App() { - const [ - productsInCart, setProductsInCart, - ] = useState(handleLocalStorage()); const [ productsInCartCount, setProductsInCartCount, ] = useState(handleLocalStorage()); const [products, setProducts] = useState(null); const [formVisible, setFormVisible] = useState(false); const [fetchProductsById, isPending] = useFetching(async () => { - const response = await PostService.getCartItems(productsInCart) + const response = await PostService.getCartItems(productsInCartCount) .then((items) => items.map((item) => item)); setProducts(response); }); useEffect(() => { fetchProductsById(); - }, [productsInCart]); + }, [productsInCartCount]); useEffect(() => { - setDataToLocalStorage(productsInCart); - }, [productsInCart]); + setDataToLocalStorage(productsInCartCount); + }, [productsInCartCount]); const increaseProductCount = (event: React.MouseEvent) => { const cur = Number(event.currentTarget.value); @@ -55,7 +52,7 @@ function App() { const cur = Number(event.currentTarget.value); const result = productsInCartCount.reduce((acc, product) => { if (product.id === cur && product.count === 1) { - setProductsInCart(productsInCart.filter((el) => el.id !== cur)); + setProductsInCartCount(productsInCartCount.filter((el) => el.id !== cur)); return acc; } if (product.id === cur) { @@ -69,18 +66,18 @@ function App() { setDataToLocalStorage(result); }; - const isProductInCart = (id?: number): boolean => productsInCart.some((item) => item.id === id); + const isProductInCart = (id?: number): boolean => productsInCartCount.some( + (item) => item.id === id, + ); const addToCart = (id: number) => { if (!isProductInCart(id)) { - setProductsInCart([...productsInCart, { id, count: 1 }]); setProductsInCartCount([...productsInCartCount, { id, count: 1 }]); } }; const dropFromCart = (id: number) => { if (isProductInCart(id)) { - setProductsInCart(productsInCart.filter((item) => item.id !== id)); setProductsInCartCount(productsInCartCount.filter((item) => item.id !== id)); } }; @@ -89,8 +86,6 @@ function App() { @@ -60,7 +58,7 @@ export default function RootRouter(props: TRootRouterProps) { path="/product/:id" element={( { setTimeout(() => { setFormVisible(false); - setProductsInCart([]); setProductsInCartCount([]); history('/', { replace: true }); }, 5000); diff --git a/src/Components/UI/button/ProductCartButton.test.tsx b/src/Components/UI/button/ProductCartButton.test.tsx new file mode 100644 index 0000000..6e37614 --- /dev/null +++ b/src/Components/UI/button/ProductCartButton.test.tsx @@ -0,0 +1,8 @@ +import { render, screen } from '@testing-library/react'; +import ProductCartButton from './ProductCartButton'; + +test('renders main page - test not done!', () => { + render( console.log('click')} value={0}>Test button); + const textElement = screen.getByText(/Test button/i); + expect(textElement).toBeInTheDocument(); +}); diff --git a/src/Components/utils/checkUniqueImgs.ts b/src/Components/utils/checkUniqueImgs.ts index e2a2ffb..6d690f3 100644 --- a/src/Components/utils/checkUniqueImgs.ts +++ b/src/Components/utils/checkUniqueImgs.ts @@ -6,9 +6,6 @@ function checkUniqueImgs( callBack: (arr: string[]) => void, ) { const result = arrImgSizes.reduce((acc, el, index) => { - // if (!acc.includes(arrImg[index])) { - // acc = [...acc, arrImg[index]]; - // } if ( arrImgSizes.indexOf(el) !== arrImgSizes.lastIndexOf(el) diff --git a/src/Components/utils/test/countTotalCount.test.tsx b/src/Components/utils/test/countTotalCount.test.tsx new file mode 100644 index 0000000..8a621eb --- /dev/null +++ b/src/Components/utils/test/countTotalCount.test.tsx @@ -0,0 +1,56 @@ +import countTotalCount from '../countTotalCount'; + +const firstData = [ + { + id: 1, + count: 2, + }, + { + id: 2, + count: 1, + }, + { + id: 3, + count: 5, + }, + { + id: 4, + count: 3, + }, +]; + +const firstResult = 11; + +const secondData = [ + { + id: 1, + count: 2, + }, + { + id: 2, + count: 1, + }, + { + id: 3, + count: 5, + }, + { + id: 4, + count: 3, + }, + { + id: 5, + count: 1, + }, +]; + +const secondResult = 12; + +describe('countTotalCount', () => { + test('Gets the first data array', () => { + expect(countTotalCount(firstData)).toEqual(firstResult); + }); + test('Gets the second data array', () => { + expect(countTotalCount(secondData)).toEqual(secondResult); + }); +}); diff --git a/src/Components/utils/test/countTotalSumWithDiscounts.test.tsx b/src/Components/utils/test/countTotalSumWithDiscounts.test.tsx new file mode 100644 index 0000000..527290a --- /dev/null +++ b/src/Components/utils/test/countTotalSumWithDiscounts.test.tsx @@ -0,0 +1,25 @@ +import countTotalSumWithDiscounts from '../countTotalSumWithDiscounts'; + +const firstCurrenCost = 100; + +const firstArrayOfDiscounts = [10, 20]; + +const firstResult = '70.00'; + +const secondCurrenCost = 1000; + +const secondArrayOfDiscounts = [10, 20, 15]; + +const secondResult = '550.00'; + +describe('countTotalSumWithDiscounts', () => { + test('Gets the first sum with discount', () => { + expect(countTotalSumWithDiscounts(firstCurrenCost, firstArrayOfDiscounts)).toBe(firstResult); + }); + test('Gets the second data array', () => { + expect(countTotalSumWithDiscounts( + secondCurrenCost, + secondArrayOfDiscounts, + )).toBe(secondResult); + }); +}); diff --git a/src/Components/utils/test/isFormValidHandle.test.tsx b/src/Components/utils/test/isFormValidHandle.test.tsx new file mode 100644 index 0000000..823f15d --- /dev/null +++ b/src/Components/utils/test/isFormValidHandle.test.tsx @@ -0,0 +1,22 @@ +import isFormValidHandle from '../isFormValidHandle'; + +const firstArray = [true, true, false, true]; +const firstResult = false; + +const secondArray = [true, true, true, true]; +const secondResult = true; + +const thirdArray = [true, true, true, true, false]; +const thirdResult = false; + +describe('isFormValidHandle', () => { + test('Gets the first array', () => { + expect(isFormValidHandle(firstArray)).toEqual(firstResult); + }); + test('Gets the second array', () => { + expect(isFormValidHandle(secondArray)).toEqual(secondResult); + }); + test('Gets the third array', () => { + expect(isFormValidHandle(thirdArray)).toEqual(thirdResult); + }); +}); diff --git a/src/Components/utils/test/isPromoCodeTrue.test.tsx b/src/Components/utils/test/isPromoCodeTrue.test.tsx new file mode 100644 index 0000000..d94d5c4 --- /dev/null +++ b/src/Components/utils/test/isPromoCodeTrue.test.tsx @@ -0,0 +1,45 @@ +import isPromoCodeTrue from '../isPromoCodeTrue'; + +const promoCodesArray = [ + { name: 'true', discount: 10 }, + { name: 'false', discount: 15 }, + { name: 'rs', discount: 20 }, + { name: 'asdf', discount: 25 }, + { name: 'not_code', discount: 30 }, +]; + +const firstCode = 'true'; +const firstCurrentCodesArray = [10, 15]; +const firstResult = false; + +const secondCode = 'rs'; +const secondCurrentCodesArray = [10, 15, 25, 30]; +const secondResult = true; + +const thirdCode = 'ASDF'; +const thirdCurrentCodesArray = [10, 15, 20, 30]; +const thirdResult = true; + +describe('isPromoCodeTrue', () => { + test('Should check codes from firstCurrentCodesArray', () => { + expect(isPromoCodeTrue( + promoCodesArray, + firstCode, + firstCurrentCodesArray, + )).toBe(firstResult); + }); + test('Should check codes from secondCurrentCodesArray', () => { + expect(isPromoCodeTrue( + promoCodesArray, + secondCode, + secondCurrentCodesArray, + )).toBe(secondResult); + }); + test('Should check codes from thirdCurrentCodesArray', () => { + expect(isPromoCodeTrue( + promoCodesArray, + thirdCode, + thirdCurrentCodesArray, + )).toBe(thirdResult); + }); +}); diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 8a27c24..0125141 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -2,8 +2,6 @@ import React, { useState, useEffect } from 'react'; import { useSearchParams, Link } from 'react-router-dom'; import ApprovePurchase from '../../Components/Cart/ApprovePerchase/ApprovePurchase'; -// import React, { useEffect, useState } from 'react'; -// import PostService from '../../Components/API/PostService'; import CartProduct from '../../Components/Cart/CartProduct/CartProduct'; import CartPagination from '../../Components/Cart/Pagination/CartPagination'; import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; @@ -13,20 +11,15 @@ import Purchase from '../../Components/Cart/PurchaseModal/Purchase/Purchase'; import CartContainer from '../../Components/UI/container/CartContainer/CartContainer'; import SiteContainer from '../../Components/UI/container/SiteContainer'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; -// eslint-disable-next-line no-unused-vars import countTotalCost from '../../Components/utils/countTotalCost'; import countTotalCount from '../../Components/utils/countTotalCount'; import countTotalSumWithDiscounts from '../../Components/utils/countTotalSumWithDiscounts'; -// import useFetching from '../../hooks/useFetching'; import { TProductsItem, TProductPartialProps } from '../../types/types'; import formatPrice from '../../Components/utils/formatPrice'; import styles from './cart.module.scss'; import emptyCartImg from '../../assets/images/emptyCart.svg'; type TCartProps = { - productsInCart: TProductPartialProps[] - // eslint-disable-next-line no-unused-vars - setProductsInCart(arr: TProductPartialProps[]): void; isPending: boolean; productsInCartCount: TProductPartialProps[]; // eslint-disable-next-line no-unused-vars @@ -43,7 +36,7 @@ type TCartProps = { function Cart(props: TCartProps) { const { - productsInCart, setProductsInCart, isPending, productsInCartCount, setProductsInCartCount, products, increaseProductCount, decreaseProductCount, formVisible, setFormVisible, + isPending, productsInCartCount, setProductsInCartCount, products, increaseProductCount, decreaseProductCount, formVisible, setFormVisible, } = props; const [totalCount, setTotalCount] = useState(countTotalCount(productsInCartCount)); const [totalCost, setTotalCost] = useState(0); @@ -106,7 +99,7 @@ function Cart(props: TCartProps) { useEffect(() => { setTotalCount(countTotalCount(productsInCartCount)); - }, [productsInCartCount, productsInCart]); + }, [productsInCartCount]); useEffect(() => { if (products) { @@ -141,7 +134,7 @@ function Cart(props: TCartProps) { if (showAffirmative) { return ( - + ); } diff --git a/src/hooks/useFetching.ts b/src/hooks/useFetching.ts index 9bb1784..362c903 100644 --- a/src/hooks/useFetching.ts +++ b/src/hooks/useFetching.ts @@ -1,6 +1,6 @@ import { useState } from 'react'; -const useFetching = (callback: () => any) => { +const useFetching = (callback: () => void) => { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(''); From 3394fe2bb7d088d58be82ac0bb7cf488af9d80e5 Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 17 Jan 2023 22:41:42 +0400 Subject: [PATCH 55/65] fix: restructure 'view' radio-buttons code to stop eslint error --- src/Pages/Main/index.tsx | 51 +++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index a50cc16..853b836 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,4 +1,4 @@ -/* eslint-disable jsx-a11y/label-has-associated-control */ +// /* eslint-disable jsx-a11y/label-has-associated-control */ import React, { ChangeEvent, useEffect, useState } from 'react'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; @@ -190,32 +190,29 @@ function Main(props: TMainProps) {
- -
Date: Tue, 17 Jan 2023 22:48:12 +0400 Subject: [PATCH 56/65] fix: change card expiration date placeholder fontsize --- .../Cart/PurchaseModal/Purchase/purchase.module.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss index 6f3373b..be4a1be 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss +++ b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss @@ -122,6 +122,9 @@ &:focus { outline: 0; } + &::placeholder { + font-size: 0.9rem; + } } } From 3a22e85094212e9ae54bcbfec2423f960068b413 Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 17 Jan 2023 23:31:35 +0400 Subject: [PATCH 57/65] fix: remove eslint errors --- src/Components/Cart/PurchaseModal/Modal.tsx | 1 - .../Cart/PurchaseModal/Purchase/Purchase.tsx | 2 - .../CarouselImages/CarouselImages.tsx | 1 - .../ProductImagesCarousel.tsx | 2 - src/Components/ProductPage/ProductPage.tsx | 7 +--- .../UI/button/ProductCartButton.tsx | 1 - src/Components/utils/areAllInputsValid.ts | 5 +-- src/Components/utils/checkUniqueImgs.ts | 8 +--- src/Components/utils/countTotalCost.ts | 4 +- src/Components/utils/countTotalCount.ts | 6 +-- .../utils/countTotalSumWithDiscounts.ts | 6 +-- src/Components/utils/isFormValidHandle.ts | 5 +-- src/Components/utils/isPromoCodeTrue.ts | 5 ++- src/Pages/Cart/cart.tsx | 37 ++++++++++++++----- src/Pages/Main/index.tsx | 1 - src/hooks/useValidation.ts | 1 - src/types/types.ts | 7 +--- 17 files changed, 40 insertions(+), 59 deletions(-) diff --git a/src/Components/Cart/PurchaseModal/Modal.tsx b/src/Components/Cart/PurchaseModal/Modal.tsx index 0ae010c..bb4cdb2 100644 --- a/src/Components/Cart/PurchaseModal/Modal.tsx +++ b/src/Components/Cart/PurchaseModal/Modal.tsx @@ -6,7 +6,6 @@ import styles from './modal.module.scss'; interface IModal { children: React.ReactNode visible: boolean - // eslint-disable-next-line no-unused-vars setVisible: (bool:boolean) => void } diff --git a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx index da32856..933d5f7 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx +++ b/src/Components/Cart/PurchaseModal/Purchase/Purchase.tsx @@ -5,13 +5,11 @@ import isFormValidHandle from '../../../utils/isFormValidHandle'; import styles from './purchase.module.scss'; interface IPurchase { - // eslint-disable-next-line no-unused-vars setShowAffirmative: (bool: boolean) => void } function Purchase({ setShowAffirmative }: IPurchase) { const [runValidate, setRunValidate] = useState(false); - // eslint-disable-next-line no-unused-vars const [isFormValid, setIsFormValid] = useState(false); const handleClickButton = (event: React.MouseEvent, isFormVal: boolean) => { event.preventDefault(); diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx index c61fa79..a4064c3 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx +++ b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx @@ -5,7 +5,6 @@ import styles from './CarouselImages.module.scss'; interface ICarouselImages { value: string - // eslint-disable-next-line no-unused-vars setCurrentImg(str:string): void } diff --git a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx index 56c2a27..84a2212 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx +++ b/src/Components/ProductPage/ProductImagesCarousel/ProductImagesCarousel.tsx @@ -4,7 +4,6 @@ import styles from './ProductImagesCarousel.module.scss'; interface IProductImagesCarousel { cleanArrImg: string[] - // eslint-disable-next-line no-unused-vars setCurrentImg(str:string): void } @@ -12,7 +11,6 @@ function ProductImagesCarousel({ cleanArrImg, setCurrentImg }: IProductImagesCar const amountOfImgs = cleanArrImg.length; const IMAGE_WIDTH = 190; - // eslint-disable-next-line no-unused-vars const [currentOffset, setCurrentOffset] = useState(0); const handleLeftArrowClick = (px: number) => { diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index 8510012..c8762e8 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ import React, { useEffect, useMemo, useState } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; import useFetching from '../../hooks/useFetching'; @@ -16,9 +15,7 @@ import styles from './productPage.module.scss'; interface IProductPage { productsInCart: TProductPartialProps[] - // eslint-disable-next-line no-unused-vars addToCart(id: number | undefined): void; - // eslint-disable-next-line no-unused-vars dropFromCart(id: number | undefined): void; setFormVisible: (bool:boolean) => void } @@ -88,9 +85,7 @@ function ProductPage({ const handleBuyButtonClick = () => { const isProductInCart = productsInCart.reduce((acc, el) => { if (el.id === id) { - // eslint-disable-next-line no-param-reassign - acc = true; - return acc; + return true; } return acc; }, false); diff --git a/src/Components/UI/button/ProductCartButton.tsx b/src/Components/UI/button/ProductCartButton.tsx index 9bbab68..8f3b205 100644 --- a/src/Components/UI/button/ProductCartButton.tsx +++ b/src/Components/UI/button/ProductCartButton.tsx @@ -3,7 +3,6 @@ import styles from './ProductCartButton.module.scss'; interface CartButtonProps { children: React.ReactNode - // eslint-disable-next-line no-unused-vars onClick: (event:React.MouseEvent) => void value: number diff --git a/src/Components/utils/areAllInputsValid.ts b/src/Components/utils/areAllInputsValid.ts index fe8e752..c0f5731 100644 --- a/src/Components/utils/areAllInputsValid.ts +++ b/src/Components/utils/areAllInputsValid.ts @@ -1,12 +1,9 @@ -// eslint-disable-next-line no-unused-vars type TareAllInputsValid = (args: boolean[]) => boolean const areAllInputsValid: TareAllInputsValid = (args) => { const result = args.reduce((acc, bool) => { if (bool) { - // eslint-disable-next-line no-param-reassign - acc = false; - return acc; + return false; } return acc; }, true); diff --git a/src/Components/utils/checkUniqueImgs.ts b/src/Components/utils/checkUniqueImgs.ts index 6d690f3..6625c14 100644 --- a/src/Components/utils/checkUniqueImgs.ts +++ b/src/Components/utils/checkUniqueImgs.ts @@ -1,8 +1,6 @@ -/* eslint-disable no-param-reassign */ function checkUniqueImgs( arrImgSizes: number[], arrImg: string[], - // eslint-disable-next-line no-unused-vars callBack: (arr: string[]) => void, ) { const result = arrImgSizes.reduce((acc, el, index) => { @@ -12,12 +10,10 @@ function checkUniqueImgs( && !acc.includes(arrImg[index]) && !acc.includes(arrImg[arrImgSizes.indexOf(el)]) ) { - acc = [...acc, arrImg[arrImgSizes.indexOf(el)]]; - return acc; + return [...acc, arrImg[arrImgSizes.indexOf(el)]]; } if (arrImgSizes.indexOf(el) === arrImgSizes.lastIndexOf(el) && !acc.includes(arrImg[index])) { - acc = [...acc, arrImg[index]]; - return acc; + return [...acc, arrImg[index]]; } return acc; }, []); diff --git a/src/Components/utils/countTotalCost.ts b/src/Components/utils/countTotalCost.ts index c5bcede..9e28f52 100644 --- a/src/Components/utils/countTotalCost.ts +++ b/src/Components/utils/countTotalCost.ts @@ -4,9 +4,7 @@ const countTotalCost = (arr: TProductsItem[], arr2: TProductPartialProps[]) => { const result = arr.reduce((acc, product, index) => { const currentProductCount = arr2[index] ? arr2[index].count : 0; if (arr.length === arr2.length) { - // eslint-disable-next-line no-param-reassign - acc += product.price * currentProductCount; - return acc; + return acc + product.price * currentProductCount; } return acc; }, 0); diff --git a/src/Components/utils/countTotalCount.ts b/src/Components/utils/countTotalCount.ts index a3d0412..17bc2b7 100644 --- a/src/Components/utils/countTotalCount.ts +++ b/src/Components/utils/countTotalCount.ts @@ -1,11 +1,7 @@ import { TProductPartialProps } from '../../types/types'; const countTotalCount = (arr: TProductPartialProps[]) => { - const result = arr.reduce((acc, product) => { - // eslint-disable-next-line no-param-reassign - acc += product.count; - return acc; - }, 0); + const result = arr.reduce((acc, product) => acc + product.count, 0); return result; }; diff --git a/src/Components/utils/countTotalSumWithDiscounts.ts b/src/Components/utils/countTotalSumWithDiscounts.ts index 73d5ee5..0314bd6 100644 --- a/src/Components/utils/countTotalSumWithDiscounts.ts +++ b/src/Components/utils/countTotalSumWithDiscounts.ts @@ -1,9 +1,5 @@ const countTotalSumWithDiscounts = (currentCost: number, arrOfDiscounts: number[]) => { - const totalDiscounts = arrOfDiscounts.reduce((acc, discount) => { - // eslint-disable-next-line no-param-reassign - acc += discount; - return acc; - }, 0); + const totalDiscounts = arrOfDiscounts.reduce((acc, discount) => acc + discount, 0); const result = (currentCost - (currentCost / 100) * totalDiscounts).toFixed(2); diff --git a/src/Components/utils/isFormValidHandle.ts b/src/Components/utils/isFormValidHandle.ts index b768724..6ea22ec 100644 --- a/src/Components/utils/isFormValidHandle.ts +++ b/src/Components/utils/isFormValidHandle.ts @@ -1,12 +1,9 @@ -// eslint-disable-next-line no-unused-vars type TIsFormValidHandle = (args: boolean[]) => boolean const isFormValidHandle: TIsFormValidHandle = (args) => { const result = args.reduce((acc, bool) => { if (!bool) { - // eslint-disable-next-line no-param-reassign - acc = false; - return acc; + return false; } return acc; }, true); diff --git a/src/Components/utils/isPromoCodeTrue.ts b/src/Components/utils/isPromoCodeTrue.ts index 5000682..a4be378 100644 --- a/src/Components/utils/isPromoCodeTrue.ts +++ b/src/Components/utils/isPromoCodeTrue.ts @@ -4,8 +4,9 @@ const isPromoCodeTrue = (promoCodesArr: TPromoCodesArr, code:string, currentCode let result = false; promoCodesArr.forEach((item) => { - // eslint-disable-next-line max-len - if (item.name === code.toLocaleLowerCase().trim() && !currentCodes.includes(item.discount)) result = true; + if (item.name === code.toLocaleLowerCase().trim() && !currentCodes.includes(item.discount)) { + result = true; + } }); return result; diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 0125141..4998be0 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,4 +1,3 @@ -/* eslint-disable max-len */ import React, { useState, useEffect } from 'react'; import { useSearchParams, Link } from 'react-router-dom'; import ApprovePurchase from '../../Components/Cart/ApprovePerchase/ApprovePurchase'; @@ -22,21 +21,24 @@ import emptyCartImg from '../../assets/images/emptyCart.svg'; type TCartProps = { isPending: boolean; productsInCartCount: TProductPartialProps[]; - // eslint-disable-next-line no-unused-vars setProductsInCartCount(arr: TProductPartialProps[]): void; products: TProductsItem[] | null; - // eslint-disable-next-line no-unused-vars increaseProductCount(event: React.MouseEvent): void; - // eslint-disable-next-line no-unused-vars decreaseProductCount(event: React.MouseEvent): void; formVisible: boolean; - // eslint-disable-next-line no-unused-vars setFormVisible(bool:boolean): void; } function Cart(props: TCartProps) { const { - isPending, productsInCartCount, setProductsInCartCount, products, increaseProductCount, decreaseProductCount, formVisible, setFormVisible, + isPending, + productsInCartCount, + setProductsInCartCount, + products, + increaseProductCount, + decreaseProductCount, + formVisible, + setFormVisible, } = props; const [totalCount, setTotalCount] = useState(countTotalCount(productsInCartCount)); const [totalCost, setTotalCost] = useState(0); @@ -48,7 +50,6 @@ function Cart(props: TCartProps) { // Блок с пагинацией - // eslint-disable-next-line no-unused-vars const [searchParams, setSearchParams] = useSearchParams(); const initialStateToProductsPerPage = Number(searchParams.get('limit')) || 3; @@ -134,7 +135,11 @@ function Cart(props: TCartProps) { if (showAffirmative) { return ( - + ); } @@ -155,7 +160,14 @@ function Cart(props: TCartProps) {

Cart

- + { currentProducts?.map((product: TProductsItem, index) => (
) :

No applied codes

} - +
) => void, - // eslint-disable-next-line no-unused-vars, no-undef onClickHandlerDecrease: (event: React.MouseEvent) => void } @@ -44,13 +43,11 @@ export interface IPromoCodeHandler { todo: string code: string discount: number - // eslint-disable-next-line no-unused-vars, no-undef setCode: (event: React.MouseEvent, isAdd: boolean) => void } export interface IAddHandler extends IPromoCodeHandler{ code: string - // eslint-disable-next-line no-unused-vars inputData: (string:string) => void } From e77c110118840f24bda6653b5e1e15b7abeb81da Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 17 Jan 2023 23:58:36 +0400 Subject: [PATCH 58/65] fix: fix styles for 'view' radio-buttons --- src/Pages/Main/Main.module.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Pages/Main/Main.module.scss b/src/Pages/Main/Main.module.scss index 19cc1df..90238d1 100644 --- a/src/Pages/Main/Main.module.scss +++ b/src/Pages/Main/Main.module.scss @@ -21,6 +21,11 @@ align-items: center; } +.productsView div { + display: flex; + align-items: center; +} + .productsView input[type="radio"] { appearance: none; } From 75fcfe1f3dcac2ff6c9a179726a7077e75f86688 Mon Sep 17 00:00:00 2001 From: Dinara Date: Wed, 18 Jan 2023 01:00:40 +0400 Subject: [PATCH 59/65] fix: fix breadcrumbs link --- src/Components/ProductPage/ProductPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index c8762e8..ac7a7e6 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -113,7 +113,7 @@ function ProductPage({ } const linkToCategories = `/?category=${currentPage?.category}`; - const linkToBrands = `/?brand=${currentPage?.brand}`; + const linkToBrands = `/?category=${currentPage?.category}&brand=${currentPage?.brand}`; return ( From bd949a48106e175ee7a84b24405339578187aa1b Mon Sep 17 00:00:00 2001 From: Buffik Date: Wed, 18 Jan 2023 17:03:03 +0300 Subject: [PATCH 60/65] refactor: delete console.log --- .../{ApprovePerchase => ApprovePurchase}/ApprovePurchase.tsx | 0 .../approvePurchase.module.scss | 0 src/Pages/Cart/cart.tsx | 2 +- src/hooks/useValidation.ts | 2 -- 4 files changed, 1 insertion(+), 3 deletions(-) rename src/Components/Cart/{ApprovePerchase => ApprovePurchase}/ApprovePurchase.tsx (100%) rename src/Components/Cart/{ApprovePerchase => ApprovePurchase}/approvePurchase.module.scss (100%) diff --git a/src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx b/src/Components/Cart/ApprovePurchase/ApprovePurchase.tsx similarity index 100% rename from src/Components/Cart/ApprovePerchase/ApprovePurchase.tsx rename to src/Components/Cart/ApprovePurchase/ApprovePurchase.tsx diff --git a/src/Components/Cart/ApprovePerchase/approvePurchase.module.scss b/src/Components/Cart/ApprovePurchase/approvePurchase.module.scss similarity index 100% rename from src/Components/Cart/ApprovePerchase/approvePurchase.module.scss rename to src/Components/Cart/ApprovePurchase/approvePurchase.module.scss diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 4998be0..62473f4 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { useSearchParams, Link } from 'react-router-dom'; -import ApprovePurchase from '../../Components/Cart/ApprovePerchase/ApprovePurchase'; +import ApprovePurchase from '../../Components/Cart/ApprovePurchase/ApprovePurchase'; import CartProduct from '../../Components/Cart/CartProduct/CartProduct'; import CartPagination from '../../Components/Cart/Pagination/CartPagination'; import DeleteCode from '../../Components/Cart/Promo/handleCodes/DeleteCode'; diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts index 13cc205..6743a8b 100644 --- a/src/hooks/useValidation.ts +++ b/src/hooks/useValidation.ts @@ -138,13 +138,11 @@ const useValidation = (value: string, validations:TValidations) => { case 'isCardDateMonthInvalid': if (value.trim().length === 1 && !/^([1-9])$/.test(value.trim())) { - console.log('here'); setIsCardDateMonthInvalid(true); break; } else setIsCardDateMonthInvalid(false); if (value.trim().length > 1 && !/^(1[012]|0?[1-9])$/.test(value)) { - console.log('there'); setIsCardDateMonthInvalid(true); } else setIsCardDateMonthInvalid(false); break; From c8755e7b87d6d0dae01aa834acf579e32e3ad454 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Wed, 18 Jan 2023 17:32:01 +0300 Subject: [PATCH 61/65] fix: revert old logic with two states of cart to prevent plural fetching from API, while changing count of products in cart (#27) --- src/App/App.tsx | 17 ++++++++++++----- src/App/RootRouter/index.tsx | 12 ++++++++---- .../Cart/ApprovePurchase/ApprovePurchase.tsx | 4 +++- src/Pages/Cart/cart.tsx | 8 +++++++- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/App/App.tsx b/src/App/App.tsx index 6edc6db..d83e3d3 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -8,24 +8,27 @@ import handleLocalStorage from '../Components/utils/handleLocalStorage'; import setDataToLocalStorage from '../Components/utils/setDataToLocalStorage'; function App() { + const [ + productsInCart, setProductsInCart, + ] = useState(handleLocalStorage()); const [ productsInCartCount, setProductsInCartCount, ] = useState(handleLocalStorage()); const [products, setProducts] = useState(null); const [formVisible, setFormVisible] = useState(false); const [fetchProductsById, isPending] = useFetching(async () => { - const response = await PostService.getCartItems(productsInCartCount) + const response = await PostService.getCartItems(productsInCart) .then((items) => items.map((item) => item)); setProducts(response); }); useEffect(() => { fetchProductsById(); - }, [productsInCartCount]); + }, [productsInCart]); useEffect(() => { setDataToLocalStorage(productsInCartCount); - }, [productsInCartCount]); + }, [productsInCart]); const increaseProductCount = (event: React.MouseEvent) => { const cur = Number(event.currentTarget.value); @@ -52,7 +55,7 @@ function App() { const cur = Number(event.currentTarget.value); const result = productsInCartCount.reduce((acc, product) => { if (product.id === cur && product.count === 1) { - setProductsInCartCount(productsInCartCount.filter((el) => el.id !== cur)); + setProductsInCart(productsInCart.filter((el) => el.id !== cur)); return acc; } if (product.id === cur) { @@ -66,18 +69,20 @@ function App() { setDataToLocalStorage(result); }; - const isProductInCart = (id?: number): boolean => productsInCartCount.some( + const isProductInCart = (id?: number): boolean => productsInCart.some( (item) => item.id === id, ); const addToCart = (id: number) => { if (!isProductInCart(id)) { + setProductsInCart([...productsInCart, { id, count: 1 }]); setProductsInCartCount([...productsInCartCount, { id, count: 1 }]); } }; const dropFromCart = (id: number) => { if (isProductInCart(id)) { + setProductsInCart(productsInCart.filter((item) => item.id !== id)); setProductsInCartCount(productsInCartCount.filter((item) => item.id !== id)); } }; @@ -86,6 +91,8 @@ function App() { @@ -58,7 +60,7 @@ export default function RootRouter(props: TRootRouterProps) { path="/product/:id" element={( { setTimeout(() => { setFormVisible(false); + setProductsInCart([]); setProductsInCartCount([]); history('/', { replace: true }); }, 5000); diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 62473f4..885aa42 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -20,6 +20,9 @@ import emptyCartImg from '../../assets/images/emptyCart.svg'; type TCartProps = { isPending: boolean; + productsInCart: TProductPartialProps[] + // eslint-disable-next-line no-unused-vars + setProductsInCart(arr: TProductPartialProps[]): void; productsInCartCount: TProductPartialProps[]; setProductsInCartCount(arr: TProductPartialProps[]): void; products: TProductsItem[] | null; @@ -32,6 +35,8 @@ type TCartProps = { function Cart(props: TCartProps) { const { isPending, + productsInCart, + setProductsInCart, productsInCartCount, setProductsInCartCount, products, @@ -100,7 +105,7 @@ function Cart(props: TCartProps) { useEffect(() => { setTotalCount(countTotalCount(productsInCartCount)); - }, [productsInCartCount]); + }, [productsInCartCount, productsInCart]); useEffect(() => { if (products) { @@ -136,6 +141,7 @@ function Cart(props: TCartProps) { if (showAffirmative) { return ( Date: Wed, 18 Jan 2023 18:07:52 +0300 Subject: [PATCH 62/65] Fix lint errors (#28) * fix: revert old logic with two states of cart to prevent plural fetching from API, while changing count of products in cart * fix: lint errors at carousel imgs, lint errors in wrappers of modal window, delete unused components --- .../Cart/ApprovePurchase/ApprovePurchase.tsx | 3 --- .../Cart/CartProduct/CartProduct.tsx | 17 ++++++++---- .../Cart/Pagination/CartPagination.tsx | 1 - src/Components/Cart/Promo/Promo.tsx | 2 -- src/Components/Cart/PurchaseModal/Modal.tsx | 4 +-- .../CarouselImages/CarouselImages.tsx | 4 +-- src/Components/ProductPage/ProductPage.tsx | 6 ----- .../TestComponentWithHooks/index.tsx | 26 ------------------- src/Components/TestForMain/index.tsx | 16 ------------ src/Components/TestForMain/styles.scss | 0 src/Components/TestForOther/index.tsx | 10 ------- src/Pages/Other/index.tsx | 13 ---------- src/Pages/Other/test/other.test.tsx | 8 ------ 13 files changed, 15 insertions(+), 95 deletions(-) delete mode 100644 src/Components/TestComponentWithHooks/index.tsx delete mode 100644 src/Components/TestForMain/index.tsx delete mode 100644 src/Components/TestForMain/styles.scss delete mode 100644 src/Components/TestForOther/index.tsx delete mode 100644 src/Pages/Other/index.tsx delete mode 100644 src/Pages/Other/test/other.test.tsx diff --git a/src/Components/Cart/ApprovePurchase/ApprovePurchase.tsx b/src/Components/Cart/ApprovePurchase/ApprovePurchase.tsx index 3100acf..52eee2c 100644 --- a/src/Components/Cart/ApprovePurchase/ApprovePurchase.tsx +++ b/src/Components/Cart/ApprovePurchase/ApprovePurchase.tsx @@ -7,11 +7,8 @@ import styles from './approvePurchase.module.scss'; interface IApprovePurchase { showAffirmative: boolean - // eslint-disable-next-line no-unused-vars setFormVisible(bool:boolean): void; - // eslint-disable-next-line no-unused-vars setProductsInCart(arr: TProductPartialProps[]): void; - // eslint-disable-next-line no-unused-vars setProductsInCartCount(arr: TProductPartialProps[]): void; } diff --git a/src/Components/Cart/CartProduct/CartProduct.tsx b/src/Components/Cart/CartProduct/CartProduct.tsx index 8391c96..6974d84 100644 --- a/src/Components/Cart/CartProduct/CartProduct.tsx +++ b/src/Components/Cart/CartProduct/CartProduct.tsx @@ -1,5 +1,3 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable max-len */ import React from 'react'; import { Link } from 'react-router-dom'; import { TProductsCart } from '../../../types/types'; @@ -9,7 +7,6 @@ import formatPrice from '../../utils/formatPrice'; import styles from './CartProduct.module.scss'; function CartProduct(props:TProductsCart) { - // eslint-disable-next-line max-len const { productIndex, id, @@ -86,9 +83,19 @@ function CartProduct(props:TProductsCart) { {'Available stock: '} {stock}
-
+
+ +
+
+
{data.count}
-
{data.count === 1 ? 'Delete from cart' : '-'}
+ +
{data.count === 1 ? 'Delete from cart' : '-'}
+
{formatPrice(price * data.count)}
diff --git a/src/Components/Cart/Pagination/CartPagination.tsx b/src/Components/Cart/Pagination/CartPagination.tsx index 1847849..7561c12 100644 --- a/src/Components/Cart/Pagination/CartPagination.tsx +++ b/src/Components/Cart/Pagination/CartPagination.tsx @@ -2,7 +2,6 @@ import React from 'react'; import styles from './cartPagination.module.scss'; interface ICartPagination { - // eslint-disable-next-line no-unused-vars handleProductsPerPage: (event: React.ChangeEvent) => void productsPerPage: number maxPages: number diff --git a/src/Components/Cart/Promo/Promo.tsx b/src/Components/Cart/Promo/Promo.tsx index 871a1cf..13030b8 100644 --- a/src/Components/Cart/Promo/Promo.tsx +++ b/src/Components/Cart/Promo/Promo.tsx @@ -8,9 +8,7 @@ import styles from './promo.module.scss'; interface IPromoProps { isCodeTrue: boolean currenCodes: number[] - // eslint-disable-next-line no-unused-vars setIsCodeTrue: (boolean:boolean) => void - // eslint-disable-next-line no-unused-vars setIsCodeAdd: (event: React.MouseEvent, isAdd: boolean) => void } diff --git a/src/Components/Cart/PurchaseModal/Modal.tsx b/src/Components/Cart/PurchaseModal/Modal.tsx index bb4cdb2..581696a 100644 --- a/src/Components/Cart/PurchaseModal/Modal.tsx +++ b/src/Components/Cart/PurchaseModal/Modal.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-static-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import React from 'react'; import styles from './modal.module.scss'; @@ -16,6 +14,7 @@ function Modal({ children, visible, setVisible }: IModal) { } return (
setVisible(false)} onKeyUp={(e) => { @@ -25,6 +24,7 @@ function Modal({ children, visible, setVisible }: IModal) { }} >
e.stopPropagation()} > diff --git a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx index a4064c3..c99f529 100644 --- a/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx +++ b/src/Components/ProductPage/ProductImagesCarousel/CarouselImages/CarouselImages.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ import React from 'react'; import styles from './CarouselImages.module.scss'; @@ -10,7 +8,7 @@ interface ICarouselImages { function CarouselImages({ value, setCurrentImg }: ICarouselImages) { return ( - setCurrentImg(value)} alt="product" /> + setCurrentImg(value)} role="presentation" alt="product" /> ); } diff --git a/src/Components/ProductPage/ProductPage.tsx b/src/Components/ProductPage/ProductPage.tsx index ac7a7e6..13f4229 100644 --- a/src/Components/ProductPage/ProductPage.tsx +++ b/src/Components/ProductPage/ProductPage.tsx @@ -5,7 +5,6 @@ import { TProductPartialProps, TProductsItemWithImages } from '../../types/types import PostService from '../API/PostService'; import ProductAddDropButton from '../UI/button/ProductAddDropButton'; import CartContainer from '../UI/container/CartContainer/CartContainer'; -// import SiteContainer from '../UI/container/SiteContainer'; import LoadingSpinner from '../UI/LoadingSpinner'; import checkUniqueImgs from '../utils/checkUniqueImgs'; import setDataToLocalStorage from '../utils/setDataToLocalStorage'; @@ -27,7 +26,6 @@ function ProductPage({ const navigate = useNavigate(); const id = Number(params.id); - // const [goToCart, setGoToCart] = useState(false); const [currentPage, setCurrentPage] = useState(); const [fetchProductById, isPending] = useFetching(async () => { @@ -68,10 +66,6 @@ function ProductPage({ [currentPage], ); - // useEffect(() => { - // i; - // }, [currentPage]); - useEffect(() => { setDataToLocalStorage(productsInCart); }, [productsInCart]); diff --git a/src/Components/TestComponentWithHooks/index.tsx b/src/Components/TestComponentWithHooks/index.tsx deleted file mode 100644 index a723b0b..0000000 --- a/src/Components/TestComponentWithHooks/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { useEffect, useState } from 'react'; - -function TestComponentWithHooks() { - // пример использования хука useState - const [counter, setCounter] = useState(0); - // пример использования хука useEffect, который запуститься только 1 раз при рендере страницы - // массив зависимостей в таком случае должен быть пустым - useEffect(() => { - console.log('вызывается один раз при рендере'); - }, []); - // этот useEffect запустится при рендере - // + при каждом изменении значения переменной указанной в массиве зависимостей - useEffect(() => { - console.log(`Текущий counter: ${counter}`); - }, [counter]); - - return ( -
-

{`Current counter: ${counter}`}

- - -
- ); -} - -export default TestComponentWithHooks; diff --git a/src/Components/TestForMain/index.tsx b/src/Components/TestForMain/index.tsx deleted file mode 100644 index 3986d0e..0000000 --- a/src/Components/TestForMain/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import './styles.scss'; - -interface Props { - number: number -} -// компонент объявлен в виде function expression, особой разницы нет, можно и declaration -// также посмотрите на типизацию пропсов, можно типизировать через FC, почитайте в доке -function TestForMain({ number }: Props) { - return ( -
-

{`Main page component №${number}`}

-
- ); -} - -export default TestForMain; diff --git a/src/Components/TestForMain/styles.scss b/src/Components/TestForMain/styles.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/Components/TestForOther/index.tsx b/src/Components/TestForOther/index.tsx deleted file mode 100644 index 98f7b1a..0000000 --- a/src/Components/TestForOther/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -// компонент создан через function expression, как создавать особого значения не имеет -function TestForOther() { - return ( -
-

Other page component

-
- ); -} - -export default TestForOther; diff --git a/src/Pages/Other/index.tsx b/src/Pages/Other/index.tsx deleted file mode 100644 index 68b6391..0000000 --- a/src/Pages/Other/index.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import TestComponentWithHooks from '../../Components/TestComponentWithHooks'; -import TestForOther from '../../Components/TestForOther'; - -function Other() { - return ( - <> - - - - ); -} - -export default Other; diff --git a/src/Pages/Other/test/other.test.tsx b/src/Pages/Other/test/other.test.tsx deleted file mode 100644 index 7888bc8..0000000 --- a/src/Pages/Other/test/other.test.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import Other from '../index'; -// Тест. Проверяем зарендерилась страница с теми блоками которые мы ожидаем на ней увидеть -test('renders other page', () => { - render(); - const textElement = screen.getByText(/Other page component/i); - expect(textElement).toBeInTheDocument(); -}); From 566ff8b0fc386460ee7b3075e7d2383b0165d2d7 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Tue, 31 Jan 2023 00:58:32 +0300 Subject: [PATCH 63/65] fix: response types at API services (#29) --- .eslintrc.json | 18 ++++++++++++++---- src/Components/API/PostService.ts | 12 ++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index a30a73d..99b06c6 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,7 +4,12 @@ "es2021": true, "jest": true }, - "extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "airbnb"], + "extends": [ + "eslint:recommended", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "airbnb" + ], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaFeatures": { @@ -15,17 +20,22 @@ }, "plugins": ["react", "@typescript-eslint"], "rules": { - "import/extensions": [1, "ignorePackages", { + "import/extensions": [ + 1, + "ignorePackages", + { "ts": "never", "tsx": "never" - }], + } + ], "react/react-in-jsx-scope": "off", "react/jsx-filename-extension": [ 1, { "extensions": [".js", ".jsx", "ts", "tsx"] } ], "no-unused-vars": "off", - "@typescript-eslint/no-unused-vars": "error" + "@typescript-eslint/no-unused-vars": "error", + "@typescript-eslint/no-explicit-any": "error" }, "settings": { "import/resolver": { diff --git a/src/Components/API/PostService.ts b/src/Components/API/PostService.ts index f0d55b5..0420026 100644 --- a/src/Components/API/PostService.ts +++ b/src/Components/API/PostService.ts @@ -1,15 +1,15 @@ -import { TProductPartialProps } from '../../types/types'; +import { TProductPartialProps, TProductsItem, TProductsItemWithImages } from '../../types/types'; export default class PostService { - static async getById(id:number) { + static async getById(id: number) { const URL = `https://dummyjson.com/products/${id}`; - const result = await fetch(URL).then((response) => response.json()); + const result: TProductsItemWithImages = await fetch(URL).then((response) => response.json()); return result; } - static async getCartItems(arr:TProductPartialProps[]) { + static async getCartItems(arr: TProductPartialProps[]) { const itemRequests = arr.map((item) => PostService.getById(item.id)); - const promises = await Promise.all(itemRequests); + const promises: TProductsItem[] = await Promise.all(itemRequests); return promises; } @@ -21,7 +21,7 @@ export default class PostService { static async getAllSizes(arr: string[]) { const imgSizes = arr.map((img) => PostService.getImgByURL(img)); - const promises = await Promise.all(imgSizes); + const promises: number[] = await Promise.all(imgSizes); return promises; } } From 2fefa8b8da8064fd1efa5a19c342728c522739dd Mon Sep 17 00:00:00 2001 From: Dinara Date: Tue, 31 Jan 2023 12:57:59 +0400 Subject: [PATCH 64/65] fix: fix mistakes --- .../Cart/CartProduct/CartProduct.module.scss | 2 -- .../Pagination/cartPagination.module.scss | 9 ------ .../Cart/Promo/handleCodes/code.module.scss | 1 - .../Purchase/purchase.module.scss | 1 - src/Components/Main/DualSlider.module.scss | 2 -- src/Components/Main/DualSlider.tsx | 3 -- src/Components/Main/FiltersList.module.scss | 1 - src/Components/Main/FiltersList.tsx | 7 ++--- src/Components/Main/ProductsList.module.scss | 29 ------------------- .../ProductPage/productPage.module.scss | 9 ------ src/Components/header/index.tsx | 17 ++++++----- src/Components/header/styles.module.scss | 4 --- src/Components/utils/sortProducts.ts | 19 ------------ src/Pages/Cart/cart.module.scss | 3 -- src/Pages/Cart/cart.tsx | 1 - src/Pages/Main/index.tsx | 25 ---------------- src/index.scss | 4 --- src/types/types.ts | 7 ----- 18 files changed, 11 insertions(+), 133 deletions(-) diff --git a/src/Components/Cart/CartProduct/CartProduct.module.scss b/src/Components/Cart/CartProduct/CartProduct.module.scss index 63bb050..46bc182 100644 --- a/src/Components/Cart/CartProduct/CartProduct.module.scss +++ b/src/Components/Cart/CartProduct/CartProduct.module.scss @@ -96,7 +96,6 @@ width: 100%; justify-content: space-between; & div { - // color: var(--accent-color); margin: 10px; } @@ -109,7 +108,6 @@ margin-top: 10px; font-weight: bold; font-size: 1.2rem; - // color: var(--accent-color); } .productIndex { diff --git a/src/Components/Cart/Pagination/cartPagination.module.scss b/src/Components/Cart/Pagination/cartPagination.module.scss index 628afe3..6e43890 100644 --- a/src/Components/Cart/Pagination/cartPagination.module.scss +++ b/src/Components/Cart/Pagination/cartPagination.module.scss @@ -6,20 +6,15 @@ margin: 20px 0; } .text { - // font-size: 20px; - // font-weight: bold; - // color: teal; margin-right: 15px; } .input { - // color: var(--accent-color); width: 55px; text-align: center; outline: none; border: 1px solid var(--unimportant-color); border-radius: 0.2rem; - // font-size: 140%; margin-right: 20px; padding: 5px 10px; } @@ -27,7 +22,6 @@ margin: 20px 0; .paginateButton { padding: 5px 10px; color: var(--accent-color); - // font-size: 1.5rem; background: transparent; border: 1px solid var(--accent-color); border-radius: 5px; @@ -36,8 +30,5 @@ margin: 20px 0; } .paginateText { - // font-size: 20px; - // font-weight: bold; margin-right: 5px; - // color: teal; } \ No newline at end of file diff --git a/src/Components/Cart/Promo/handleCodes/code.module.scss b/src/Components/Cart/Promo/handleCodes/code.module.scss index 78f292d..a39ebc6 100644 --- a/src/Components/Cart/Promo/handleCodes/code.module.scss +++ b/src/Components/Cart/Promo/handleCodes/code.module.scss @@ -15,7 +15,6 @@ &:hover { transition: all 0.3s; - // color: teal; background-color: var(--accent-hover-color); } } diff --git a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss index be4a1be..95a8530 100644 --- a/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss +++ b/src/Components/Cart/PurchaseModal/Purchase/purchase.module.scss @@ -138,7 +138,6 @@ border-radius: 10px; &:hover { transition: 0.3s all; - // color: teal; background-color: var(--accent-hover-color); } } diff --git a/src/Components/Main/DualSlider.module.scss b/src/Components/Main/DualSlider.module.scss index d672f28..ec48001 100644 --- a/src/Components/Main/DualSlider.module.scss +++ b/src/Components/Main/DualSlider.module.scss @@ -46,7 +46,6 @@ border-radius: 50%; background-color: var(--accent-color); cursor: pointer; - // transition: all 0.4s; &:hover { background-color: var(--accent-hover-color); @@ -62,7 +61,6 @@ border-radius: 50%; background-color: var(--accent-color); cursor: pointer; - // transition: all 0.4s; &:hover { background-color: var(--accent-hover-color); diff --git a/src/Components/Main/DualSlider.tsx b/src/Components/Main/DualSlider.tsx index 8b9f82f..0c48d04 100644 --- a/src/Components/Main/DualSlider.tsx +++ b/src/Components/Main/DualSlider.tsx @@ -10,7 +10,6 @@ type TDualSliderProps = { handleSliderFilter(event: React.ChangeEvent): void; filteredSearchedProducts: TProductsItem[] | []; searchParamsObject: TSearchParamsObject; - // fillSlider(filter: 'price' | 'stock'): string; } function DualSlider(props: TDualSliderProps) { @@ -21,7 +20,6 @@ function DualSlider(props: TDualSliderProps) { handleSliderFilter, filteredSearchedProducts, searchParamsObject, - // fillSlider, } = props; const filterValuesTotal = (products.length > 0) @@ -59,7 +57,6 @@ function DualSlider(props: TDualSliderProps) { value={maxFilterValue} onInput={handleSliderFilter} className={[styles.slider, styles.sliderMax].join(' ')} - // style={{ background: `${fillSlider(filter)}` }} />

diff --git a/src/Components/Main/FiltersList.module.scss b/src/Components/Main/FiltersList.module.scss index 6fae4bb..bc06a13 100644 --- a/src/Components/Main/FiltersList.module.scss +++ b/src/Components/Main/FiltersList.module.scss @@ -52,7 +52,6 @@ ul.filter__section { display: flex; align-items: center; gap: 10px; - // margin-bottom: 5px; margin-top: -10px; cursor: pointer; diff --git a/src/Components/Main/FiltersList.tsx b/src/Components/Main/FiltersList.tsx index 2decaa1..4bfb9bb 100644 --- a/src/Components/Main/FiltersList.tsx +++ b/src/Components/Main/FiltersList.tsx @@ -8,6 +8,8 @@ import { TProductsItem, TSearchParamsObject, TSetSearchParamsObject, TFilterSelectionTypes, } from '../../types/types'; +type TItemsCount = (items: TProductsItem[], key: TFilterSelectionTypes, value: string) => number; + type TFiltersListProps = { products: TProductsItem[]; filteredSearchedProducts: TProductsItem[] | []; @@ -17,7 +19,6 @@ type TFiltersListProps = { handleCopyClick(): void; handleSliderFilter(event: React.ChangeEvent): void; copied: boolean; - // fillSlider(filter: 'price' | 'stock'): string; } function FiltersList(props: TFiltersListProps) { @@ -30,13 +31,11 @@ function FiltersList(props: TFiltersListProps) { handleCopyClick, handleSliderFilter, copied, - // fillSlider, } = props; const categoriesList = getFilterOptions(products, 'category'); const brandsList = getFilterOptions(products, 'brand'); - type TItemsCount = (items: TProductsItem[], key: TFilterSelectionTypes, value: string) => number; const itemsCount: TItemsCount = (items, key, value) => items.filter((product) => product[key] === value).length; @@ -107,7 +106,6 @@ function FiltersList(props: TFiltersListProps) { handleSliderFilter={handleSliderFilter} searchParamsObject={searchParamsObject} filteredSearchedProducts={filteredSearchedProducts} - // fillSlider={fillSlider} />

Stock

@@ -119,7 +117,6 @@ function FiltersList(props: TFiltersListProps) { handleSliderFilter={handleSliderFilter} searchParamsObject={searchParamsObject} filteredSearchedProducts={filteredSearchedProducts} - // fillSlider={fillSlider} />
diff --git a/src/Components/Main/ProductsList.module.scss b/src/Components/Main/ProductsList.module.scss index 6248ff2..6bc8436 100644 --- a/src/Components/Main/ProductsList.module.scss +++ b/src/Components/Main/ProductsList.module.scss @@ -1,28 +1,20 @@ .products { padding: 50px 0 0; box-sizing: content-box; - // display: grid; display: flex; flex-direction: column; gap: 30px; } .products_grid { - // grid-template-columns: 1fr 1fr 1fr; flex-direction: row; flex-wrap: wrap; - // justify-content: space-evenly; padding-left: 40px; - - @media (max-width: 999px) { - // grid-template-columns: 1fr 1fr; - } } .product { box-sizing: content-box; width: 200px; - // border: 1px solid var(--unimportant-color); box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); border-radius: 10px; padding: 20px; @@ -39,16 +31,12 @@ .product__title { font-size: 1rem; - // margin-left: 5px; - // margin-right: 5px; } .product__parameter { display: flex; justify-content: space-between; - // gap: 5px; font-size: 0.9rem; - // margin: 0 5px; } .product__parameter__title { @@ -58,7 +46,6 @@ .product__parameter_price { display: flex; justify-content: space-between; - // margin: 0 5px; margin-top: 5px; margin-bottom: 15px; font-size: 1.2rem; @@ -103,23 +90,14 @@ } } -.products.products_list { - - // @media (max-width: 1199px) { - // padding-left: 0; - // } -} - .products_list .product { width: 85%; margin: 0 auto; - // display: flex; flex-direction: row; gap: 20px; } .products_list .product__image { - // width: 250px; height: 175px; } @@ -147,13 +125,6 @@ font-size: 1.5rem; } -// .products_list .product__parameter_price { - -// @media (max-width: 1199px) { -// font-size: 1.2rem; -// } -// } - .products_list .product__buttonsContainer { flex-direction: column-reverse; gap: 15px; diff --git a/src/Components/ProductPage/productPage.module.scss b/src/Components/ProductPage/productPage.module.scss index aa5985c..bc0b92f 100644 --- a/src/Components/ProductPage/productPage.module.scss +++ b/src/Components/ProductPage/productPage.module.scss @@ -10,15 +10,12 @@ .breedsWrapper { color: var(--unimportant-color); text-align: center; - // margin: 0 auto 30px auto; margin-bottom: 30px; align-self: flex-start; display: flex; - // max-width: 800px; justify-content: center; gap: 10px; align-items: center; - // font-size: 20px; & a { text-decoration: none; color: var(--accent-color); @@ -36,7 +33,6 @@ .breedsItems { color: var(--unimportant-color); font-size: 1.2rem; - // margin: 0 30px; } .productWrapper { @@ -89,21 +85,16 @@ .infoHeaders { color: var(--accent-color); - // font-weight: bold; } .infoDescription { margin-top: 10px; line-height: 150%; - // text-align: center; - // font-weight: bold; } .buttonsWrapper { padding: 30px 25px; min-width: 290px; - // min-height: 165px; - // max-height: 165px; align-self: flex-start; box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); border-radius: 10px; diff --git a/src/Components/header/index.tsx b/src/Components/header/index.tsx index 008e6c9..a339e5a 100644 --- a/src/Components/header/index.tsx +++ b/src/Components/header/index.tsx @@ -1,4 +1,3 @@ -// import React, { useMemo } from 'react'; import { Link } from 'react-router-dom'; import styles from './styles.module.scss'; import { TProductsItem, TProductPartialProps } from '../../types/types'; @@ -16,13 +15,15 @@ export default function Header(props: TProps) { products, } = props; - const cartTotalItems = products?.reduce((acc, elem) => { - const productInCart = productsInCart.find((item) => item.id === elem.id); - if (productInCart === undefined) { - return 0; - } - return acc + elem.price * productInCart.count; - }, 0); + const cartTotalItems = products + ? products.reduce((acc, elem) => { + const productInCart = productsInCart.find((item) => item.id === elem.id); + if (productInCart === undefined) { + return 0; + } + return acc + elem.price * productInCart.count; + }, 0) + : 0; const cartTotalPrice = productsInCart.reduce((acc, elem) => acc + elem.count, 0); diff --git a/src/Components/header/styles.module.scss b/src/Components/header/styles.module.scss index 7ca4996..3555d3f 100644 --- a/src/Components/header/styles.module.scss +++ b/src/Components/header/styles.module.scss @@ -1,5 +1,4 @@ .header { - // min-height: 100px; padding: 30px 0; display: flex; justify-content: center; @@ -43,13 +42,11 @@ .header__navigation__link { display: block; margin-left: 50px; - // color: white; text-decoration: none; &__active { display: block; text-decoration: underline; margin-left: 50px; - // color: black; } } @@ -59,7 +56,6 @@ .header__navigation__total__price { color: var(--accent-color); - // font-weight: bold; font-size: 1.2rem; } diff --git a/src/Components/utils/sortProducts.ts b/src/Components/utils/sortProducts.ts index 2cf55e2..e0c6c2d 100644 --- a/src/Components/utils/sortProducts.ts +++ b/src/Components/utils/sortProducts.ts @@ -23,25 +23,6 @@ const sortProducts: TsortProducts = (productsArray, searchParamsObject) => { default: return productsArray; } - // if (sortby === 'price-ascending') { - // return productsArray.sort((a, b) => a.price - b.price); - // } - // if (sortby === 'price-descending') { - // return productsArray.sort((a, b) => b.price - a.price); - // } - // if (sortby === 'rating-ascending') { - // return productsArray.sort((a, b) => a.rating - b.rating); - // } - // if (sortby === 'rating-descending') { - // return productsArray.sort((a, b) => b.rating - a.rating); - // } - // if (sortby === 'discount-ascending') { - // return productsArray.sort((a, b) => a.discountPercentage - b.discountPercentage); - // } - // if (sortby === 'discount-descending') { - // return productsArray.sort((a, b) => b.discountPercentage - a.discountPercentage); - // } - // return productsArray; }; export default sortProducts; diff --git a/src/Pages/Cart/cart.module.scss b/src/Pages/Cart/cart.module.scss index 974d04c..df0a1e6 100644 --- a/src/Pages/Cart/cart.module.scss +++ b/src/Pages/Cart/cart.module.scss @@ -1,5 +1,4 @@ .wrapper { - // width: 95%; margin: 20px auto; display: flex; justify-content: space-between; @@ -15,7 +14,6 @@ display: flex; flex-direction: column; align-items: center; - // border: 1px solid var(--accent-color); box-shadow: -4px 0px 4px rgba(0, 0, 0, 0.1), 4px 2px 4px rgba(0, 0, 0, 0.1); border-radius: 10px; height: 100%; @@ -52,7 +50,6 @@ margin-bottom: 10px; font-size: 1.5rem; font-weight: bold; - // color: teal } .byuButton { diff --git a/src/Pages/Cart/cart.tsx b/src/Pages/Cart/cart.tsx index 885aa42..3e23be5 100644 --- a/src/Pages/Cart/cart.tsx +++ b/src/Pages/Cart/cart.tsx @@ -21,7 +21,6 @@ import emptyCartImg from '../../assets/images/emptyCart.svg'; type TCartProps = { isPending: boolean; productsInCart: TProductPartialProps[] - // eslint-disable-next-line no-unused-vars setProductsInCart(arr: TProductPartialProps[]): void; productsInCartCount: TProductPartialProps[]; setProductsInCartCount(arr: TProductPartialProps[]): void; diff --git a/src/Pages/Main/index.tsx b/src/Pages/Main/index.tsx index bc0a091..681c576 100644 --- a/src/Pages/Main/index.tsx +++ b/src/Pages/Main/index.tsx @@ -1,7 +1,6 @@ import React, { ChangeEvent, useEffect, useState } from 'react'; import FiltersList from '../../Components/Main/FiltersList'; import ProductsList from '../../Components/Main/ProductsList'; -// import TestForMain from '../../Components/TestForMain'; import useSearchParamsObject from '../../hooks/useSearchParamsObject'; import LoadingSpinner from '../../Components/UI/LoadingSpinner'; import SiteContainer from '../../Components/UI/container/SiteContainer'; @@ -48,26 +47,6 @@ function Main(props: TMainProps) { const [searchParamsObject, setSearchParamsObject] = useSearchParamsObject(); - // const fillSlider = (filter: 'price' | 'stock') => { - // const sliderColor = '#b9b9b9'; - // const rangeColor = '#2CB708'; - // const max = Math.max(...products.map((item) => item[filter])); - // const min = Math.min(...products.map((item) => item[filter])); - // const valueMin = Number(searchParamsObject[`${[filter]}range`]?.split(',')[0]); - // const valueMax = Number(searchParamsObject[`${[filter]}range`]?.split(',')[1]); - // const rangeDistance = max - min; - // const fromPosition = valueMin - min; - // const toPosition = valueMax - min; - // return `linear-gradient( - // to right, - // ${sliderColor} 0%, - // ${sliderColor} ${((fromPosition) / (rangeDistance)) * 100}%, - // ${rangeColor} ${((fromPosition) / (rangeDistance)) * 100}%, - // ${rangeColor} ${((toPosition) / (rangeDistance)) * 100}%, - // ${sliderColor} ${((toPosition) / (rangeDistance)) * 100}%, - // ${sliderColor} 100%)`; - // }; - const getMinPrice = (source: TProductsItem[], paramName: TFilterRangeTypes) => { if (source.length !== 0) { return Math.min(...source.map((item) => item[paramName])); @@ -98,7 +77,6 @@ function Main(props: TMainProps) { return; } setSearchParamsObject({ ...searchParamsObject, [`${filterName}range`]: [minValue, maxValue].sort((a, b) => a - b).join(',') }); - // fillSlider('price'); }; const handleSearchChange = (event: React.ChangeEvent) => { @@ -127,8 +105,6 @@ function Main(props: TMainProps) { const handleResetClick = () => { setSearchParamsObject({}); - // fillSlider('price'); - // fillSlider('stock'); }; const [copied, setCopied] = useState(false); @@ -164,7 +140,6 @@ function Main(props: TMainProps) { handleCopyClick={handleCopyClick} handleSliderFilter={handleSliderFilter} copied={copied} - // fillSlider={fillSlider} />
diff --git a/src/index.scss b/src/index.scss index 3482787..c6e9557 100644 --- a/src/index.scss +++ b/src/index.scss @@ -18,9 +18,6 @@ body { margin: 0; - // font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - // 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - // sans-serif; font-family: 'Roboto', 'Arial', 'Helvetica', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -105,7 +102,6 @@ code { } h2 { - // color: teal; font-size: 2rem; margin: 20px 0; } diff --git a/src/types/types.ts b/src/types/types.ts index 582d05e..c0db385 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -59,13 +59,6 @@ export type TSearchParamsObject = Record; export type TSetSearchParamsObject = (searchParamsObject: TSearchParamsObject) => void; -// export enum filterTypes { -// category = 'category', -// brand = 'brand', -// price = 'price', -// stock = 'stock', -// } - export type TFilterSelectionTypes = 'category' | 'brand'; export type TFilterRangeTypes = 'price' | 'stock'; From a4995021456e5486165ceee4a9fc05f9b47a5233 Mon Sep 17 00:00:00 2001 From: Buffik <62429354+Buffik@users.noreply.github.com> Date: Tue, 31 Jan 2023 20:49:04 +0300 Subject: [PATCH 65/65] Fix utils types (#31) * fix: response types at API services * feat: fix types at util function handle localstorage --- src/Components/utils/handleLocalStorage.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Components/utils/handleLocalStorage.ts b/src/Components/utils/handleLocalStorage.ts index 4ef7953..448451a 100644 --- a/src/Components/utils/handleLocalStorage.ts +++ b/src/Components/utils/handleLocalStorage.ts @@ -1,4 +1,6 @@ -function handleLocalStorage() { +import { TProductPartialProps } from '../../types/types'; + +function handleLocalStorage(): TProductPartialProps[] | [] { const currentProducts = window.localStorage.getItem('productsByTeamDiBu'); if (currentProducts) return JSON.parse(currentProducts); return [];