diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..6d999ff --- /dev/null +++ b/.env.development @@ -0,0 +1,2 @@ +API_URL=http://localhost:8090/api +NEXTAUTH_SECRET=secret \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..2036fea --- /dev/null +++ b/.env.production @@ -0,0 +1,3 @@ +API_URL=http://localhost:8090/api +NEXTAUTH_SECRET=secret +NEXTAUTH_URL=https://tsms-uat.2fi-solutions.com \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..7159cbb --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,16 @@ +{ + "extends": ["next/core-web-vitals", "plugin:@typescript-eslint/recommended", "prettier"], + "plugins": ["prettier", "@typescript-eslint"], + "rules": { + // "prettier/prettier": "warn", + "prettier/prettier": [ + "error", + { + "endOfLine": "off" + } + ], + "no-unused-vars": "off", + // "@typescript-eslint/no-explicit-any": ["off"], + "@typescript-eslint/no-unused-vars": "warn" + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8b6a27a --- /dev/null +++ b/.gitignore @@ -0,0 +1,49 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts + +.vscode + +#tsms.zip +tsms.zip + +# PWA files +**/public/sw.js +**/public/workbox-*.js +**/public/worker-*.js +**/public/sw.js.map +**/public/workbox-*.js.map +**/public/worker-*.js.map \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5660f81 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..a77793e --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/hydrogen diff --git a/README.md b/README.md index 4b847d2..d8bffd4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,32 @@ -# FPSMS-frontend +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). -FPSMS-frontend \ No newline at end of file +## Setting Up the Environment + +It is recommended to use the same node and npm versions for development. An easy way to do so would be to use `nvm` ([Linux/MacOS](https://github.com/nvm-sh/nvm), [Windows](https://github.com/coreybutler/nvm-windows)). + +After installing `nvm`, run: + +```bash +nvm use +npm install +``` + +This will automatically use the node version defined in `.nvmrc` and then proceed with installing the necessary dependencies for development. + +## Getting Started + +First, run the development server: + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +## References + +This project uses the following libraries: +- [NextJS](https://nextjs.org/docs) +- [Next-Auth](https://next-auth.js.org/getting-started/example) +- [Material UI](https://mui.com/material-ui/getting-started/) +- [i18next](https://www.i18next.com/overview/getting-started) \ No newline at end of file diff --git a/next.config.js b/next.config.js new file mode 100644 index 0000000..a27da5d --- /dev/null +++ b/next.config.js @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +/** @type {import('next').NextConfig} */ + +const withPWA = require("next-pwa")({ + dest: "public", + register: true, + skipWaiting: true, +}); + +const nextConfig = { + // eslint: { + // // Warning: This allows production builds to successfully complete even if + // // your project has ESLint errors. + // ignoreDuringBuilds: true, + // }, +}; + +module.exports = withPWA(nextConfig); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..b243cb6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10254 @@ +{ + "name": "tsms", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tsms", + "version": "0.1.0", + "dependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@fontsource/inter": "^5.0.16", + "@fontsource/plus-jakarta-sans": "^5.0.18", + "@mui/icons-material": "^5.15.0", + "@mui/material": "^5.15.0", + "@mui/material-nextjs": "^5.15.0", + "@mui/x-data-grid": "^6.18.7", + "@mui/x-date-pickers": "^6.18.7", + "@unly/universal-language-detector": "^2.0.3", + "apexcharts": "^3.45.2", + "dayjs": "^1.11.10", + "i18next": "^23.7.11", + "i18next-resources-to-backend": "^1.2.0", + "lodash": "^4.17.21", + "next": "14.0.4", + "next-auth": "^4.24.5", + "next-pwa": "^5.6.0", + "react": "^18", + "react-apexcharts": "^1.4.1", + "react-dom": "^18", + "react-hook-form": "^7.49.2", + "react-i18next": "^13.5.0", + "react-intl": "^6.5.5", + "react-select": "^5.8.0", + "reactstrap": "^9.2.2", + "styled-components": "^6.1.8", + "sweetalert2": "^11.10.3" + }, + "devDependencies": { + "@types/lodash": "^4.14.202", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/parser": "^6.18.1", + "autoprefixer": "^10.4.16", + "eslint": "^8", + "eslint-config-next": "14.0.4", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.0.1", + "postcss": "^8.4.33", + "prettier": "3.1.1", + "tailwindcss": "^3.4.1", + "typescript": "^5" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/@babel/core/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", + "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", + "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.0.tgz", + "integrity": "sha512-QAH+vfvts51BCsNZ2PhY6HAggnlS6omLLFTsIpeqZk/MmJ6cW7tgz5yRv0fMJThcr6FmbMrENh1RgrWPTYA76g==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-member-expression-to-functions": "^7.23.0", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", + "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", + "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", + "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", + "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", + "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", + "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", + "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", + "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "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.23.3", + "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.23.3.tgz", + "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", + "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", + "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/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-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-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-import-assertions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", + "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", + "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-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-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", + "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", + "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", + "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", + "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", + "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", + "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", + "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", + "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/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/@babel/plugin-transform-computed-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", + "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", + "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", + "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", + "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", + "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", + "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", + "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", + "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", + "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", + "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", + "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", + "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", + "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", + "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", + "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", + "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", + "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", + "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", + "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", + "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", + "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz", + "integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.23.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", + "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", + "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", + "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", + "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", + "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", + "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", + "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", + "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", + "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", + "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", + "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", + "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", + "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", + "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", + "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", + "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", + "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", + "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", + "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-plugin-utils": "^7.24.0", + "@babel/helper-validator-option": "^7.23.5", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.23.3", + "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.23.3", + "@babel/plugin-transform-async-generator-functions": "^7.23.9", + "@babel/plugin-transform-async-to-generator": "^7.23.3", + "@babel/plugin-transform-block-scoped-functions": "^7.23.3", + "@babel/plugin-transform-block-scoping": "^7.23.4", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-class-static-block": "^7.23.4", + "@babel/plugin-transform-classes": "^7.23.8", + "@babel/plugin-transform-computed-properties": "^7.23.3", + "@babel/plugin-transform-destructuring": "^7.23.3", + "@babel/plugin-transform-dotall-regex": "^7.23.3", + "@babel/plugin-transform-duplicate-keys": "^7.23.3", + "@babel/plugin-transform-dynamic-import": "^7.23.4", + "@babel/plugin-transform-exponentiation-operator": "^7.23.3", + "@babel/plugin-transform-export-namespace-from": "^7.23.4", + "@babel/plugin-transform-for-of": "^7.23.6", + "@babel/plugin-transform-function-name": "^7.23.3", + "@babel/plugin-transform-json-strings": "^7.23.4", + "@babel/plugin-transform-literals": "^7.23.3", + "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", + "@babel/plugin-transform-member-expression-literals": "^7.23.3", + "@babel/plugin-transform-modules-amd": "^7.23.3", + "@babel/plugin-transform-modules-commonjs": "^7.23.3", + "@babel/plugin-transform-modules-systemjs": "^7.23.9", + "@babel/plugin-transform-modules-umd": "^7.23.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.23.3", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", + "@babel/plugin-transform-numeric-separator": "^7.23.4", + "@babel/plugin-transform-object-rest-spread": "^7.24.0", + "@babel/plugin-transform-object-super": "^7.23.3", + "@babel/plugin-transform-optional-catch-binding": "^7.23.4", + "@babel/plugin-transform-optional-chaining": "^7.23.4", + "@babel/plugin-transform-parameters": "^7.23.3", + "@babel/plugin-transform-private-methods": "^7.23.3", + "@babel/plugin-transform-private-property-in-object": "^7.23.4", + "@babel/plugin-transform-property-literals": "^7.23.3", + "@babel/plugin-transform-regenerator": "^7.23.3", + "@babel/plugin-transform-reserved-words": "^7.23.3", + "@babel/plugin-transform-shorthand-properties": "^7.23.3", + "@babel/plugin-transform-spread": "^7.23.3", + "@babel/plugin-transform-sticky-regex": "^7.23.3", + "@babel/plugin-transform-template-literals": "^7.23.3", + "@babel/plugin-transform-typeof-symbol": "^7.23.3", + "@babel/plugin-transform-unicode-escapes": "^7.23.3", + "@babel/plugin-transform-unicode-property-regex": "^7.23.3", + "@babel/plugin-transform-unicode-regex": "^7.23.3", + "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.8", + "babel-plugin-polyfill-corejs3": "^0.9.0", + "babel-plugin-polyfill-regenerator": "^0.5.5", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, + "node_modules/@babel/runtime": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, + "node_modules/@fontsource/inter": { + "version": "5.0.17", + "resolved": "https://registry.npmjs.org/@fontsource/inter/-/inter-5.0.17.tgz", + "integrity": "sha512-2meBGx1kt7u5LwzGc5Sz5rka6ZDrydg6nT3x6Wkt310vHXUchIywrO8pooWMzZdHYcyFY/cv4lEpJZgMD94bCg==" + }, + "node_modules/@fontsource/plus-jakarta-sans": { + "version": "5.0.19", + "resolved": "https://registry.npmjs.org/@fontsource/plus-jakarta-sans/-/plus-jakarta-sans-5.0.19.tgz", + "integrity": "sha512-LWMReNfB3s3tLRCPlFkqTfheqV40+2RQ4pOFhmKKB+9QrFsSf+g4Sl5r2V0+FNWHzdjfCas7uF4d+PejipqvUw==" + }, + "node_modules/@formatjs/ecma402-abstract": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz", + "integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==", + "dependencies": { + "@formatjs/intl-localematcher": "0.5.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/fast-memoize": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz", + "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/icu-messageformat-parser": { + "version": "2.7.6", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.6.tgz", + "integrity": "sha512-etVau26po9+eewJKYoiBKP6743I1br0/Ie00Pb/S/PtmYfmjTcOn2YCh2yNkSZI12h6Rg+BOgQYborXk46BvkA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/icu-skeleton-parser": "1.8.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/icu-skeleton-parser": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.0.tgz", + "integrity": "sha512-QWLAYvM0n8hv7Nq5BEs4LKIjevpVpbGLAJgOaYzg9wABEoX1j0JO1q2/jVkO6CVlq0dbsxZCngS5aXbysYueqA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@formatjs/intl/-/intl-2.10.0.tgz", + "integrity": "sha512-X3xT9guVkKDS86EKV80lS0KxoazUglkJTGZO66sKY7otgl0VeStPA8B3u8UkKT47PexVV98fUzjpkchYmbe9nw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/fast-memoize": "2.2.0", + "@formatjs/icu-messageformat-parser": "2.7.6", + "@formatjs/intl-displaynames": "6.6.6", + "@formatjs/intl-listformat": "7.5.5", + "intl-messageformat": "10.5.11", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "typescript": "^4.7 || 5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@formatjs/intl-displaynames": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/@formatjs/intl-displaynames/-/intl-displaynames-6.6.6.tgz", + "integrity": "sha512-Dg5URSjx0uzF8VZXtHb6KYZ6LFEEhCbAbKoYChYHEOnMFTw/ZU3jIo/NrujzQD2EfKPgQzIq73LOUvW6Z/LpFA==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/intl-localematcher": "0.5.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl-listformat": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-7.5.5.tgz", + "integrity": "sha512-XoI52qrU6aBGJC9KJddqnacuBbPlb/bXFN+lIFVFhQ1RnFHpzuFrlFdjD9am2O7ZSYsyqzYRpkVcXeT1GHkwDQ==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/intl-localematcher": "0.5.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl-localematcher": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz", + "integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "dev": true + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz", + "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.12.tgz", + "integrity": "sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.12.tgz", + "integrity": "sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.12.tgz", + "integrity": "sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.38", + "@mui/core-downloads-tracker": "^5.15.12", + "@mui/system": "^5.15.12", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material-nextjs": { + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/material-nextjs/-/material-nextjs-5.15.11.tgz", + "integrity": "sha512-cp5RWYbBngyi7NKP91R9QITllfxumCVPFjqe4AKzNROVuCot0VpgkafxXqfbv0uFsyUU0ROs0O2M3r17q604Aw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/server": "^11.11.0", + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "next": "^13.0.0 || ^14.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/cache": { + "optional": true + }, + "@emotion/server": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/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/@mui/private-theming": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz", + "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.12", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz", + "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.12", + "@mui/styled-engine": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz", + "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/x-data-grid": { + "version": "6.19.6", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.19.6.tgz", + "integrity": "sha512-jpZkX1Gnlo87gKcD10mKMY8YoAzUD8Cv3/IvedH3FINDKO3hnraMeOciKDeUk0tYSj8RUDB02kpTHCM8ojLVBA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/utils": "^5.14.16", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "reselect": "^4.1.8" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.4.1", + "@mui/system": "^5.4.1", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@mui/x-date-pickers": { + "version": "6.19.6", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.19.6.tgz", + "integrity": "sha512-QW9AFcPi0vLpkUhmquhhyhLaBvB0AZJuu3NTrE173qNKx3Z3n51aCLY9bc7c6i4ltZMMsVRHlvzQjsve04TC8A==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@mui/base": "^5.0.0-beta.22", + "@mui/utils": "^5.14.16", + "@types/react-transition-group": "^4.4.8", + "clsx": "^2.0.0", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.9.0", + "@emotion/styled": "^11.8.1", + "@mui/material": "^5.8.6", + "@mui/system": "^5.8.0", + "date-fns": "^2.25.0 || ^3.2.0", + "date-fns-jalali": "^2.13.0-0", + "dayjs": "^1.10.7", + "luxon": "^3.0.2", + "moment": "^2.29.4", + "moment-hijri": "^2.1.2", + "moment-jalaali": "^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "date-fns": { + "optional": true + }, + "date-fns-jalali": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + }, + "moment-hijri": { + "optional": true + }, + "moment-jalaali": { + "optional": true + } + } + }, + "node_modules/@next/env": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.4.tgz", + "integrity": "sha512-irQnbMLbUNQpP1wcE5NstJtbuA/69kRfzBrpAD7Gsn8zm/CY6YQYc3HQBz8QPxwISG26tIm5afvvVbu508oBeQ==" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.0.4.tgz", + "integrity": "sha512-U3qMNHmEZoVmHA0j/57nRfi3AscXNvkOnxDmle/69Jz/G0o/gWjXTDdlgILZdrxQ0Lw/jv2mPW8PGy0EGIHXhQ==", + "dev": true, + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@next/eslint-plugin-next/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.4.tgz", + "integrity": "sha512-mF05E/5uPthWzyYDyptcwHptucf/jj09i2SXBPwNzbgBNc+XnwzrL0U6BmPjQeOL+FiB+iG1gwBeq7mlDjSRPg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.4.tgz", + "integrity": "sha512-IZQ3C7Bx0k2rYtrZZxKKiusMTM9WWcK5ajyhOZkYYTCc8xytmwSzR1skU7qLgVT/EY9xtXDG0WhY6fyujnI3rw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.4.tgz", + "integrity": "sha512-VwwZKrBQo/MGb1VOrxJ6LrKvbpo7UbROuyMRvQKTFKhNaXjUmKTu7wxVkIuCARAfiI8JpaWAnKR+D6tzpCcM4w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.4.tgz", + "integrity": "sha512-8QftwPEW37XxXoAwsn+nXlodKWHfpMaSvt81W43Wh8dv0gkheD+30ezWMcFGHLI71KiWmHK5PSQbTQGUiidvLQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.4.tgz", + "integrity": "sha512-/s/Pme3VKfZAfISlYVq2hzFS8AcAIOTnoKupc/j4WlvF6GQ0VouS2Q2KEgPuO1eMBwakWPB1aYFIA4VNVh667A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.4.tgz", + "integrity": "sha512-m8z/6Fyal4L9Bnlxde5g2Mfa1Z7dasMQyhEhskDATpqr+Y0mjOBZcXQ7G5U+vgL22cI4T7MfvgtrM2jdopqWaw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.4.tgz", + "integrity": "sha512-7Wv4PRiWIAWbm5XrGz3D8HUkCVDMMz9igffZG4NB1p4u1KoItwx9qjATHz88kwCEal/HXmbShucaslXCQXUM5w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.4.tgz", + "integrity": "sha512-zLeNEAPULsl0phfGb4kdzF/cAVIfaC7hY+kt0/d+y9mzcZHsMS3hAS829WbJ31DkSlVKQeHEjZHIdhN+Pg7Gyg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.4.tgz", + "integrity": "sha512-yEh2+R8qDlDCjxVpzOTEpBLQTEFAcP2A8fUFLaWNap9GitYKkKv1//y2S6XY6zsR4rCOPRpU7plYDR+az2n30A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "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/@panva/hkdf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz", + "integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@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.7.2", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz", + "integrity": "sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA==", + "dev": true + }, + "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/@surma/rollup-plugin-off-main-thread/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", + "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.5", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", + "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "peer": true + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==" + }, + "node_modules/@types/node": { + "version": "20.11.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.24.tgz", + "integrity": "sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + }, + "node_modules/@types/react": { + "version": "18.2.63", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.63.tgz", + "integrity": "sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.20", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.20.tgz", + "integrity": "sha512-HXN/biJY8nv20Cn9ZbCFq3liERd4CozVZmKbaiZ9KiKTrWqsP7eoGDO6OOGvJQwoVFuiXaiJ7nBBjiFFbRmQMQ==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "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/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + }, + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true + }, + "node_modules/@types/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", + "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/type-utils": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", + "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", + "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "6.21.0", + "@typescript-eslint/utils": "6.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", + "dev": true, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, + "node_modules/@unly/iso3166-1": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@unly/iso3166-1/-/iso3166-1-1.0.2.tgz", + "integrity": "sha512-aL/7cmcfjpwOaKFr9XHcWP/Z7lQjKLm5NMcjncT96aeSJxfblmPLnH/8lnX0GrWWFA2/CseCxnA73u5eiZcClA==" + }, + "node_modules/@unly/universal-language-detector": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@unly/universal-language-detector/-/universal-language-detector-2.0.3.tgz", + "integrity": "sha512-UMmZIQS2XfJko8/GOrJc9ojO4UIF9HJM59NyQgcH+Ncrb0WBHL2L7EZ/7iZ/YcdoRnioonRECUQmmUELWt9z5Q==", + "dependencies": { + "@unly/iso3166-1": "1.0.2", + "@unly/utils": "1.0.3", + "accept-language-parser": "1.5.0", + "i18next": "19.0.2", + "i18next-browser-languagedetector": "4.0.1", + "lodash.get": "4.4.2", + "lodash.includes": "4.3.0" + } + }, + "node_modules/@unly/universal-language-detector/node_modules/i18next": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-19.0.2.tgz", + "integrity": "sha512-fBa43Ann2udP1CQAz3IQpOZ1dGAkmi3mMfzisOhH17igneSRbvZ7P2RNbL+L1iRYKMufBmVwnC7G3gqcyviZ9g==", + "dependencies": { + "@babel/runtime": "^7.3.1" + } + }, + "node_modules/@unly/utils": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@unly/utils/-/utils-1.0.3.tgz", + "integrity": "sha512-QTRknIDX56FvzGcIpBum5D/oRSlX3dkZ+l1op1jsFlYCTd925OGUb991V7zsFv3ePcqFfvfqfR5cNVv+w4JAOw==" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "peer": true + }, + "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==", + "peer": true + }, + "node_modules/@yr/monotone-cubic-spline": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", + "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" + }, + "node_modules/accept-language-parser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/accept-language-parser/-/accept-language-parser-1.5.0.tgz", + "integrity": "sha512-QhyTbMLYo0BBGg1aWbeMG4ekWtds/31BrEU+DONOg/7ax23vxpL03Pb7/zBmha2v7vdD3AyzZVWBVGEZxKOXWw==" + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "peer": true, + "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==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "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-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-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apexcharts": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.46.0.tgz", + "integrity": "sha512-ELAY6vj8JQD7QLktKasTzwm9Wt0qxqfQSo+3QWS7G7I774iK8HCkG1toGsqJH0mkK6PtYBtnSIe66uUcwoCw1w==", + "dependencies": { + "@yr/monotone-cubic-spline": "^1.0.3", + "svg.draggable.js": "^2.2.2", + "svg.easing.js": "^2.0.0", + "svg.filter.js": "^2.0.2", + "svg.pathmorphing.js": "^0.1.3", + "svg.resize.js": "^1.4.3", + "svg.select.js": "^3.0.1" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.filter": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz", + "integrity": "sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.4.tgz", + "integrity": "sha512-BMtLxpV+8BD+6ZPFIWmnUBpQoy+A+ujcg4rhp2iwCRJYA7PEh2MS4NL3lz8EiDlLrJPp2hg9qWihr5pd//jcGw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz", + "integrity": "sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.toreversed": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz", + "integrity": "sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.3.tgz", + "integrity": "sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.1.0", + "es-shim-unscopables": "^1.0.2" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true + }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", + "integrity": "sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "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.18", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", + "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.23.0", + "caniuse-lite": "^1.0.30001591", + "fraction.js": "^4.3.7", + "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.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", + "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "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-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-polyfill-corejs2": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", + "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.5.0", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", + "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0", + "core-js-compat": "^3.34.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", + "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.5.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "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/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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/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/browserslist": { + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "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/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001594", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz", + "integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/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/chalk/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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/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==", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, + "node_modules/clean-webpack-plugin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz", + "integrity": "sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==", + "dependencies": { + "del": "^4.1.1" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": ">=4.0.0 <6.0.0" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + }, + "node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, + "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/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + }, + "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/core-js-compat": { + "version": "3.36.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", + "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "dependencies": { + "browserslist": "^4.22.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "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==", + "dev": true, + "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-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, + "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/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/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/del/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.693", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.693.tgz", + "integrity": "sha512-/if4Ueg0GUQlhCrW2ZlXwDAm40ipuKo+OgeHInlL8sbjt+hzISxZK949fZeJaVsheamrzANXvw1zQTvbxTvSHw==" + }, + "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==", + "dev": true + }, + "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/enhanced-resolve": { + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", + "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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/es-abstract": { + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", + "integrity": "sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.1", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.0", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.5", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz", + "integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==", + "dev": true, + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.4", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.2", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "peer": true + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.0.4.tgz", + "integrity": "sha512-9/xbOHEQOmQtqvQ1UsTQZpnA7SlDMBtuKJ//S4JnoyK3oGLhILKXdBgu/UO7lQo/2xOykQULS1qQ6p2+EpHgAQ==", + "dev": true, + "dependencies": { + "@next/eslint-plugin-next": "14.0.4", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz", + "integrity": "sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.23.2", + "aria-query": "^5.3.0", + "array-includes": "^3.1.7", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "=4.7.0", + "axobject-query": "^3.2.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "es-iterator-helpers": "^1.0.15", + "hasown": "^2.0.0", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.34.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.0.tgz", + "integrity": "sha512-MeVXdReleBTdkz/bvcQMSnCXGi+c9kvy51IpinjnJgutl3YTHWsDdke7Z1ufZpGfDG8xduBDKyjtB9JH1eBKIQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlast": "^1.2.4", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.toreversed": "^1.1.2", + "array.prototype.tosorted": "^1.1.3", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.17", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.7", + "object.fromentries": "^2.0.7", + "object.hasown": "^1.1.3", + "object.values": "^1.1.7", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.10" + }, + "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==", + "dev": true, + "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/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.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==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/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==", + "dev": true, + "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==", + "dev": true + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "dev": true, + "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/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "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-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "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-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==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "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==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.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/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": 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/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "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/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.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "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-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "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": "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/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "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/glob/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/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true + }, + "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.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", + "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "node_modules/i18next": { + "version": "23.10.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.0.tgz", + "integrity": "sha512-/TgHOqsa7/9abUKJjdPeydoyDc0oTi/7u9F8lMSj6ufg4cbC1Oj3f/Jja7zj7WRIhEQKB7Q4eN6y68I9RDxxGQ==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/i18next-browser-languagedetector": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-4.0.1.tgz", + "integrity": "sha512-RxSoX6mB8cab0CTIQ+klCS764vYRj+Jk621cnFVsINvcdlb/cdi3vQFyrPwmnowB7ReUadjHovgZX+RPIzHVQQ==", + "dependencies": { + "@babel/runtime": "^7.5.5" + } + }, + "node_modules/i18next-resources-to-backend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.0.tgz", + "integrity": "sha512-8f1l03s+QxDmCfpSXCh9V+AFcxAwIp0UaroWuyOx+hmmv8484GcELHs+lnu54FrNij8cDBEXvEwhzZoXsKcVpg==", + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, + "node_modules/idb": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz", + "integrity": "sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==" + }, + "node_modules/ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "engines": { + "node": ">= 4" + } + }, + "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/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "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/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/intl-messageformat": { + "version": "10.5.11", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz", + "integrity": "sha512-eYq5fkFBVxc7GIFDzpFQkDOZgNayNTQn4Oufe8jw6YY6OHVw70/4pA3FyCsQ0Gb2DnvEJEMmN2tOaXUGByM+kg==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/fast-memoize": "2.2.0", + "@formatjs/icu-messageformat-parser": "2.7.6", + "tslib": "^2.4.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "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-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz", + "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", + "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", + "dev": true, + "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.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "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-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd/node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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-set": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", + "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "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.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jake/node_modules/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/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/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/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-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", + "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "dev": true, + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "4.15.4", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz", + "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "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==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "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==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "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==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "dev": true, + "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==", + "peer": true, + "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/loader-utils/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "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.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "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/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/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/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "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/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-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "peer": true, + "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==", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "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/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "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==", + "peer": true + }, + "node_modules/next": { + "version": "14.0.4", + "resolved": "https://registry.npmjs.org/next/-/next-14.0.4.tgz", + "integrity": "sha512-qbwypnM7327SadwFtxXnQdGiKpkuhaRLE2uq62/nRul9cj9KhQ5LhHmlziTNqUidZotw/Q1I9OjirBROdUJNgA==", + "dependencies": { + "@next/env": "14.0.4", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001406", + "graceful-fs": "^4.2.11", + "postcss": "8.4.31", + "styled-jsx": "5.1.1", + "watchpack": "2.4.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=18.17.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "14.0.4", + "@next/swc-darwin-x64": "14.0.4", + "@next/swc-linux-arm64-gnu": "14.0.4", + "@next/swc-linux-arm64-musl": "14.0.4", + "@next/swc-linux-x64-gnu": "14.0.4", + "@next/swc-linux-x64-musl": "14.0.4", + "@next/swc-win32-arm64-msvc": "14.0.4", + "@next/swc-win32-ia32-msvc": "14.0.4", + "@next/swc-win32-x64-msvc": "14.0.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-auth": { + "version": "4.24.6", + "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.6.tgz", + "integrity": "sha512-djQt3ZEaWEIxcsuh3HTW2uuzLfXMRjHH+ugAsichlQSbH4iA5MRcgMA2HvTNvsDTDLh44tyU72+/gWsxgTbAKg==", + "dependencies": { + "@babel/runtime": "^7.20.13", + "@panva/hkdf": "^1.0.2", + "cookie": "^0.5.0", + "jose": "^4.11.4", + "oauth": "^0.9.15", + "openid-client": "^5.4.0", + "preact": "^10.6.3", + "preact-render-to-string": "^5.1.19", + "uuid": "^8.3.2" + }, + "peerDependencies": { + "next": "^12.2.5 || ^13 || ^14", + "nodemailer": "^6.6.5", + "react": "^17.0.2 || ^18", + "react-dom": "^17.0.2 || ^18" + }, + "peerDependenciesMeta": { + "nodemailer": { + "optional": true + } + } + }, + "node_modules/next-pwa": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/next-pwa/-/next-pwa-5.6.0.tgz", + "integrity": "sha512-XV8g8C6B7UmViXU8askMEYhWwQ4qc/XqJGnexbLV68hzKaGHZDMtHsm2TNxFcbR7+ypVuth/wwpiIlMwpRJJ5A==", + "dependencies": { + "babel-loader": "^8.2.5", + "clean-webpack-plugin": "^4.0.0", + "globby": "^11.0.4", + "terser-webpack-plugin": "^5.3.3", + "workbox-webpack-plugin": "^6.5.4", + "workbox-window": "^6.5.4" + }, + "peerDependencies": { + "next": ">=9.0.0" + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==" + }, + "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": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-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.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz", + "integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.2.tgz", + "integrity": "sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==", + "dev": true, + "dependencies": { + "array.prototype.filter": "^1.0.3", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz", + "integrity": "sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==", + "dev": true, + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz", + "integrity": "sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "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/openid-client": { + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.6.4.tgz", + "integrity": "sha512-T1h3B10BRPKfcObdBklX639tVz+xh34O7GjofqrqiAQdm7eHsQ00ih18x6wuJ/E6FxdtS2u3FmUGPDeEcMwzNA==", + "dependencies": { + "jose": "^4.15.4", + "lru-cache": "^6.0.0", + "object-hash": "^2.2.0", + "oidc-token-hash": "^5.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "dev": true, + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "engines": { + "node": ">=6" + } + }, + "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/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/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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "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/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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "dev": true, + "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/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", + "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-load-config/node_modules/yaml": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.0.tgz", + "integrity": "sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/postcss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", + "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.11" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.15", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", + "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/preact": { + "version": "10.19.6", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.19.6.tgz", + "integrity": "sha512-gympg+T2Z1fG1unB8NH29yHJwnEaCH37Z32diPDku316OTnRPeMbiRV9kTrfZpocXjdfnWuFUl/Mj4BHaf6gnw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/preact-render-to-string": { + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz", + "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==", + "dependencies": { + "pretty-format": "^3.8.0" + }, + "peerDependencies": { + "preact": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz", + "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "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-format": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz", + "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==" + }, + "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/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "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/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/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-apexcharts": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.1.tgz", + "integrity": "sha512-G14nVaD64Bnbgy8tYxkjuXEUp/7h30Q0U33xc3AwtGFijJB9nHqOt1a6eG0WBn055RgRg+NwqbKGtqPxy15d0Q==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "apexcharts": "^3.41.0", + "react": ">=0.13" + } + }, + "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-fast-compare": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", + "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + }, + "node_modules/react-hook-form": { + "version": "7.51.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.0.tgz", + "integrity": "sha512-BggOy5j58RdhdMzzRUHGOYhSz1oeylFAv6jUSG86OvCIvlAvS7KvnRY7yoAf2pfEiPN7BesnR0xx73nEk3qIiw==", + "engines": { + "node": ">=12.22.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/react-i18next": { + "version": "13.5.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-13.5.0.tgz", + "integrity": "sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-intl": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-6.6.2.tgz", + "integrity": "sha512-IpW2IkLtGENSFlX3vfH11rjuCIsW0VyjT0Q1pPKMZPtT2z1FxLt4weFT5Ezti2TScT1xiyb3aQBFth9EB7jzAg==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.18.2", + "@formatjs/icu-messageformat-parser": "2.7.6", + "@formatjs/intl": "2.10.0", + "@formatjs/intl-displaynames": "6.6.6", + "@formatjs/intl-listformat": "7.5.5", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/react": "16 || 17 || 18", + "hoist-non-react-statics": "^3.3.2", + "intl-messageformat": "10.5.11", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "react": "^16.6.0 || 17 || 18", + "typescript": "^4.7 || 5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "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/react-popper": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz", + "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17 || ^18", + "react-dom": "^16.8.0 || ^17 || ^18" + } + }, + "node_modules/react-select": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.8.0.tgz", + "integrity": "sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==", + "dependencies": { + "@babel/runtime": "^7.12.0", + "@emotion/cache": "^11.4.0", + "@emotion/react": "^11.8.1", + "@floating-ui/dom": "^1.0.1", + "@types/react-transition-group": "^4.4.0", + "memoize-one": "^6.0.0", + "prop-types": "^15.6.0", + "react-transition-group": "^4.3.0", + "use-isomorphic-layout-effect": "^1.1.2" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/reactstrap": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-9.2.2.tgz", + "integrity": "sha512-4KroiGOdqZLAnMGzHjpErW3G7bLB+QbKzzMLIDXydPIV0y74lpdL7WtXHkLWAGInd97WCPNx4+R0NQDPyzIfhw==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "@popperjs/core": "^2.6.0", + "classnames": "^2.2.3", + "prop-types": "^15.5.8", + "react-popper": "^2.2.4", + "react-transition-group": "^4.4.2" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.5.tgz", + "integrity": "sha512-62wgfC8dJWrmxv44CA36pLDnP6KKl3Vhxb7PL+8+qrrFMMoJij4vgiMP8zV4O8+CBMXY1mHxI5fITGHXFHVmQQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "get-intrinsic": "^1.2.3", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", + "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/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/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-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-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "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==", + "dev": true, + "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-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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": "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/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", + "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "dependencies": { + "define-data-property": "^1.1.2", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "engines": { + "node": ">=8" + } + }, + "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.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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-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/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width/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==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-components": { + "version": "6.1.8", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz", + "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==", + "dependencies": { + "@emotion/is-prop-valid": "1.2.1", + "@emotion/unitless": "0.8.0", + "@types/stylis": "4.2.0", + "css-to-react-native": "3.2.0", + "csstype": "3.1.2", + "postcss": "8.4.31", + "shallowequal": "1.1.0", + "stylis": "4.3.1", + "tslib": "2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz", + "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/styled-components/node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + }, + "node_modules/styled-components/node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz", + "integrity": "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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-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.draggable.js": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", + "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", + "dependencies": { + "svg.js": "^2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.easing.js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", + "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", + "dependencies": { + "svg.js": ">=2.3.x" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.filter.js": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", + "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.js": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", + "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" + }, + "node_modules/svg.pathmorphing.js": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", + "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", + "dependencies": { + "svg.js": "^2.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", + "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", + "dependencies": { + "svg.js": "^2.6.5", + "svg.select.js": "^2.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.resize.js/node_modules/svg.select.js": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", + "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", + "dependencies": { + "svg.js": "^2.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/svg.select.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", + "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", + "dependencies": { + "svg.js": "^2.6.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/sweetalert2": { + "version": "11.10.6", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.6.tgz", + "integrity": "sha512-CINZPLZXZRSZqSOE7H7j1F7X8e8O1kLOiXPmtJn1DYxvXsKBr3d16d90+IcwTTs7dJww20h8r8QIxIwsLGX+6A==", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tailwindcss/node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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/terser": { + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", + "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "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-webpack-plugin/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/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/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==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "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/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/ts-api-utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", + "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "dev": true + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.5.tgz", + "integrity": "sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "devOptional": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "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/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "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.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "engines": { + "node": ">= 10.0.0" + } + }, + "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.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "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/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "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/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/webpack": { + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "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-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==", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/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==", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "peer": true, + "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/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/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz", + "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", + "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", + "dev": true, + "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.14", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.14.tgz", + "integrity": "sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==", + "dependencies": { + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.5", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/workbox-background-sync": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.6.0.tgz", + "integrity": "sha512-jkf4ZdgOJxC9u2vztxLuPT/UjlH7m/nWRQ/MgGL0v8BJHoZdVGJd18Kck+a0e55wGXdqyHO+4IQTk0685g4MUw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-broadcast-update": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-broadcast-update/-/workbox-broadcast-update-6.6.0.tgz", + "integrity": "sha512-nm+v6QmrIFaB/yokJmQ/93qIJ7n72NICxIwQwe5xsZiV2aI93MGGyEyzOzDPVz5THEr5rC3FJSsO3346cId64Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-build": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-6.6.0.tgz", + "integrity": "sha512-Tjf+gBwOTuGyZwMz2Nk/B13Fuyeo0Q84W++bebbVsfr9iLkDSo6j6PST8tET9HYA58mlRXwlMGpyWO8ETJiXdQ==", + "dependencies": { + "@apideck/better-ajv-errors": "^0.3.1", + "@babel/core": "^7.11.1", + "@babel/preset-env": "^7.11.0", + "@babel/runtime": "^7.11.2", + "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-node-resolve": "^11.2.1", + "@rollup/plugin-replace": "^2.4.1", + "@surma/rollup-plugin-off-main-thread": "^2.2.3", + "ajv": "^8.6.0", + "common-tags": "^1.8.0", + "fast-json-stable-stringify": "^2.1.0", + "fs-extra": "^9.0.1", + "glob": "^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.6.0", + "workbox-broadcast-update": "6.6.0", + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-google-analytics": "6.6.0", + "workbox-navigation-preload": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-range-requests": "6.6.0", + "workbox-recipes": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0", + "workbox-streams": "6.6.0", + "workbox-sw": "6.6.0", + "workbox-window": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/workbox-build/node_modules/@apideck/better-ajv-errors": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz", + "integrity": "sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==", + "dependencies": { + "json-schema": "^0.4.0", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "ajv": ">=8" + } + }, + "node_modules/workbox-build/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/workbox-build/node_modules/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-cacheable-response": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-6.6.0.tgz", + "integrity": "sha512-JfhJUSQDwsF1Xv3EV1vWzSsCOZn4mQ38bWEBR3LdvOxSPgB65gAM6cS2CX8rkkKHRgiLrN7Wxoyu+TuH67kHrw==", + "deprecated": "workbox-background-sync@6.6.0", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-core": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.6.0.tgz", + "integrity": "sha512-GDtFRF7Yg3DD859PMbPAYPeJyg5gJYXuBQAC+wyrWuuXgpfoOrIQIvFRZnQ7+czTIQjIr1DhLEGFzZanAT/3bQ==" + }, + "node_modules/workbox-expiration": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-expiration/-/workbox-expiration-6.6.0.tgz", + "integrity": "sha512-baplYXcDHbe8vAo7GYvyAmlS4f6998Jff513L4XvlzAOxcl8F620O91guoJ5EOf5qeXG4cGdNZHkkVAPouFCpw==", + "dependencies": { + "idb": "^7.0.1", + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-google-analytics": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-6.6.0.tgz", + "integrity": "sha512-p4DJa6OldXWd6M9zRl0H6vB9lkrmqYFkRQ2xEiNdBFp9U0LhsGO7hsBscVEyH9H2/3eZZt8c97NB2FD9U2NJ+Q==", + "deprecated": "It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained", + "dependencies": { + "workbox-background-sync": "6.6.0", + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-navigation-preload": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-6.6.0.tgz", + "integrity": "sha512-utNEWG+uOfXdaZmvhshrh7KzhDu/1iMHyQOV6Aqup8Mm78D286ugu5k9MFD9SzBT5TcwgwSORVvInaXWbvKz9Q==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-precaching": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-6.6.0.tgz", + "integrity": "sha512-eYu/7MqtRZN1IDttl/UQcSZFkHP7dnvr/X3Vn6Iw6OsPMruQHiVjjomDFCNtd8k2RdjLs0xiz9nq+t3YVBcWPw==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-range-requests": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-6.6.0.tgz", + "integrity": "sha512-V3aICz5fLGq5DpSYEU8LxeXvsT//mRWzKrfBOIxzIdQnV/Wj7R+LyJVTczi4CQ4NwKhAaBVaSujI1cEjXW+hTw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-recipes": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-recipes/-/workbox-recipes-6.6.0.tgz", + "integrity": "sha512-TFi3kTgYw73t5tg73yPVqQC8QQjxJSeqjXRO4ouE/CeypmP2O/xqmB/ZFBBQazLTPxILUQ0b8aeh0IuxVn9a6A==", + "dependencies": { + "workbox-cacheable-response": "6.6.0", + "workbox-core": "6.6.0", + "workbox-expiration": "6.6.0", + "workbox-precaching": "6.6.0", + "workbox-routing": "6.6.0", + "workbox-strategies": "6.6.0" + } + }, + "node_modules/workbox-routing": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.6.0.tgz", + "integrity": "sha512-x8gdN7VDBiLC03izAZRfU+WKUXJnbqt6PG9Uh0XuPRzJPpZGLKce/FkOX95dWHRpOHWLEq8RXzjW0O+POSkKvw==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-strategies": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.6.0.tgz", + "integrity": "sha512-eC07XGuINAKUWDnZeIPdRdVja4JQtTuc35TZ8SwMb1ztjp7Ddq2CJ4yqLvWzFWGlYI7CG/YGqaETntTxBGdKgQ==", + "dependencies": { + "workbox-core": "6.6.0" + } + }, + "node_modules/workbox-streams": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-6.6.0.tgz", + "integrity": "sha512-rfMJLVvwuED09CnH1RnIep7L9+mj4ufkTyDPVaXPKlhi9+0czCu+SJggWCIFbPpJaAZmp2iyVGLqS3RUmY3fxg==", + "dependencies": { + "workbox-core": "6.6.0", + "workbox-routing": "6.6.0" + } + }, + "node_modules/workbox-sw": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-6.6.0.tgz", + "integrity": "sha512-R2IkwDokbtHUE4Kus8pKO5+VkPHD2oqTgl+XJwh4zbF1HyjAbgNmK/FneZHVU7p03XUt9ICfuGDYISWG9qV/CQ==" + }, + "node_modules/workbox-webpack-plugin": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-6.6.0.tgz", + "integrity": "sha512-xNZIZHalboZU66Wa7x1YkjIqEy1gTR+zPM+kjrYJzqN7iurYZBctBLISyScjhkJKYuRrZUP0iqViZTh8rS0+3A==", + "dependencies": { + "fast-json-stable-stringify": "^2.1.0", + "pretty-bytes": "^5.4.1", + "upath": "^1.2.0", + "webpack-sources": "^1.4.3", + "workbox-build": "6.6.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "webpack": "^4.4.0 || ^5.9.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/workbox-webpack-plugin/node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/workbox-window": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/workbox-window/-/workbox-window-6.6.0.tgz", + "integrity": "sha512-L4N9+vka17d16geaJXXRjENLFldvkWy7JyGxElRD0JvBxvFEd8LOhr+uXCcar/NzAmIBRv9EZ+M+Qr4mOoBITw==", + "dependencies": { + "@types/trusted-types": "^2.0.2", + "workbox-core": "6.6.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + }, + "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/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c8eea49 --- /dev/null +++ b/package.json @@ -0,0 +1,59 @@ +{ + "name": "tsms", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "NODE_OPTIONS='--inspect' next start", + "lint": "next lint" + }, + "dependencies": { + "@emotion/cache": "^11.11.0", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@fontsource/inter": "^5.0.16", + "@fontsource/plus-jakarta-sans": "^5.0.18", + "@mui/icons-material": "^5.15.0", + "@mui/material": "^5.15.0", + "@mui/material-nextjs": "^5.15.0", + "@mui/x-data-grid": "^6.18.7", + "@mui/x-date-pickers": "^6.18.7", + "@unly/universal-language-detector": "^2.0.3", + "apexcharts": "^3.45.2", + "dayjs": "^1.11.10", + "i18next": "^23.7.11", + "i18next-resources-to-backend": "^1.2.0", + "lodash": "^4.17.21", + "next": "14.0.4", + "next-auth": "^4.24.5", + "next-pwa": "^5.6.0", + "react": "^18", + "react-apexcharts": "^1.4.1", + "react-dom": "^18", + "react-hook-form": "^7.49.2", + "react-i18next": "^13.5.0", + "react-intl": "^6.5.5", + "react-select": "^5.8.0", + "reactstrap": "^9.2.2", + "styled-components": "^6.1.8", + "sweetalert2": "^11.10.3" + }, + "devDependencies": { + "@types/lodash": "^4.14.202", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "@typescript-eslint/eslint-plugin": "^6.18.1", + "@typescript-eslint/parser": "^6.18.1", + "autoprefixer": "^10.4.16", + "eslint": "^8", + "eslint-config-next": "14.0.4", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.0.1", + "postcss": "^8.4.33", + "prettier": "3.1.1", + "tailwindcss": "^3.4.1", + "typescript": "^5" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/public/android/android-launchericon-144-144.png b/public/android/android-launchericon-144-144.png new file mode 100644 index 0000000..5b8cff0 Binary files /dev/null and b/public/android/android-launchericon-144-144.png differ diff --git a/public/android/android-launchericon-192-192.png b/public/android/android-launchericon-192-192.png new file mode 100644 index 0000000..fc974ac Binary files /dev/null and b/public/android/android-launchericon-192-192.png differ diff --git a/public/android/android-launchericon-48-48.png b/public/android/android-launchericon-48-48.png new file mode 100644 index 0000000..fb51d69 Binary files /dev/null and b/public/android/android-launchericon-48-48.png differ diff --git a/public/android/android-launchericon-512-512.png b/public/android/android-launchericon-512-512.png new file mode 100644 index 0000000..52d8c5f Binary files /dev/null and b/public/android/android-launchericon-512-512.png differ diff --git a/public/android/android-launchericon-72-72.png b/public/android/android-launchericon-72-72.png new file mode 100644 index 0000000..862afc8 Binary files /dev/null and b/public/android/android-launchericon-72-72.png differ diff --git a/public/android/android-launchericon-96-96.png b/public/android/android-launchericon-96-96.png new file mode 100644 index 0000000..7709d52 Binary files /dev/null and b/public/android/android-launchericon-96-96.png differ diff --git a/public/ios/100.png b/public/ios/100.png new file mode 100644 index 0000000..ffac59e Binary files /dev/null and b/public/ios/100.png differ diff --git a/public/ios/1024.png b/public/ios/1024.png new file mode 100644 index 0000000..bfddd72 Binary files /dev/null and b/public/ios/1024.png differ diff --git a/public/ios/114.png b/public/ios/114.png new file mode 100644 index 0000000..04b16da Binary files /dev/null and b/public/ios/114.png differ diff --git a/public/ios/120.png b/public/ios/120.png new file mode 100644 index 0000000..317fb68 Binary files /dev/null and b/public/ios/120.png differ diff --git a/public/ios/128.png b/public/ios/128.png new file mode 100644 index 0000000..25a14aa Binary files /dev/null and b/public/ios/128.png differ diff --git a/public/ios/144.png b/public/ios/144.png new file mode 100644 index 0000000..5b8cff0 Binary files /dev/null and b/public/ios/144.png differ diff --git a/public/ios/152.png b/public/ios/152.png new file mode 100644 index 0000000..faf2abb Binary files /dev/null and b/public/ios/152.png differ diff --git a/public/ios/16.png b/public/ios/16.png new file mode 100644 index 0000000..1bf35ab Binary files /dev/null and b/public/ios/16.png differ diff --git a/public/ios/167.png b/public/ios/167.png new file mode 100644 index 0000000..9903ed6 Binary files /dev/null and b/public/ios/167.png differ diff --git a/public/ios/180.png b/public/ios/180.png new file mode 100644 index 0000000..b37852a Binary files /dev/null and b/public/ios/180.png differ diff --git a/public/ios/192.png b/public/ios/192.png new file mode 100644 index 0000000..fc974ac Binary files /dev/null and b/public/ios/192.png differ diff --git a/public/ios/20.png b/public/ios/20.png new file mode 100644 index 0000000..3265bd8 Binary files /dev/null and b/public/ios/20.png differ diff --git a/public/ios/256.png b/public/ios/256.png new file mode 100644 index 0000000..3e30a75 Binary files /dev/null and b/public/ios/256.png differ diff --git a/public/ios/29.png b/public/ios/29.png new file mode 100644 index 0000000..233a37a Binary files /dev/null and b/public/ios/29.png differ diff --git a/public/ios/32.png b/public/ios/32.png new file mode 100644 index 0000000..4667d2b Binary files /dev/null and b/public/ios/32.png differ diff --git a/public/ios/40.png b/public/ios/40.png new file mode 100644 index 0000000..3b158ff Binary files /dev/null and b/public/ios/40.png differ diff --git a/public/ios/50.png b/public/ios/50.png new file mode 100644 index 0000000..ce015a0 Binary files /dev/null and b/public/ios/50.png differ diff --git a/public/ios/512.png b/public/ios/512.png new file mode 100644 index 0000000..52d8c5f Binary files /dev/null and b/public/ios/512.png differ diff --git a/public/ios/57.png b/public/ios/57.png new file mode 100644 index 0000000..0a4fb02 Binary files /dev/null and b/public/ios/57.png differ diff --git a/public/ios/58.png b/public/ios/58.png new file mode 100644 index 0000000..a67d6aa Binary files /dev/null and b/public/ios/58.png differ diff --git a/public/ios/60.png b/public/ios/60.png new file mode 100644 index 0000000..7d5c06f Binary files /dev/null and b/public/ios/60.png differ diff --git a/public/ios/64.png b/public/ios/64.png new file mode 100644 index 0000000..50e0637 Binary files /dev/null and b/public/ios/64.png differ diff --git a/public/ios/72.png b/public/ios/72.png new file mode 100644 index 0000000..862afc8 Binary files /dev/null and b/public/ios/72.png differ diff --git a/public/ios/76.png b/public/ios/76.png new file mode 100644 index 0000000..5d3a48e Binary files /dev/null and b/public/ios/76.png differ diff --git a/public/ios/80.png b/public/ios/80.png new file mode 100644 index 0000000..dd6016a Binary files /dev/null and b/public/ios/80.png differ diff --git a/public/ios/87.png b/public/ios/87.png new file mode 100644 index 0000000..6f723df Binary files /dev/null and b/public/ios/87.png differ diff --git a/public/windows11/LargeTile.scale-100.png b/public/windows11/LargeTile.scale-100.png new file mode 100644 index 0000000..01d410d Binary files /dev/null and b/public/windows11/LargeTile.scale-100.png differ diff --git a/public/windows11/LargeTile.scale-125.png b/public/windows11/LargeTile.scale-125.png new file mode 100644 index 0000000..d6b386d Binary files /dev/null and b/public/windows11/LargeTile.scale-125.png differ diff --git a/public/windows11/LargeTile.scale-150.png b/public/windows11/LargeTile.scale-150.png new file mode 100644 index 0000000..03de668 Binary files /dev/null and b/public/windows11/LargeTile.scale-150.png differ diff --git a/public/windows11/LargeTile.scale-200.png b/public/windows11/LargeTile.scale-200.png new file mode 100644 index 0000000..2a6fdec Binary files /dev/null and b/public/windows11/LargeTile.scale-200.png differ diff --git a/public/windows11/LargeTile.scale-400.png b/public/windows11/LargeTile.scale-400.png new file mode 100644 index 0000000..d6fe335 Binary files /dev/null and b/public/windows11/LargeTile.scale-400.png differ diff --git a/public/windows11/SmallTile.scale-100.png b/public/windows11/SmallTile.scale-100.png new file mode 100644 index 0000000..f086f66 Binary files /dev/null and b/public/windows11/SmallTile.scale-100.png differ diff --git a/public/windows11/SmallTile.scale-125.png b/public/windows11/SmallTile.scale-125.png new file mode 100644 index 0000000..9057fbd Binary files /dev/null and b/public/windows11/SmallTile.scale-125.png differ diff --git a/public/windows11/SmallTile.scale-150.png b/public/windows11/SmallTile.scale-150.png new file mode 100644 index 0000000..6cae119 Binary files /dev/null and b/public/windows11/SmallTile.scale-150.png differ diff --git a/public/windows11/SmallTile.scale-200.png b/public/windows11/SmallTile.scale-200.png new file mode 100644 index 0000000..8662921 Binary files /dev/null and b/public/windows11/SmallTile.scale-200.png differ diff --git a/public/windows11/SmallTile.scale-400.png b/public/windows11/SmallTile.scale-400.png new file mode 100644 index 0000000..a21e56a Binary files /dev/null and b/public/windows11/SmallTile.scale-400.png differ diff --git a/public/windows11/SplashScreen.scale-100.png b/public/windows11/SplashScreen.scale-100.png new file mode 100644 index 0000000..dfd538c Binary files /dev/null and b/public/windows11/SplashScreen.scale-100.png differ diff --git a/public/windows11/SplashScreen.scale-125.png b/public/windows11/SplashScreen.scale-125.png new file mode 100644 index 0000000..528db16 Binary files /dev/null and b/public/windows11/SplashScreen.scale-125.png differ diff --git a/public/windows11/SplashScreen.scale-150.png b/public/windows11/SplashScreen.scale-150.png new file mode 100644 index 0000000..9765333 Binary files /dev/null and b/public/windows11/SplashScreen.scale-150.png differ diff --git a/public/windows11/SplashScreen.scale-200.png b/public/windows11/SplashScreen.scale-200.png new file mode 100644 index 0000000..04eef39 Binary files /dev/null and b/public/windows11/SplashScreen.scale-200.png differ diff --git a/public/windows11/SplashScreen.scale-400.png b/public/windows11/SplashScreen.scale-400.png new file mode 100644 index 0000000..8cd23c5 Binary files /dev/null and b/public/windows11/SplashScreen.scale-400.png differ diff --git a/public/windows11/Square150x150Logo.scale-100.png b/public/windows11/Square150x150Logo.scale-100.png new file mode 100644 index 0000000..283ddca Binary files /dev/null and b/public/windows11/Square150x150Logo.scale-100.png differ diff --git a/public/windows11/Square150x150Logo.scale-125.png b/public/windows11/Square150x150Logo.scale-125.png new file mode 100644 index 0000000..3fc0f40 Binary files /dev/null and b/public/windows11/Square150x150Logo.scale-125.png differ diff --git a/public/windows11/Square150x150Logo.scale-150.png b/public/windows11/Square150x150Logo.scale-150.png new file mode 100644 index 0000000..b6eeb22 Binary files /dev/null and b/public/windows11/Square150x150Logo.scale-150.png differ diff --git a/public/windows11/Square150x150Logo.scale-200.png b/public/windows11/Square150x150Logo.scale-200.png new file mode 100644 index 0000000..509de7b Binary files /dev/null and b/public/windows11/Square150x150Logo.scale-200.png differ diff --git a/public/windows11/Square150x150Logo.scale-400.png b/public/windows11/Square150x150Logo.scale-400.png new file mode 100644 index 0000000..6246314 Binary files /dev/null and b/public/windows11/Square150x150Logo.scale-400.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-16.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-16.png new file mode 100644 index 0000000..1bf35ab Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-16.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-20.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-20.png new file mode 100644 index 0000000..3265bd8 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-20.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-24.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-24.png new file mode 100644 index 0000000..c35d89a Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-24.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-256.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-256.png new file mode 100644 index 0000000..3e30a75 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-256.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-30.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-30.png new file mode 100644 index 0000000..317c3f5 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-30.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-32.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-32.png new file mode 100644 index 0000000..4667d2b Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-32.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-36.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-36.png new file mode 100644 index 0000000..051a864 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-36.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-40.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-40.png new file mode 100644 index 0000000..3b158ff Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-40.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-44.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-44.png new file mode 100644 index 0000000..f4cd04d Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-44.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-48.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-48.png new file mode 100644 index 0000000..fb51d69 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-48.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-60.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-60.png new file mode 100644 index 0000000..7d5c06f Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-60.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-64.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-64.png new file mode 100644 index 0000000..50e0637 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-64.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-72.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-72.png new file mode 100644 index 0000000..862afc8 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-72.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-80.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-80.png new file mode 100644 index 0000000..dd6016a Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-80.png differ diff --git a/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-96.png b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-96.png new file mode 100644 index 0000000..7709d52 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-lightunplated_targetsize-96.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-16.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-16.png new file mode 100644 index 0000000..1bf35ab Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-16.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-20.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-20.png new file mode 100644 index 0000000..3265bd8 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-20.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-24.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-24.png new file mode 100644 index 0000000..c35d89a Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-24.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-256.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-256.png new file mode 100644 index 0000000..3e30a75 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-256.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-30.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-30.png new file mode 100644 index 0000000..317c3f5 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-30.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-32.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-32.png new file mode 100644 index 0000000..4667d2b Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-32.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-36.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-36.png new file mode 100644 index 0000000..051a864 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-36.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-40.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-40.png new file mode 100644 index 0000000..3b158ff Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-40.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-44.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-44.png new file mode 100644 index 0000000..f4cd04d Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-44.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-48.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-48.png new file mode 100644 index 0000000..fb51d69 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-48.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-60.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-60.png new file mode 100644 index 0000000..7d5c06f Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-60.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-64.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-64.png new file mode 100644 index 0000000..50e0637 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-64.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-72.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-72.png new file mode 100644 index 0000000..862afc8 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-72.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-80.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-80.png new file mode 100644 index 0000000..dd6016a Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-80.png differ diff --git a/public/windows11/Square44x44Logo.altform-unplated_targetsize-96.png b/public/windows11/Square44x44Logo.altform-unplated_targetsize-96.png new file mode 100644 index 0000000..7709d52 Binary files /dev/null and b/public/windows11/Square44x44Logo.altform-unplated_targetsize-96.png differ diff --git a/public/windows11/Square44x44Logo.scale-100.png b/public/windows11/Square44x44Logo.scale-100.png new file mode 100644 index 0000000..f4cd04d Binary files /dev/null and b/public/windows11/Square44x44Logo.scale-100.png differ diff --git a/public/windows11/Square44x44Logo.scale-125.png b/public/windows11/Square44x44Logo.scale-125.png new file mode 100644 index 0000000..ed29e05 Binary files /dev/null and b/public/windows11/Square44x44Logo.scale-125.png differ diff --git a/public/windows11/Square44x44Logo.scale-150.png b/public/windows11/Square44x44Logo.scale-150.png new file mode 100644 index 0000000..2a255d9 Binary files /dev/null and b/public/windows11/Square44x44Logo.scale-150.png differ diff --git a/public/windows11/Square44x44Logo.scale-200.png b/public/windows11/Square44x44Logo.scale-200.png new file mode 100644 index 0000000..18966c4 Binary files /dev/null and b/public/windows11/Square44x44Logo.scale-200.png differ diff --git a/public/windows11/Square44x44Logo.scale-400.png b/public/windows11/Square44x44Logo.scale-400.png new file mode 100644 index 0000000..6db3b1d Binary files /dev/null and b/public/windows11/Square44x44Logo.scale-400.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-16.png b/public/windows11/Square44x44Logo.targetsize-16.png new file mode 100644 index 0000000..1bf35ab Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-16.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-20.png b/public/windows11/Square44x44Logo.targetsize-20.png new file mode 100644 index 0000000..3265bd8 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-20.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-24.png b/public/windows11/Square44x44Logo.targetsize-24.png new file mode 100644 index 0000000..c35d89a Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-24.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-256.png b/public/windows11/Square44x44Logo.targetsize-256.png new file mode 100644 index 0000000..3e30a75 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-256.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-30.png b/public/windows11/Square44x44Logo.targetsize-30.png new file mode 100644 index 0000000..317c3f5 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-30.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-32.png b/public/windows11/Square44x44Logo.targetsize-32.png new file mode 100644 index 0000000..4667d2b Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-32.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-36.png b/public/windows11/Square44x44Logo.targetsize-36.png new file mode 100644 index 0000000..051a864 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-36.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-40.png b/public/windows11/Square44x44Logo.targetsize-40.png new file mode 100644 index 0000000..3b158ff Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-40.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-44.png b/public/windows11/Square44x44Logo.targetsize-44.png new file mode 100644 index 0000000..f4cd04d Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-44.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-48.png b/public/windows11/Square44x44Logo.targetsize-48.png new file mode 100644 index 0000000..fb51d69 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-48.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-60.png b/public/windows11/Square44x44Logo.targetsize-60.png new file mode 100644 index 0000000..7d5c06f Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-60.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-64.png b/public/windows11/Square44x44Logo.targetsize-64.png new file mode 100644 index 0000000..50e0637 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-64.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-72.png b/public/windows11/Square44x44Logo.targetsize-72.png new file mode 100644 index 0000000..862afc8 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-72.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-80.png b/public/windows11/Square44x44Logo.targetsize-80.png new file mode 100644 index 0000000..dd6016a Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-80.png differ diff --git a/public/windows11/Square44x44Logo.targetsize-96.png b/public/windows11/Square44x44Logo.targetsize-96.png new file mode 100644 index 0000000..7709d52 Binary files /dev/null and b/public/windows11/Square44x44Logo.targetsize-96.png differ diff --git a/public/windows11/StoreLogo.scale-100.png b/public/windows11/StoreLogo.scale-100.png new file mode 100644 index 0000000..80c7dc6 Binary files /dev/null and b/public/windows11/StoreLogo.scale-100.png differ diff --git a/public/windows11/StoreLogo.scale-125.png b/public/windows11/StoreLogo.scale-125.png new file mode 100644 index 0000000..be0220f Binary files /dev/null and b/public/windows11/StoreLogo.scale-125.png differ diff --git a/public/windows11/StoreLogo.scale-150.png b/public/windows11/StoreLogo.scale-150.png new file mode 100644 index 0000000..ca9892b Binary files /dev/null and b/public/windows11/StoreLogo.scale-150.png differ diff --git a/public/windows11/StoreLogo.scale-200.png b/public/windows11/StoreLogo.scale-200.png new file mode 100644 index 0000000..a4a3b0e Binary files /dev/null and b/public/windows11/StoreLogo.scale-200.png differ diff --git a/public/windows11/StoreLogo.scale-400.png b/public/windows11/StoreLogo.scale-400.png new file mode 100644 index 0000000..e7e25eb Binary files /dev/null and b/public/windows11/StoreLogo.scale-400.png differ diff --git a/public/windows11/Wide310x150Logo.scale-100.png b/public/windows11/Wide310x150Logo.scale-100.png new file mode 100644 index 0000000..f270004 Binary files /dev/null and b/public/windows11/Wide310x150Logo.scale-100.png differ diff --git a/public/windows11/Wide310x150Logo.scale-125.png b/public/windows11/Wide310x150Logo.scale-125.png new file mode 100644 index 0000000..771c413 Binary files /dev/null and b/public/windows11/Wide310x150Logo.scale-125.png differ diff --git a/public/windows11/Wide310x150Logo.scale-150.png b/public/windows11/Wide310x150Logo.scale-150.png new file mode 100644 index 0000000..a534073 Binary files /dev/null and b/public/windows11/Wide310x150Logo.scale-150.png differ diff --git a/public/windows11/Wide310x150Logo.scale-200.png b/public/windows11/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000..dfd538c Binary files /dev/null and b/public/windows11/Wide310x150Logo.scale-200.png differ diff --git a/public/windows11/Wide310x150Logo.scale-400.png b/public/windows11/Wide310x150Logo.scale-400.png new file mode 100644 index 0000000..04eef39 Binary files /dev/null and b/public/windows11/Wide310x150Logo.scale-400.png differ diff --git a/src/app/(main)/analytics/page.tsx b/src/app/(main)/analytics/page.tsx new file mode 100644 index 0000000..9ca9a24 --- /dev/null +++ b/src/app/(main)/analytics/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Analytics", +}; + +const Analytics: React.FC = async () => { + return "Analytics"; +}; + +export default Analytics; diff --git a/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx b/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx new file mode 100644 index 0000000..3a6079d --- /dev/null +++ b/src/app/(main)/dashboard/CompanyTeamCashFlow/page.tsx @@ -0,0 +1,26 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import DashboardPage from "@/components/DashboardPage/DashboardPage"; +import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; +import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; +import { Suspense } from "react"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Typography from "@mui/material/Typography"; +import CompanyTeamCashFlowComponent from "@/components/CompanyTeamCashFlow"; + +export const metadata: Metadata = { + title: "Project Status by Client", +}; + +const CompanyTeamCashFlow: React.FC = () => { + return ( + + + Company / Team Cash Flow + + + + ); +}; +export default CompanyTeamCashFlow; diff --git a/src/app/(main)/dashboard/ProjectCashFlow/page.tsx b/src/app/(main)/dashboard/ProjectCashFlow/page.tsx new file mode 100644 index 0000000..2e87f44 --- /dev/null +++ b/src/app/(main)/dashboard/ProjectCashFlow/page.tsx @@ -0,0 +1,29 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import DashboardPage from "@/components/DashboardPage/DashboardPage"; +import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; +import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; +import { Suspense } from "react"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Typography from "@mui/material/Typography"; +import ProjectCashFlowComponent from "@/components/ProjectCashFlow"; + +export const metadata: Metadata = { + title: "Project Status by Client", +}; + +const ProjectCashFlow: React.FC = () => { + return ( + + + Project Cash Flow + + {/* }> + + */} + + + ); +}; +export default ProjectCashFlow; diff --git a/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx b/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx new file mode 100644 index 0000000..3549f77 --- /dev/null +++ b/src/app/(main)/dashboard/ProjectFinancialSummary/page.tsx @@ -0,0 +1,26 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import DashboardPage from "@/components/DashboardPage/DashboardPage"; +import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Typography from "@mui/material/Typography"; +import ProjectFinancialSummaryComponents from "@/components/ProjectFinancialSummary"; + +export const metadata: Metadata = { + title: "Project Status by Client", +}; + +const ProjectFinancialSummary: React.FC = () => { + return ( + + + Project Financial Summary + + + + ); +}; +export default ProjectFinancialSummary; diff --git a/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx b/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx new file mode 100644 index 0000000..4ca47da --- /dev/null +++ b/src/app/(main)/dashboard/ProjectStatusByClient/page.tsx @@ -0,0 +1,29 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import DashboardPage from "@/components/DashboardPage/DashboardPage"; +import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Typography from "@mui/material/Typography"; +import ProgressByClient from "@/components/ProgressByClient"; + +export const metadata: Metadata = { + title: "Project Status by Client", +}; + +const ProjectStatusByClient: React.FC = () => { + return ( + + + Project Status by Client + + }> + + + + + ); +}; +export default ProjectStatusByClient; diff --git a/src/app/(main)/dashboard/StaffUtilization/page.tsx b/src/app/(main)/dashboard/StaffUtilization/page.tsx new file mode 100644 index 0000000..2ddea02 --- /dev/null +++ b/src/app/(main)/dashboard/StaffUtilization/page.tsx @@ -0,0 +1,26 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import DashboardPage from "@/components/DashboardPage/DashboardPage"; +import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import Typography from "@mui/material/Typography"; +import StaffUtilizationComponent from "@/components/StaffUtilization"; + +export const metadata: Metadata = { + title: "Project Status by Client", +}; + +const StaffUtilization: React.FC = () => { + return ( + + + Staff Utilization + + + + ); +}; +export default StaffUtilization; diff --git a/src/app/(main)/dashboard/page.tsx b/src/app/(main)/dashboard/page.tsx new file mode 100644 index 0000000..5f3d40b --- /dev/null +++ b/src/app/(main)/dashboard/page.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import DashboardPage from "@/components/DashboardPage/DashboardPage"; +import DashboardPageButton from "@/components/DashboardPage/DashboardTabButton"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; + +export const metadata: Metadata = { + title: "Dashboard", +}; + +const Dashboard: React.FC = () => { + return
test
; +}; + +export default Dashboard; diff --git a/src/app/(main)/home/page.tsx b/src/app/(main)/home/page.tsx new file mode 100644 index 0000000..a710195 --- /dev/null +++ b/src/app/(main)/home/page.tsx @@ -0,0 +1,17 @@ +import { Metadata } from "next"; +import { I18nProvider } from "@/i18n"; +import UserWorkspacePage from "@/components/UserWorkspacePage/UserWorkspacePage"; + +export const metadata: Metadata = { + title: "User Workspace", +}; + +const Home: React.FC = async () => { + return ( + + + + ); +}; + +export default Home; diff --git a/src/app/(main)/invoice/page.tsx b/src/app/(main)/invoice/page.tsx new file mode 100644 index 0000000..ae9fc37 --- /dev/null +++ b/src/app/(main)/invoice/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Invoice", +}; + +const Invoice: React.FC = async () => { + return "Invoice"; +}; + +export default Invoice; diff --git a/src/app/(main)/layout.tsx b/src/app/(main)/layout.tsx new file mode 100644 index 0000000..b93ed10 --- /dev/null +++ b/src/app/(main)/layout.tsx @@ -0,0 +1,41 @@ +import AppBar from "@/components/AppBar"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/config/authConfig"; +import { redirect } from "next/navigation"; +import Box from "@mui/material/Box"; +import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig"; +import Stack from "@mui/material/Stack"; +import Breadcrumb from "@/components/Breadcrumb"; + +export default async function MainLayout({ + children, +}: { + children: React.ReactNode; +}) { + const session = await getServerSession(authOptions); + + if (!session?.user) { + redirect("/login"); + } + + return ( + <> + + + + + {children} + + + + ); +} diff --git a/src/app/(main)/projects/create/page.tsx b/src/app/(main)/projects/create/page.tsx new file mode 100644 index 0000000..60ab586 --- /dev/null +++ b/src/app/(main)/projects/create/page.tsx @@ -0,0 +1,23 @@ +import CreateProject from "@/components/CreateProject"; +import { I18nProvider, getServerI18n } from "@/i18n"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Create Project", +}; + +const Projects: React.FC = async () => { + const { t } = await getServerI18n("projects"); + + return ( + <> + {t("Create Project")} + + + + + ); +}; + +export default Projects; diff --git a/src/app/(main)/projects/page.tsx b/src/app/(main)/projects/page.tsx new file mode 100644 index 0000000..1fe1800 --- /dev/null +++ b/src/app/(main)/projects/page.tsx @@ -0,0 +1,47 @@ +import { preloadProjects } from "@/app/api/projects"; +import ProjectSearch from "@/components/ProjectSearch"; +import { getServerI18n } from "@/i18n"; +import Add from "@mui/icons-material/Add"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; +import Link from "next/link"; +import { Suspense } from "react"; + +export const metadata: Metadata = { + title: "Projects", +}; + +const Projects: React.FC = async () => { + const { t } = await getServerI18n("projects"); + preloadProjects(); + + return ( + <> + + + {t("Projects")} + + + + }> + + + + ); +}; + +export default Projects; diff --git a/src/app/(main)/settings/page.tsx b/src/app/(main)/settings/page.tsx new file mode 100644 index 0000000..c3b9620 --- /dev/null +++ b/src/app/(main)/settings/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Settings", +}; + +const Settings: React.FC = async () => { + return "Settings"; +}; + +export default Settings; diff --git a/src/app/(main)/staffReimbursement/ClaimApproval/page.tsx b/src/app/(main)/staffReimbursement/ClaimApproval/page.tsx new file mode 100644 index 0000000..9388d1a --- /dev/null +++ b/src/app/(main)/staffReimbursement/ClaimApproval/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Claim", +}; + +const Claim: React.FC = async () => { + return "Claim"; +}; + +export default Claim; diff --git a/src/app/(main)/staffReimbursement/ClaimSummary/page.tsx b/src/app/(main)/staffReimbursement/ClaimSummary/page.tsx new file mode 100644 index 0000000..9388d1a --- /dev/null +++ b/src/app/(main)/staffReimbursement/ClaimSummary/page.tsx @@ -0,0 +1,11 @@ +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Claim", +}; + +const Claim: React.FC = async () => { + return "Claim"; +}; + +export default Claim; diff --git a/src/app/(main)/staffReimbursement/create/page.tsx b/src/app/(main)/staffReimbursement/create/page.tsx new file mode 100644 index 0000000..eafce4f --- /dev/null +++ b/src/app/(main)/staffReimbursement/create/page.tsx @@ -0,0 +1,21 @@ +import CreateClaim from "@/components/CreateClaim"; +import { getServerI18n } from "@/i18n"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Create Claim", +}; + +const CreateClaims: React.FC = async () => { + const { t } = await getServerI18n("claims"); + + return ( + <> + {t("Create Claim")} + + + ); +}; + +export default CreateClaims; diff --git a/src/app/(main)/staffReimbursement/page.tsx b/src/app/(main)/staffReimbursement/page.tsx new file mode 100644 index 0000000..1a1afcf --- /dev/null +++ b/src/app/(main)/staffReimbursement/page.tsx @@ -0,0 +1,47 @@ +import { preloadClaims } from "@/app/api/claims"; +import ClaimSearch from "@/components/ClaimSearch"; +import { getServerI18n } from "@/i18n"; +import Add from "@mui/icons-material/Add"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; +import Link from "next/link"; +import { Suspense } from "react"; + +export const metadata: Metadata = { + title: "Claims", +}; + +const StaffReimbursement: React.FC = async () => { + const { t } = await getServerI18n("claims"); + preloadClaims(); + + return ( + <> + + + {t("Staff Reimbursement")} + + + + }> + + + + ); +}; + +export default StaffReimbursement; diff --git a/src/app/(main)/tasks/create/page.tsx b/src/app/(main)/tasks/create/page.tsx new file mode 100644 index 0000000..656139f --- /dev/null +++ b/src/app/(main)/tasks/create/page.tsx @@ -0,0 +1,23 @@ +import { preloadAllTasks } from "@/app/api/tasks"; +import CreateTaskTemplate from "@/components/CreateTaskTemplate"; +import { getServerI18n } from "@/i18n"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Create Task Template", +}; + +const Projects: React.FC = async () => { + const { t } = await getServerI18n("tasks"); + preloadAllTasks(); + + return ( + <> + {t("Create Task Template")} + + + ); +}; + +export default Projects; diff --git a/src/app/(main)/tasks/page.tsx b/src/app/(main)/tasks/page.tsx new file mode 100644 index 0000000..b9e9bf8 --- /dev/null +++ b/src/app/(main)/tasks/page.tsx @@ -0,0 +1,47 @@ +import { preloadTaskTemplates } from "@/app/api/tasks"; +import TaskTemplateSearch from "@/components/TaskTemplateSearch"; +import { getServerI18n } from "@/i18n"; +import Add from "@mui/icons-material/Add"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Typography from "@mui/material/Typography"; +import { Metadata } from "next"; +import Link from "next/link"; +import { Suspense } from "react"; + +export const metadata: Metadata = { + title: "Tasks", +}; + +const TaskTemplates: React.FC = async () => { + const { t } = await getServerI18n("projects"); + preloadTaskTemplates(); + + return ( + <> + + + {t("Task Template")} + + + + }> + + + + ); +}; + +export default TaskTemplates; diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..2fa7df5 --- /dev/null +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,6 @@ +import { authOptions } from "@/config/authConfig"; +import NextAuth from "next-auth"; + +const handler = NextAuth(authOptions); + +export { handler as GET, handler as POST }; diff --git a/src/app/api/cashflow/index.ts b/src/app/api/cashflow/index.ts new file mode 100644 index 0000000..978a61e --- /dev/null +++ b/src/app/api/cashflow/index.ts @@ -0,0 +1,39 @@ +import { cache } from "react"; + +export interface CashFlow { + id: number; + projectCode: string; + projectName: string; + team: string; + teamLeader: string; + startDate: string; + startDateFrom: string; + startDateTo: string; + targetEndDate: string; + client: string; + subsidiary: string; +} + +export const preloadProjects = () => { + fetchProjectsCashFlow(); +}; + +export const fetchProjectsCashFlow = cache(async () => { + return mockProjects; +}); + +const mockProjects: CashFlow[] = [ + { + id: 1, + projectCode: "CUST-001", + projectName: "Client A", + team: "N/A", + teamLeader: "N/A", + startDate: "5", + startDateFrom: "5", + startDateTo: "5", + targetEndDate: "s", + client: "ss", + subsidiary: "ss", + }, +]; diff --git a/src/app/api/claims/index.ts b/src/app/api/claims/index.ts new file mode 100644 index 0000000..f012bcc --- /dev/null +++ b/src/app/api/claims/index.ts @@ -0,0 +1,50 @@ +import { cache } from "react"; +import "server-only"; + +export interface ClaimResult { + id: number; + created: string; + name: string; + cost: number; + type: "Expense" | "Petty Cash"; + status: "Not Submitted" | "Waiting for Approval" | "Approved" | "Rejected"; + remarks: string; +} + +export const preloadClaims = () => { + fetchClaims(); +}; + +export const fetchClaims = cache(async () => { + return mockClaims; +}); + +const mockClaims: ClaimResult[] = [ + { + id: 1, + created: "2023-11-22", + name: "Consultancy Project A", + cost: 121.0, + type: "Expense", + status: "Not Submitted", + remarks: "", + }, + { + id: 2, + created: "2023-11-30", + name: "Consultancy Project A", + cost: 4300.0, + type: "Expense", + status: "Waiting for Approval", + remarks: "", + }, + { + id: 3, + created: "2023-12-12", + name: "Construction Project C", + cost: 3675.0, + type: "Petty Cash", + status: "Rejected", + remarks: "Duplicate Claim Form", + }, +]; diff --git a/src/app/api/clientprojects/index.ts b/src/app/api/clientprojects/index.ts new file mode 100644 index 0000000..5c65810 --- /dev/null +++ b/src/app/api/clientprojects/index.ts @@ -0,0 +1,53 @@ +import { cache } from "react"; + +export interface ClientProjectResult { + id: number; + clientCode: string; + clientName: string; + SubsidiaryClientCode: string; + SubsidiaryClientName: string; + NoOfProjects: number; +} + +export const preloadProjects = () => { + fetchClientProjects(); +}; + +export const fetchClientProjects = cache(async () => { + return mockProjects; +}); + +const mockProjects: ClientProjectResult[] = [ + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + SubsidiaryClientCode: "N/A", + SubsidiaryClientName: "N/A", + NoOfProjects: 5, + }, + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + SubsidiaryClientCode: "SUBS-001", + SubsidiaryClientName: "Subsidiary A", + NoOfProjects: 5, + }, + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + SubsidiaryClientCode: "SUBS-002", + SubsidiaryClientName: "Subsidiary B", + NoOfProjects: 3, + }, + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + SubsidiaryClientCode: "SUBS-003", + SubsidiaryClientName: "Subsidiary C", + NoOfProjects: 1, + }, +]; diff --git a/src/app/api/projects/actions.ts b/src/app/api/projects/actions.ts new file mode 100644 index 0000000..ef39406 --- /dev/null +++ b/src/app/api/projects/actions.ts @@ -0,0 +1,59 @@ +"use server"; + +import { serverFetchJson } from "@/app/utils/fetchUtil"; +import { BASE_API_URL } from "@/config/api"; +import { Task, TaskGroup } from "../tasks"; + +export interface CreateProjectInputs { + // Project details + projectCode: string; + projectName: string; + projectCategory: string; + projectDescription: string; + + // Client details + clientCode: string; + clientName: string; + clientContactName: string; + clientPhone: string; + clientEmail: string; + clientSubsidiary: string; + + // Tasks + tasks: { + [taskId: Task["id"]]: { + manhourAllocation: ManhourAllocation; + }; + }; + + // Staff + allocatedStaffIds: number[]; + + // Milestones + milestones: { + [taskGroupId: TaskGroup["id"]]: { + startDate: string; + endDate: string; + payments: PaymentInputs[]; + }; + }; +} + +export interface ManhourAllocation { + [gradeId: number]: number; +} + +export interface PaymentInputs { + id: number; + description: string; + date: string; + amount: number; +} + +export const saveProject = async (data: CreateProjectInputs) => { + return serverFetchJson(`${BASE_API_URL}/projects/new`, { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + }); +}; diff --git a/src/app/api/projects/index.ts b/src/app/api/projects/index.ts new file mode 100644 index 0000000..a29be24 --- /dev/null +++ b/src/app/api/projects/index.ts @@ -0,0 +1,46 @@ +import { cache } from "react"; +import "server-only"; + +export interface ProjectResult { + id: number; + code: string; + name: string; + category: "Confirmed Project" | "Project to be bidded"; + team: string; + client: string; +} + +export const preloadProjects = () => { + fetchProjects(); +}; + +export const fetchProjects = cache(async () => { + return mockProjects; +}); + +const mockProjects: ProjectResult[] = [ + { + id: 1, + code: "M1001", + name: "Consultancy Project A", + category: "Confirmed Project", + team: "TW", + client: "Client A", + }, + { + id: 2, + code: "M1002", + name: "Consultancy Project B", + category: "Project to be bidded", + team: "WY", + client: "Client B", + }, + { + id: 3, + code: "S1001", + name: "Consultancy Project C", + category: "Confirmed Project", + team: "WY", + client: "Client C", + }, +]; diff --git a/src/app/api/tasks/actions.ts b/src/app/api/tasks/actions.ts new file mode 100644 index 0000000..862cc62 --- /dev/null +++ b/src/app/api/tasks/actions.ts @@ -0,0 +1,27 @@ +"use server"; + +import { serverFetchJson } from "@/app/utils/fetchUtil"; +import { BASE_API_URL } from "@/config/api"; +import { TaskTemplate } from "."; +import { revalidateTag } from "next/cache"; + +export interface NewTaskTemplateFormInputs { + code: string; + name: string; + taskIds: number[]; +} + +export const saveTaskTemplate = async (data: NewTaskTemplateFormInputs) => { + const newTaskTemplate = await serverFetchJson( + `${BASE_API_URL}/tasks/templates/new`, + { + method: "POST", + body: JSON.stringify(data), + headers: { "Content-Type": "application/json" }, + }, + ); + + revalidateTag("taskTemplates"); + + return newTaskTemplate; +}; diff --git a/src/app/api/tasks/index.ts b/src/app/api/tasks/index.ts new file mode 100644 index 0000000..f5889d7 --- /dev/null +++ b/src/app/api/tasks/index.ts @@ -0,0 +1,40 @@ +import { serverFetchJson } from "@/app/utils/fetchUtil"; +import { BASE_API_URL } from "@/config/api"; +import { cache } from "react"; +import "server-only"; + +export interface TaskGroup { + id: number; + name: string; +} + +export interface Task { + id: number; + name: string; + description: string | null; + taskGroup: TaskGroup; +} + +export interface TaskTemplate { + id: number; + code: string; + name: string; +} + +export const preloadTaskTemplates = () => { + fetchTaskTemplates(); +}; + +export const fetchTaskTemplates = cache(async () => { + return serverFetchJson(`${BASE_API_URL}/tasks/templates`, { + next: { tags: ["taskTemplates"] }, + }); +}); + +export const preloadAllTasks = () => { + fetchAllTasks(); +}; + +export const fetchAllTasks = cache(async () => { + return serverFetchJson(`${BASE_API_URL}/tasks`); +}); diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000..52d8c5f Binary files /dev/null and b/src/app/favicon.ico differ diff --git a/src/app/global.css b/src/app/global.css new file mode 100644 index 0000000..d4d058e --- /dev/null +++ b/src/app/global.css @@ -0,0 +1,3 @@ + +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..43b60c1 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,24 @@ +import type { Metadata } from "next"; +import { detectLanguage } from "@/i18n"; +import ThemeRegistry from "@/theme/ThemeRegistry"; + +export const metadata: Metadata = { + title: "TSMS", + description: "TSMS - Timesheet Management System", +}; + +export default async function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + const lang = await detectLanguage(); + + return ( + + + {children} + + + ); +} diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx new file mode 100644 index 0000000..7f9d7d7 --- /dev/null +++ b/src/app/login/page.tsx @@ -0,0 +1,20 @@ +import { getServerSession } from "next-auth"; +import { redirect } from "next/navigation"; +import { authOptions } from "@/config/authConfig"; +import { I18nProvider } from "@/i18n"; +import LoginPage from "@/components/LoginPage/LoginPage"; + +const Login: React.FC = async () => { + const session = await getServerSession(authOptions); + if (session?.user) { + redirect("/"); + } + + return ( + + + + ); +}; + +export default Login; diff --git a/src/app/logout/page.tsx b/src/app/logout/page.tsx new file mode 100644 index 0000000..cbaeefd --- /dev/null +++ b/src/app/logout/page.tsx @@ -0,0 +1,7 @@ +import LogoutPage from "@/components/LogoutPage"; + +const Logout: React.FC = async () => { + return ; +}; + +export default Logout; diff --git a/src/app/manifest.ts b/src/app/manifest.ts new file mode 100644 index 0000000..a0f6048 --- /dev/null +++ b/src/app/manifest.ts @@ -0,0 +1,464 @@ +import { MetadataRoute } from "next"; + +export default function manifest(): MetadataRoute.Manifest { + return { + name: "TSMS", + short_name: "TSMS", + description: "Timesheet Management System", + start_url: "/", + scope: "/", + display: "standalone", + background_color: "#fff", + theme_color: "#111927", + icons: [ + { + src: "windows11/SmallTile.scale-100.png", + sizes: "71x71", + }, + { + src: "windows11/SmallTile.scale-125.png", + sizes: "89x89", + }, + { + src: "windows11/SmallTile.scale-150.png", + sizes: "107x107", + }, + { + src: "windows11/SmallTile.scale-200.png", + sizes: "142x142", + }, + { + src: "windows11/SmallTile.scale-400.png", + sizes: "284x284", + }, + { + src: "windows11/Square150x150Logo.scale-100.png", + sizes: "150x150", + }, + { + src: "windows11/Square150x150Logo.scale-125.png", + sizes: "188x188", + }, + { + src: "windows11/Square150x150Logo.scale-150.png", + sizes: "225x225", + }, + { + src: "windows11/Square150x150Logo.scale-200.png", + sizes: "300x300", + }, + { + src: "windows11/Square150x150Logo.scale-400.png", + sizes: "600x600", + }, + { + src: "windows11/Wide310x150Logo.scale-100.png", + sizes: "310x150", + }, + { + src: "windows11/Wide310x150Logo.scale-125.png", + sizes: "388x188", + }, + { + src: "windows11/Wide310x150Logo.scale-150.png", + sizes: "465x225", + }, + { + src: "windows11/Wide310x150Logo.scale-200.png", + sizes: "620x300", + }, + { + src: "windows11/Wide310x150Logo.scale-400.png", + sizes: "1240x600", + }, + { + src: "windows11/LargeTile.scale-100.png", + sizes: "310x310", + }, + { + src: "windows11/LargeTile.scale-125.png", + sizes: "388x388", + }, + { + src: "windows11/LargeTile.scale-150.png", + sizes: "465x465", + }, + { + src: "windows11/LargeTile.scale-200.png", + sizes: "620x620", + }, + { + src: "windows11/LargeTile.scale-400.png", + sizes: "1240x1240", + }, + { + src: "windows11/Square44x44Logo.scale-100.png", + sizes: "44x44", + }, + { + src: "windows11/Square44x44Logo.scale-125.png", + sizes: "55x55", + }, + { + src: "windows11/Square44x44Logo.scale-150.png", + sizes: "66x66", + }, + { + src: "windows11/Square44x44Logo.scale-200.png", + sizes: "88x88", + }, + { + src: "windows11/Square44x44Logo.scale-400.png", + sizes: "176x176", + }, + { + src: "windows11/StoreLogo.scale-100.png", + sizes: "50x50", + }, + { + src: "windows11/StoreLogo.scale-125.png", + sizes: "63x63", + }, + { + src: "windows11/StoreLogo.scale-150.png", + sizes: "75x75", + }, + { + src: "windows11/StoreLogo.scale-200.png", + sizes: "100x100", + }, + { + src: "windows11/StoreLogo.scale-400.png", + sizes: "200x200", + }, + { + src: "windows11/SplashScreen.scale-100.png", + sizes: "620x300", + }, + { + src: "windows11/SplashScreen.scale-125.png", + sizes: "775x375", + }, + { + src: "windows11/SplashScreen.scale-150.png", + sizes: "930x450", + }, + { + src: "windows11/SplashScreen.scale-200.png", + sizes: "1240x600", + }, + { + src: "windows11/SplashScreen.scale-400.png", + sizes: "2480x1200", + }, + { + src: "windows11/Square44x44Logo.targetsize-16.png", + sizes: "16x16", + }, + { + src: "windows11/Square44x44Logo.targetsize-20.png", + sizes: "20x20", + }, + { + src: "windows11/Square44x44Logo.targetsize-24.png", + sizes: "24x24", + }, + { + src: "windows11/Square44x44Logo.targetsize-30.png", + sizes: "30x30", + }, + { + src: "windows11/Square44x44Logo.targetsize-32.png", + sizes: "32x32", + }, + { + src: "windows11/Square44x44Logo.targetsize-36.png", + sizes: "36x36", + }, + { + src: "windows11/Square44x44Logo.targetsize-40.png", + sizes: "40x40", + }, + { + src: "windows11/Square44x44Logo.targetsize-44.png", + sizes: "44x44", + }, + { + src: "windows11/Square44x44Logo.targetsize-48.png", + sizes: "48x48", + }, + { + src: "windows11/Square44x44Logo.targetsize-60.png", + sizes: "60x60", + }, + { + src: "windows11/Square44x44Logo.targetsize-64.png", + sizes: "64x64", + }, + { + src: "windows11/Square44x44Logo.targetsize-72.png", + sizes: "72x72", + }, + { + src: "windows11/Square44x44Logo.targetsize-80.png", + sizes: "80x80", + }, + { + src: "windows11/Square44x44Logo.targetsize-96.png", + sizes: "96x96", + }, + { + src: "windows11/Square44x44Logo.targetsize-256.png", + sizes: "256x256", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-16.png", + sizes: "16x16", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-20.png", + sizes: "20x20", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-24.png", + sizes: "24x24", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-30.png", + sizes: "30x30", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-32.png", + sizes: "32x32", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-36.png", + sizes: "36x36", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-40.png", + sizes: "40x40", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-44.png", + sizes: "44x44", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-48.png", + sizes: "48x48", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-60.png", + sizes: "60x60", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-64.png", + sizes: "64x64", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-72.png", + sizes: "72x72", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-80.png", + sizes: "80x80", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-96.png", + sizes: "96x96", + }, + { + src: "windows11/Square44x44Logo.altform-unplated_targetsize-256.png", + sizes: "256x256", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-16.png", + sizes: "16x16", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-20.png", + sizes: "20x20", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-24.png", + sizes: "24x24", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-30.png", + sizes: "30x30", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-32.png", + sizes: "32x32", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-36.png", + sizes: "36x36", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-40.png", + sizes: "40x40", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-44.png", + sizes: "44x44", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-48.png", + sizes: "48x48", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-60.png", + sizes: "60x60", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-64.png", + sizes: "64x64", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-72.png", + sizes: "72x72", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-80.png", + sizes: "80x80", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-96.png", + sizes: "96x96", + }, + { + src: "windows11/Square44x44Logo.altform-lightunplated_targetsize-256.png", + sizes: "256x256", + }, + { + src: "android/android-launchericon-512-512.png", + sizes: "512x512", + }, + { + src: "android/android-launchericon-192-192.png", + sizes: "192x192", + }, + { + src: "android/android-launchericon-144-144.png", + sizes: "144x144", + }, + { + src: "android/android-launchericon-96-96.png", + sizes: "96x96", + }, + { + src: "android/android-launchericon-72-72.png", + sizes: "72x72", + }, + { + src: "android/android-launchericon-48-48.png", + sizes: "48x48", + }, + { + src: "ios/16.png", + sizes: "16x16", + }, + { + src: "ios/20.png", + sizes: "20x20", + }, + { + src: "ios/29.png", + sizes: "29x29", + }, + { + src: "ios/32.png", + sizes: "32x32", + }, + { + src: "ios/40.png", + sizes: "40x40", + }, + { + src: "ios/50.png", + sizes: "50x50", + }, + { + src: "ios/57.png", + sizes: "57x57", + }, + { + src: "ios/58.png", + sizes: "58x58", + }, + { + src: "ios/60.png", + sizes: "60x60", + }, + { + src: "ios/64.png", + sizes: "64x64", + }, + { + src: "ios/72.png", + sizes: "72x72", + }, + { + src: "ios/76.png", + sizes: "76x76", + }, + { + src: "ios/80.png", + sizes: "80x80", + }, + { + src: "ios/87.png", + sizes: "87x87", + }, + { + src: "ios/100.png", + sizes: "100x100", + }, + { + src: "ios/114.png", + sizes: "114x114", + }, + { + src: "ios/120.png", + sizes: "120x120", + }, + { + src: "ios/128.png", + sizes: "128x128", + }, + { + src: "ios/144.png", + sizes: "144x144", + }, + { + src: "ios/152.png", + sizes: "152x152", + }, + { + src: "ios/167.png", + sizes: "167x167", + }, + { + src: "ios/180.png", + sizes: "180x180", + }, + { + src: "ios/192.png", + sizes: "192x192", + }, + { + src: "ios/256.png", + sizes: "256x256", + }, + { + src: "ios/512.png", + sizes: "512x512", + }, + { + src: "ios/1024.png", + sizes: "1024x1024", + }, + ], + }; +} diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..844c060 --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,7 @@ +import { permanentRedirect } from "next/navigation"; + +const Home: React.FC = async () => { + permanentRedirect("/home"); +}; + +export default Home; diff --git a/src/app/utils/fetchUtil.ts b/src/app/utils/fetchUtil.ts new file mode 100644 index 0000000..718dd30 --- /dev/null +++ b/src/app/utils/fetchUtil.ts @@ -0,0 +1,46 @@ +import { SessionWithTokens, authOptions } from "@/config/authConfig"; +import { getServerSession } from "next-auth"; +import { headers } from "next/headers"; +import { redirect } from "next/navigation"; + +export const serverFetch: typeof fetch = async (input, init) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const session = await getServerSession(authOptions); + const accessToken = session?.accessToken; + + return fetch(input, { + ...init, + headers: { + ...init?.headers, + ...(accessToken + ? { + Authorization: `Bearer ${accessToken}`, + } + : {}), + }, + }); +}; + +type FetchParams = Parameters; + +export async function serverFetchJson(...args: FetchParams) { + const response = await serverFetch(...args); + if (response.ok) { + return response.json() as T; + } else { + switch (response.status) { + case 401: + signOutUser(); + default: + throw Error("Something went wrong fetching data in server."); + } + } +} + +export const signOutUser = () => { + const headersList = headers(); + const referer = headersList.get("referer"); + redirect( + `/logout${referer ? `?callbackUrl=${encodeURIComponent(referer)}` : ""}`, + ); +}; diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts new file mode 100644 index 0000000..c2e38ea --- /dev/null +++ b/src/app/utils/formatUtil.ts @@ -0,0 +1,9 @@ +export const manhourFormatter = new Intl.NumberFormat("en-HK", { + minimumFractionDigits: 2, + maximumFractionDigits: 2, +}); + +export const moneyFormatter = new Intl.NumberFormat("en-HK", { + style: "currency", + currency: "HKD", +}); diff --git a/src/components/AppBar/AppBar.tsx b/src/components/AppBar/AppBar.tsx new file mode 100644 index 0000000..a38d2bd --- /dev/null +++ b/src/components/AppBar/AppBar.tsx @@ -0,0 +1,34 @@ +import MUIAppBar from "@mui/material/AppBar"; +import Toolbar from "@mui/material/Toolbar"; +import React from "react"; +import Profile from "./Profile"; +import Box from "@mui/material/Box"; +import NavigationToggle from "./NavigationToggle"; +import { I18nProvider } from "@/i18n"; + +export interface AppBarProps { + avatarImageSrc?: string; + profileName: string; +} + +const AppBar: React.FC = ({ avatarImageSrc, profileName }) => { + return ( + + + + + + + + + + + ); +}; + +export default AppBar; diff --git a/src/components/AppBar/NavigationToggle.tsx b/src/components/AppBar/NavigationToggle.tsx new file mode 100644 index 0000000..9f61753 --- /dev/null +++ b/src/components/AppBar/NavigationToggle.tsx @@ -0,0 +1,46 @@ +"use client"; +import IconButton from "@mui/material/IconButton"; +import MenuIcon from "@mui/icons-material/Menu"; +import NavigationContent from "../NavigationContent"; +import React from "react"; +import Drawer from "@mui/material/Drawer"; + +const NavigationToggle: React.FC = () => { + const [isOpened, setIsOpened] = React.useState(false); + + const openNavigation = () => { + setIsOpened(true); + }; + const closeNavigation = () => { + setIsOpened(false); + }; + + return ( + <> + + + + + + + + + + + ); +}; + +export default NavigationToggle; diff --git a/src/components/AppBar/Profile.tsx b/src/components/AppBar/Profile.tsx new file mode 100644 index 0000000..8cb49cf --- /dev/null +++ b/src/components/AppBar/Profile.tsx @@ -0,0 +1,61 @@ +"use client"; + +import IconButton from "@mui/material/IconButton"; +import Menu from "@mui/material/Menu"; +import MenuItem from "@mui/material/MenuItem"; +import Avatar from "@mui/material/Avatar"; +import React from "react"; +import { AppBarProps } from "./AppBar"; +import Divider from "@mui/material/Divider"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import { signOut } from "next-auth/react"; + +type Props = Pick; + +const Profile: React.FC = ({ avatarImageSrc, profileName }) => { + const [profileMenuAnchorEl, setProfileMenuAnchorEl] = + React.useState(); + const openProfileMenu: React.MouseEventHandler = ( + event, + ) => { + setProfileMenuAnchorEl(event.currentTarget); + }; + const closeProfileMenu = () => { + setProfileMenuAnchorEl(undefined); + }; + + const { t } = useTranslation("login"); + + return ( + <> + + + + + + {profileName} + + + signOut()}>{t("Sign out")} + + + ); +}; + +export default Profile; diff --git a/src/components/AppBar/index.ts b/src/components/AppBar/index.ts new file mode 100644 index 0000000..cc81140 --- /dev/null +++ b/src/components/AppBar/index.ts @@ -0,0 +1 @@ +export { default } from "./AppBar"; diff --git a/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx b/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx new file mode 100644 index 0000000..a41fc77 --- /dev/null +++ b/src/components/AssignedProjectGrid/AssignedProjectGrid.tsx @@ -0,0 +1,247 @@ +import * as React from "react"; +import { + Card, + CardHeader, + CardContent, + SxProps, + Theme, + Tabs, + Tab, + Box, + Typography, + Grid, + Link, +} from "@mui/material"; +import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { ThemeProvider } from "@emotion/react"; +import { TAB_THEME } from "@/theme/colorConst"; +import AllProjectGrid from "../UserWorkspacePage/ProjectGrid"; + +interface AssignedProjectGridProps { + Title?: string; + // rows: any[]; + // columns: any[]; + columnWidth?: number; + Style?: boolean; + sx?: SxProps; + height?: number; + [key: string]: any; +} + +interface TabPanelProps { + children?: React.ReactNode; + index: number; + value: number; +} + +function CustomTabPanel(props: TabPanelProps) { + const { children, value, index, ...other } = props; + + return ( + + ); +} + +function a11yProps(index: number) { + return { + id: `simple-tab-${index}`, + "aria-controls": `simple-tabpanel-${index}`, + }; +} + +const AssignedProjectGrid: React.FC = ({ + Title, + rows, + columns, + columnWidth, + Style = true, + sx, + height, + ...props +}) => { + // const modifiedColumns = columns.map((column) => { + // return { + // ...column, + // width: columnWidth ?? 150, + // }; + // }); + + // const rowsWithDefaultValues = rows.map((row) => { + // return { ...row }; + // }); + + const getBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7); + + const getHoverBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6); + + const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5); + + const getSelectedHoverBackgroundColor = ( + color: string, + mode: "light" | "dark", + ) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4)); + + const StyledDataGrid = styled(DataGrid)(({ theme }) => ({ + "& .super-app-theme--Open": { + backgroundColor: getBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--finish": { + backgroundColor: getBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--danger": { + backgroundColor: getBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--warning": { + backgroundColor: getBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + }, + }, + })); + + const [value, setValue] = React.useState(0); + + const handleChange = (event: React.SyntheticEvent, newValue: number) => { + setValue(newValue); + }; + + return ( +
+ + {Title && } + +
+ + + + + + + + + {/* + Item {value} + + + Item {value} + + + Item {value} + */} + +
+
+ +
+
+ ); +}; + +export default AssignedProjectGrid; diff --git a/src/components/AssignedProjectGrid/index.ts b/src/components/AssignedProjectGrid/index.ts new file mode 100644 index 0000000..7192046 --- /dev/null +++ b/src/components/AssignedProjectGrid/index.ts @@ -0,0 +1 @@ +export { default } from "./AssignedProjectGrid"; diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx new file mode 100644 index 0000000..8b4d131 --- /dev/null +++ b/src/components/Breadcrumb/Breadcrumb.tsx @@ -0,0 +1,51 @@ +"use client"; + +import Breadcrumbs from "@mui/material/Breadcrumbs"; +import Typography from "@mui/material/Typography"; +import Link from "next/link"; +import MUILink from "@mui/material/Link"; +import { usePathname } from "next/navigation"; + +const pathToLabelMap: { [path: string]: string } = { + "": "Overview", + "/projects": "Projects", + "/projects/create": "Create Project", + "/tasks": "Task Template", + "/tasks/create": "Create Task Template", +}; + +const Breadcrumb = () => { + const pathname = usePathname(); + const segments = pathname.split("/"); + + return ( + + {segments.map((segment, index) => { + const href = segments.slice(0, index + 1).join("/"); + const label = pathToLabelMap[href] || segment; + + if (index === segments.length - 1) { + return ( + + {label} + + ); + } else { + return ( + + {label} + + ); + } + })} + + ); +}; + +export default Breadcrumb; diff --git a/src/components/Breadcrumb/index.ts b/src/components/Breadcrumb/index.ts new file mode 100644 index 0000000..aa94cf8 --- /dev/null +++ b/src/components/Breadcrumb/index.ts @@ -0,0 +1 @@ +export { default } from "./Breadcrumb"; diff --git a/src/components/ClaimSearch/ClaimSearch.tsx b/src/components/ClaimSearch/ClaimSearch.tsx new file mode 100644 index 0000000..6ab02cf --- /dev/null +++ b/src/components/ClaimSearch/ClaimSearch.tsx @@ -0,0 +1,93 @@ +"use client"; + +import { ClaimResult } from "@/app/api/claims"; +import React, { useCallback, useMemo, useState } from "react"; +import SearchBox, { Criterion } from "../SearchBox/index"; +import { useTranslation } from "react-i18next"; +import SearchResults, { Column } from "../SearchResults/index"; +import EditNote from "@mui/icons-material/EditNote"; + +interface Props { + claims: ClaimResult[]; +} + +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +const ClaimSearch: React.FC = ({ claims }) => { + const { t } = useTranslation("claims"); + + // If claim searching is done on the server-side, then no need for this. + const [filteredClaims, setFilteredClaims] = useState(claims); + + const searchCriteria: Criterion[] = useMemo( + () => [ + { label: t("Creation Date"), paramName: "created", type: "dateRange" }, + { label: t("Related Project Name"), paramName: "name", type: "text" }, + { + label: t("Cost (HKD)"), + paramName: "cost", + type: "text", + }, + { + label: t("Expense Type"), + paramName: "type", + type: "select", + options: ["Expense", "Petty Cash"], + }, + { + label: t("Status"), + paramName: "status", + type: "select", + options: [ + "Not Submitted", + "Waiting for Approval", + "Approved", + "Rejected", + ], + }, + { + label: t("Remarks"), + paramName: "remarks", + type: "text", + }, + ], + [t], + ); + + const onClaimClick = useCallback((claim: ClaimResult) => { + console.log(claim); + }, []); + + const columns = useMemo[]>( + () => [ + // { + // name: "action", + // label: t("Actions"), + // onClick: onClaimClick, + // buttonIcon: , + // }, + { name: "created", label: t("Creation Date") }, + { name: "name", label: t("Related Project Name") }, + { name: "cost", label: t("Cost (HKD)") }, + { name: "type", label: t("Expense Type") }, + { name: "status", label: t("Status") }, + { name: "remarks", label: t("Remarks") }, + ], + [t, onClaimClick], + ); + + return ( + <> + { + console.log(query); + }} + /> + items={filteredClaims} columns={columns} /> + + ); +}; + +export default ClaimSearch; diff --git a/src/components/ClaimSearch/ClaimSearchLoading.tsx b/src/components/ClaimSearch/ClaimSearchLoading.tsx new file mode 100644 index 0000000..604aa7a --- /dev/null +++ b/src/components/ClaimSearch/ClaimSearchLoading.tsx @@ -0,0 +1,40 @@ +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Skeleton from "@mui/material/Skeleton"; +import Stack from "@mui/material/Stack"; +import React from "react"; + +// Can make this nicer +export const ClaimSearchLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ClaimSearchLoading; diff --git a/src/components/ClaimSearch/ClaimSearchWrapper.tsx b/src/components/ClaimSearch/ClaimSearchWrapper.tsx new file mode 100644 index 0000000..c8a7f55 --- /dev/null +++ b/src/components/ClaimSearch/ClaimSearchWrapper.tsx @@ -0,0 +1,18 @@ +import { fetchClaims } from "@/app/api/claims"; +import React from "react"; +import ClaimSearch from "./ClaimSearch"; +import ClaimSearchLoading from "./ClaimSearchLoading"; + +interface SubComponents { + Loading: typeof ClaimSearchLoading; +} + +const ClaimSearchWrapper: React.FC & SubComponents = async () => { + const claims = await fetchClaims(); + + return ; +}; + +ClaimSearchWrapper.Loading = ClaimSearchLoading; + +export default ClaimSearchWrapper; diff --git a/src/components/ClaimSearch/index.ts b/src/components/ClaimSearch/index.ts new file mode 100644 index 0000000..865400d --- /dev/null +++ b/src/components/ClaimSearch/index.ts @@ -0,0 +1 @@ +export { default } from "./ClaimSearchWrapper"; diff --git a/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx b/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx new file mode 100644 index 0000000..6d255a4 --- /dev/null +++ b/src/components/CompanyTeamCashFlow/CompanyTeamCashFlow.tsx @@ -0,0 +1,306 @@ +"use client"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord, AnyCnameRecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; +import { Input, Label } from "reactstrap"; +import Select, { components } from "react-select"; + +const CompanyTeamCashFlow: React.FC = () => { + const todayDate = new Date(); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [cashFlowYear, setCashFlowYear]: any[] = React.useState( + todayDate.getFullYear(), + ); + + const teamOptions = [ + { value: 1, label: "XXX Team" }, + { value: 2, label: "YYY Team" }, + { value: 3, label: "ZZZ Team" }, + ]; + + const columns = [ + { + id: "projectCode", + field: "projectCode", + headerName: "Project Code", + flex: 1, + }, + { + id: "projectName", + field: "projectName", + headerName: "Project Name", + flex: 1, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, + ]; + + const ledgerColumns = [ + { + id: "date", + field: "date", + headerName: "Date", + flex: 0.5, + }, + { + id: "expenditure", + field: "expenditure", + headerName: "Expenditure (HKD)", + flex: 0.6, + }, + { + id: "income", + field: "income", + headerName: "Income (HKD)", + flex: 0.6, + }, + { + id: "cashFlowBalance", + field: "cashFlowBalance", + headerName: "Cash Flow Balance (HKD)", + flex: 0.6, + }, + { + id: "remarks", + field: "remarks", + headerName: "Remarks", + flex: 1, + }, + ]; + + const options: ApexOptions = { + chart: { + height: 350, + type: "line", + }, + stroke: { + width: [0, 0, 2, 2], + }, + plotOptions: { + bar: { + horizontal: false, + distributed: false, + }, + }, + dataLabels: { + enabled: false, + }, + xaxis: { + categories: [ + "Q1", + "Q2", + "Q3", + "Q4", + "Q5", + "Q6", + "Q7", + "Q8", + "Q9", + "Q10", + "Q11", + "Q12", + ], + }, + yaxis: [ + { + title: { + text: "Monthly Income and Expenditure(HKD)", + }, + min: 0, + max: 3700000, + tickAmount: 5, + }, + { + show: false, + seriesName: "Monthly_Expenditure", + title: { + text: "Monthly Expenditure (HKD)", + }, + min: 0, + max: 3700000, + tickAmount: 5, + }, + { + seriesName: "Cumulative_Income", + opposite: true, + title: { + text: "Cumulative Income and Expenditure(HKD)", + }, + min: 0, + max: 21000000, + tickAmount: 5, + }, + { + show: false, + seriesName: "Cumulative_Expenditure", + opposite: true, + title: { + text: "Cumulative Expenditure (HKD)", + }, + min: 0, + max: 21000000, + tickAmount: 5, + }, + ], + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + series: [ + { + name: "Monthly_Income", + type: "column", + color: "#ffde91", + data: [ + 1280000, 170000, 3600000, 2400000, 1000000, 1800000, 1800000, 1200000, + 1250000, 1200000, 600000, 2400000, + ], + }, + { + name: "Monthly_Expenditure", + type: "column", + color: "#82b59a", + data: [ + 1200000, 1400000, 2000000, 1400000, 1450000, 1800000, 1200000, + 1400000, 1200000, 1600000, 2000000, 1600000, + ], + }, + { + name: "Cumulative_Income", + type: "line", + color: "#EE6D7A", + data: [ + 500000, 3000000, 7000000, 9000000, 10000000, 13000000, 14000000, + 16000000, 17000000, 17500000, 18000000, 20000000, + ], + }, + { + name: "Cumulative_Expenditure", + type: "line", + color: "#7cd3f2", + data: [ + 400000, 2800000, 4000000, 5200000, 7100000, 8000000, 10000000, + 11000000, 12100000, 14000000, 15400000, 17200000, + ], + }, + ], + }; + + return ( + <> + +
+ + + +
+
+ + +
+
+ +
+
+ +
+
+ +
+
+ + {t("M1001")} + {t("M1301")} + {t("M1354")} + + + + + + {t("Expense Type")} + + + + + + + + + + + {/* + + */} + + + ); +}; + +export default ClaimDetails; diff --git a/src/components/CreateClaim/ClaimInputGrid.tsx b/src/components/CreateClaim/ClaimInputGrid.tsx new file mode 100644 index 0000000..1231001 --- /dev/null +++ b/src/components/CreateClaim/ClaimInputGrid.tsx @@ -0,0 +1,442 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { useState, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import PageTitle from "../PageTitle/PageTitle"; +import { Suspense } from "react"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Link from "next/link"; +import { t } from "i18next"; +import { + Box, + Container, + Modal, + Select, + SelectChangeEvent, + Typography, +} from "@mui/material"; +import { Close } from "@mui/icons-material"; +import AddIcon from "@mui/icons-material/Add"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/DeleteOutlined"; +import SaveIcon from "@mui/icons-material/Save"; +import CancelIcon from "@mui/icons-material/Close"; +import AddPhotoAlternateOutlinedIcon from "@mui/icons-material/AddPhotoAlternateOutlined"; +import ImageNotSupportedOutlinedIcon from "@mui/icons-material/ImageNotSupportedOutlined"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import Swal from "sweetalert2"; +import { msg } from "../Swal/CustomAlerts"; +import React from "react"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { + GridRowsProp, + GridRowModesModel, + GridRowModes, + DataGrid, + GridColDef, + GridToolbarContainer, + GridFooterContainer, + GridActionsCellItem, + GridEventListener, + GridRowId, + GridRowModel, + GridRowEditStopReasons, + GridEditInputCell, + GridValueSetterParams, +} from "@mui/x-data-grid"; +import { LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import { Props } from "react-intl/src/components/relative"; +import palette from "@/theme/devias-material-kit/palette"; + +const weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; + +interface BottomBarProps { + getCostTotal: () => number; + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +interface EditToolbarProps { + // setDay: (newDay : dayjs.Dayjs) => void; + setDay: (newDay: (oldDay: dayjs.Dayjs) => dayjs.Dayjs) => void; + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +interface EditFooterProps { + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +const BottomBar = (props: BottomBarProps) => { + const { setRows, setRowModesModel, getCostTotal } = props; + // const getCostTotal = props.getCostTotal; + const [newId, setNewId] = useState(-1); + const [invalidDays, setInvalidDays] = useState(0); + + const handleAddClick = () => { + const id = newId; + setNewId(newId - 1); + setRows((oldRows) => [ + ...oldRows, + { id, projectCode: "", task: "", isNew: true }, + ]); + setRowModesModel((oldModel) => ({ + ...oldModel, + [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, + })); + }; + + const totalColDef = { + flex: 1, + // style: {color:getCostTotal('mon')>24?"red":"black"} + }; + + const TotalCell = ({ value }: Props) => { + const [invalid, setInvalid] = useState(false); + + useEffect(() => { + const newInvalid = (value ?? 0) < 0; + setInvalid(newInvalid); + }, [value]); + + return ( + + $ {value} + + ); + }; + + return ( +
+
+ + Total: + + +
+ +
+ ); +}; + +const EditFooter = (props: EditFooterProps) => { + return ( +
+ + Total: + + test +
+ ); +}; + +interface ClaimInputGridProps { + onClose?: () => void; +} + +const initialRows: GridRowsProp = [ + { + id: 1, + date: new Date(), + description: "Taxi to client office", + cost: 169.5, + document: "taxi_receipt.jpg", + }, + { + id: 2, + date: dayjs().add(-14, "days").toDate(), + description: "MTR fee to Kowloon Bay Office", + cost: 15.5, + document: "octopus_invoice.jpg", + }, + { + id: 3, + date: dayjs().add(-44, "days").toDate(), + description: "Starbucks", + cost: 504, + }, +]; + +const ClaimInputGrid: React.FC = ({ ...props }) => { + const [rows, setRows] = useState(initialRows); + const [day, setDay] = useState(dayjs()); + const [rowModesModel, setRowModesModel] = React.useState( + {}, + ); + + const handleRowEditStop: GridEventListener<"rowEditStop"> = ( + params, + event, + ) => { + if (params.reason === GridRowEditStopReasons.rowFocusOut) { + event.defaultMuiPrevented = true; + } + }; + + const handleEditClick = (id: GridRowId) => () => { + setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } }); + }; + + const handleSaveClick = (id: GridRowId) => () => { + setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); + }; + + const handleDeleteClick = (id: GridRowId) => () => { + setRows(rows.filter((row) => row.id !== id)); + }; + + const handleCancelClick = (id: GridRowId) => () => { + setRowModesModel({ + ...rowModesModel, + [id]: { mode: GridRowModes.View, ignoreModifications: true }, + }); + + const editedRow = rows.find((row) => row.id === id); + if (editedRow!.isNew) { + setRows(rows.filter((row) => row.id !== id)); + } + }; + + const processRowUpdate = (newRow: GridRowModel) => { + const updatedRow = { ...newRow, isNew: false }; + setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); + return updatedRow; + }; + + const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => { + setRowModesModel(newRowModesModel); + }; + + const getCostTotal = () => { + let sum = 0; + rows.forEach((row) => { + sum += row["cost"] ?? 0; + }); + return sum; + }; + + const commonGridColConfig: any = { + type: "number", + // sortable: false, + //width: 100, + flex: 1, + align: "left", + headerAlign: "left", + // headerClassName: 'header', + editable: true, + renderEditCell: (value: any) => ( + + ), + }; + + const columns: GridColDef[] = [ + { + field: "actions", + type: "actions", + headerName: "Actions", + width: 100, + cellClassName: "actions", + getActions: ({ id }) => { + const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; + + if (isInEditMode) { + return [ + } + title="Save" + label="Save" + sx={{ + color: "primary.main", + }} + onClick={handleSaveClick(id)} + />, + } + title="Cancel" + label="Cancel" + className="textPrimary" + onClick={handleCancelClick(id)} + color="inherit" + />, + ]; + } + + return [ + } + title="Edit" + label="Edit" + className="textPrimary" + onClick={handleEditClick(id)} + color="inherit" + />, + } + onClick={handleDeleteClick(id)} + sx={{ color: "red" }} + />, + ]; + }, + }, + { + field: "date", + headerName: "Invoice Date", + // width: 220, + flex: 1, + editable: true, + type: "date", + }, + { + field: "description", + headerName: "Description", + // width: 220, + flex: 2, + editable: true, + type: "string", + }, + { + field: "cost", + headerName: "Cost (HKD)", + editable: true, + type: "number", + valueFormatter: (params) => { + return `$ ${params.value ?? 0}`; + }, + }, + { + field: "document", + headerName: "Supporting Document", + type: "string", + editable: true, + flex: 2, + renderCell: (params) => { + return params.value ? ( + + + {params.value} + + + ) : ( + No Documents + ); + }, + renderEditCell: (params) => { + return params.value ? ( + + + {params.value} + + + + ) : ( + + ); + }, + }, + ]; + + return ( + + + + + + ); +}; + +export default ClaimInputGrid; diff --git a/src/components/CreateClaim/CreateClaim.tsx b/src/components/CreateClaim/CreateClaim.tsx new file mode 100644 index 0000000..5e89398 --- /dev/null +++ b/src/components/CreateClaim/CreateClaim.tsx @@ -0,0 +1,48 @@ +"use client"; + +import Check from "@mui/icons-material/Check"; +import Close from "@mui/icons-material/Close"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Tab from "@mui/material/Tab"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import { useRouter } from "next/navigation"; +import React, { useCallback, useState } from "react"; +import { useTranslation } from "react-i18next"; +import ClaimProjectDetails from "./ClaimDetails"; +// import TaskSetup from "./TaskSetup"; +// import StaffAllocation from "./StaffAllocation"; +// import ResourceMilestone from "./ResourceMilestone"; + +const CreateProject: React.FC = () => { + const [tabIndex, setTabIndex] = useState(0); + const { t } = useTranslation(); + const router = useRouter(); + + const handleCancel = () => { + router.back(); + }; + + const handleTabChange = useCallback>( + (_e, newValue) => { + setTabIndex(newValue); + }, + [], + ); + + return ( + <> + + + + + + + ); +}; + +export default CreateProject; diff --git a/src/components/CreateClaim/index.ts b/src/components/CreateClaim/index.ts new file mode 100644 index 0000000..a0bd052 --- /dev/null +++ b/src/components/CreateClaim/index.ts @@ -0,0 +1 @@ +export { default } from "./CreateClaim"; diff --git a/src/components/CreateProject/CreateProject.tsx b/src/components/CreateProject/CreateProject.tsx new file mode 100644 index 0000000..39adc96 --- /dev/null +++ b/src/components/CreateProject/CreateProject.tsx @@ -0,0 +1,125 @@ +"use client"; + +import Check from "@mui/icons-material/Check"; +import Close from "@mui/icons-material/Close"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Tab from "@mui/material/Tab"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import { useRouter } from "next/navigation"; +import React, { useCallback, useState } from "react"; +import { useTranslation } from "react-i18next"; +import ProjectClientDetails from "./ProjectClientDetails"; +import TaskSetup from "./TaskSetup"; +import StaffAllocation from "./StaffAllocation"; +import ResourceMilestone from "./ResourceMilestone"; +import { Task } from "@/app/api/tasks"; +import { + FieldErrors, + FormProvider, + SubmitErrorHandler, + SubmitHandler, + useForm, +} from "react-hook-form"; +import { CreateProjectInputs } from "@/app/api/projects/actions"; +import { Error } from "@mui/icons-material"; + +export interface Props { + allTasks: Task[]; +} + +const hasErrorsInTab = ( + tabIndex: number, + errors: FieldErrors, +) => { + switch (tabIndex) { + case 0: + return errors.projectName; + default: + false; + } +}; + +const CreateProject: React.FC = ({ allTasks }) => { + const [tabIndex, setTabIndex] = useState(0); + const { t } = useTranslation(); + const router = useRouter(); + + const handleCancel = () => { + router.back(); + }; + + const handleTabChange = useCallback>( + (_e, newValue) => { + setTabIndex(newValue); + }, + [], + ); + + const onSubmit = useCallback>((data) => { + console.log(data); + }, []); + + const onSubmitError = useCallback>( + (errors) => { + // Set the tab so that the focus will go there + if (errors.projectName) { + setTabIndex(0); + } + }, + [], + ); + + const formProps = useForm({ + defaultValues: { + tasks: {}, + allocatedStaffIds: [], + milestones: {}, + }, + }); + + const errors = formProps.formState.errors; + + return ( + + + + + ) : undefined + } + iconPosition="end" + /> + + + + + {} + {} + {} + {} + + + + + + + ); +}; + +export default CreateProject; diff --git a/src/components/CreateProject/CreateProjectWrapper.tsx b/src/components/CreateProject/CreateProjectWrapper.tsx new file mode 100644 index 0000000..f5fbb5a --- /dev/null +++ b/src/components/CreateProject/CreateProjectWrapper.tsx @@ -0,0 +1,10 @@ +import { fetchAllTasks } from "@/app/api/tasks"; +import CreateProject from "./CreateProject"; + +const CreateProjectWrapper: React.FC = async () => { + const tasks = await fetchAllTasks(); + + return ; +}; + +export default CreateProjectWrapper; diff --git a/src/components/CreateProject/MilestoneSection.tsx b/src/components/CreateProject/MilestoneSection.tsx new file mode 100644 index 0000000..dd4c154 --- /dev/null +++ b/src/components/CreateProject/MilestoneSection.tsx @@ -0,0 +1,338 @@ +import { CreateProjectInputs, PaymentInputs } from "@/app/api/projects/actions"; +import { TaskGroup } from "@/app/api/tasks"; +import { Add, Check, Close, Delete } from "@mui/icons-material"; +import { + Stack, + Typography, + Grid, + FormControl, + Box, + Button, +} from "@mui/material"; +import { + GridColDef, + GridActionsCellItem, + GridToolbarContainer, + GridRowModesModel, + GridRowModes, + FooterPropsOverrides, + GridRowId, + GridEventListener, + useGridApiRef, + GridRowModel, +} from "@mui/x-data-grid"; +import { LocalizationProvider, DatePicker } from "@mui/x-date-pickers"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import "dayjs/locale/zh-hk"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import { useFormContext } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import StyledDataGrid from "../StyledDataGrid"; +import { moneyFormatter } from "@/app/utils/formatUtil"; +import isDate from "lodash/isDate"; + +interface Props { + taskGroupId: TaskGroup["id"]; +} + +declare module "@mui/x-data-grid" { + interface FooterPropsOverrides { + onAdd: () => void; + } +} + +type PaymentRow = Partial; + +const MilestoneSection: React.FC = ({ taskGroupId }) => { + const { t } = useTranslation(); + const { getValues, setValue } = useFormContext(); + const [payments, setPayments] = useState( + getValues("milestones")[taskGroupId]?.payments || [], + ); + const [rowModesModel, setRowModesModel] = useState({}); + // Change the payments table depending on the TaskGroupId + useEffect(() => { + setPayments(getValues("milestones")[taskGroupId]?.payments || []); + setRowModesModel({}); + }, [getValues, taskGroupId]); + + const apiRef = useGridApiRef(); + const addRow = useCallback(() => { + const id = Date.now(); + setPayments((p) => [...p, { id, _isNew: true }]); + setRowModesModel((model) => ({ + ...model, + [id]: { mode: GridRowModes.Edit, fieldToFocus: "description" }, + })); + }, []); + + const validateRow = useCallback( + (id: GridRowId) => { + const row = apiRef.current.getRowWithUpdatedValues(id, "") as PaymentRow; + let error: keyof PaymentInputs | "" = ""; + if (!row.description) { + error = "description"; + } else if (!(isDate(row.date) && row.date.getTime())) { + error = "date"; + } else if (!(row.amount && row.amount >= 0)) { + error = "amount"; + } + + apiRef.current.updateRows([{ id, _error: error }]); + return !error; + }, + [apiRef], + ); + + const handleCancel = useCallback( + (id: GridRowId) => () => { + setRowModesModel((model) => ({ + ...model, + [id]: { mode: GridRowModes.View, ignoreModifications: true }, + })); + const editedRow = payments.find((payment) => payment.id === id); + if (editedRow?._isNew) { + setPayments((ps) => ps.filter((p) => p.id !== id)); + } + }, + [payments], + ); + + const handleDelete = useCallback( + (id: GridRowId) => () => { + setPayments((ps) => ps.filter((p) => p.id !== id)); + }, + [], + ); + + const handleSave = useCallback( + (id: GridRowId) => () => { + if (validateRow(id)) { + setRowModesModel((model) => ({ + ...model, + [id]: { mode: GridRowModes.View }, + })); + } + }, + [validateRow], + ); + + const handleEditStop = useCallback>( + (params, event) => { + if (!validateRow(params.id)) { + event.defaultMuiPrevented = true; + } + }, + [validateRow], + ); + + const processRowUpdate = useCallback((newRow: GridRowModel) => { + const updatedRow = { ...newRow, _isNew: false }; + setPayments((ps) => ps.map((p) => (p.id === newRow.id ? updatedRow : p))); + return updatedRow; + }, []); + + const columns = useMemo( + () => [ + { + type: "actions", + field: "actions", + headerName: t("Actions"), + getActions: ({ id }) => { + if (rowModesModel[id]?.mode === GridRowModes.Edit) { + return [ + } + label={t("Save")} + onClick={handleSave(id)} + />, + } + label={t("Cancel")} + onClick={handleCancel(id)} + />, + ]; + } + + return [ + } + label={t("Remove")} + onClick={handleDelete(id)} + />, + ]; + }, + }, + { + field: "description", + headerName: t("Payment Milestone Description"), + width: 300, + editable: true, + }, + { + field: "date", + headerName: t("Payment Milestone Date"), + width: 200, + type: "date", + editable: true, + valueGetter(params) { + return new Date(params.value); + }, + }, + { + field: "amount", + headerName: t("Payment Milestone Amount"), + width: 300, + editable: true, + type: "number", + valueFormatter(params) { + return moneyFormatter.format(params.value); + }, + }, + ], + [handleCancel, handleDelete, handleSave, rowModesModel, t], + ); + + useEffect(() => { + const milestones = getValues("milestones"); + setValue("milestones", { + ...milestones, + [taskGroupId]: { + ...milestones[taskGroupId], + payments: payments + .filter((p) => !p._isNew && !p._error) + .map((p) => ({ + description: p.description!, + id: p.id!, + amount: p.amount!, + date: dayjs(p.date!).toISOString(), + })), + }, + }); + }, [getValues, payments, setValue, taskGroupId]); + + return ( + + + {t("Task Stage Milestones")} + + + + + + { + if (!date) return; + const milestones = getValues("milestones"); + setValue("milestones", { + ...milestones, + [taskGroupId]: { + ...milestones[taskGroupId], + startDate: date.toISOString(), + }, + }); + }} + /> + + + + + { + if (!date) return; + const milestones = getValues("milestones"); + setValue("milestones", { + ...milestones, + [taskGroupId]: { + ...milestones[taskGroupId], + endDate: date.toISOString(), + }, + }); + }} + /> + + + + + ({ + marginBlockStart: 1, + marginInline: -3, + borderBottom: `1px solid ${theme.palette.divider}`, + })} + > + { + return params.row._error === params.field ? "hasError" : ""; + }} + slots={{ + footer: FooterToolbar, + noRowsOverlay: NoRowsOverlay, + }} + slotProps={{ + footer: { onAdd: addRow }, + }} + /> + + + ); +}; + +const NoRowsOverlay: React.FC = () => { + const { t } = useTranslation(); + return ( + + + {t("Add some payment milestones!")} + + + ); +}; + +const FooterToolbar: React.FC = ({ onAdd }) => { + const { t } = useTranslation(); + return ( + + + + ); +}; + +export default MilestoneSection; diff --git a/src/components/CreateProject/ProjectClientDetails.tsx b/src/components/CreateProject/ProjectClientDetails.tsx new file mode 100644 index 0000000..610c15f --- /dev/null +++ b/src/components/CreateProject/ProjectClientDetails.tsx @@ -0,0 +1,153 @@ +"use client"; + +import Stack from "@mui/material/Stack"; +import Box from "@mui/material/Box"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import FormControl from "@mui/material/FormControl"; +import Grid from "@mui/material/Grid"; +import InputLabel from "@mui/material/InputLabel"; +import MenuItem from "@mui/material/MenuItem"; +import Select from "@mui/material/Select"; +import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import CardActions from "@mui/material/CardActions"; +import RestartAlt from "@mui/icons-material/RestartAlt"; +import Button from "@mui/material/Button"; +import { useFormContext } from "react-hook-form"; +import { CreateProjectInputs } from "@/app/api/projects/actions"; + +const ProjectClientDetails: React.FC<{ isActive: boolean }> = ({ + isActive, +}) => { + const { t } = useTranslation(); + const { + register, + formState: { errors }, + } = useFormContext(); + + return ( + + + + + {t("Project Details")} + + + + + + + + + + + {t("Project Category")} + + + + + + {t("Team Lead")} + + + + + + + + + + + + {t("Client Details")} + + + + + + + + + + + + + + + + + + + + {t("Client Subsidiary")} + + + + + + + + + + + ); +}; + +export default ProjectClientDetails; diff --git a/src/components/CreateProject/ProjectTotalFee.tsx b/src/components/CreateProject/ProjectTotalFee.tsx new file mode 100644 index 0000000..ead5e71 --- /dev/null +++ b/src/components/CreateProject/ProjectTotalFee.tsx @@ -0,0 +1,47 @@ +import { CreateProjectInputs } from "@/app/api/projects/actions"; +import { TaskGroup } from "@/app/api/tasks"; +import { moneyFormatter } from "@/app/utils/formatUtil"; +import { Divider, Stack, Typography } from "@mui/material"; +import React from "react"; +import { useFormContext } from "react-hook-form"; +import { useTranslation } from "react-i18next"; + +interface Props { + taskGroups: TaskGroup[]; +} + +const ProjectTotalFee: React.FC = ({ taskGroups }) => { + const { t } = useTranslation(); + const { watch } = useFormContext(); + const milestones = watch("milestones"); + + let projectTotal = 0; + + return ( + + {taskGroups.map((group, index) => { + const payments = milestones[group.id]?.payments || []; + const paymentTotal = payments.reduce((acc, p) => acc + p.amount, 0); + projectTotal += paymentTotal; + + return ( + + {group.name} + {moneyFormatter.format(paymentTotal)} + + ); + })} + + + {t("Project Total Fee")} + {moneyFormatter.format(projectTotal)} + + + ); +}; + +export default ProjectTotalFee; diff --git a/src/components/CreateProject/ResourceCapacity.tsx b/src/components/CreateProject/ResourceCapacity.tsx new file mode 100644 index 0000000..ee466f6 --- /dev/null +++ b/src/components/CreateProject/ResourceCapacity.tsx @@ -0,0 +1,139 @@ +import { manhourFormatter } from "@/app/utils/formatUtil"; +import { + Box, + Stack, + Table, + TableBody, + TableCell, + TableContainer, + TableHead, + TableRow, + Typography, +} from "@mui/material"; +import { useMemo } from "react"; +import { useTranslation } from "react-i18next"; + +const mockItems: ResourceItem[] = [ + { + grade: "Grade 1", + title: "A. QS / QS Trainee", + headcount: 20, + totalAvailableManhours: 39520, + loadedManhours: 3760, + remainingAvailableManhours: 35760, + }, + { + grade: "Grade 2", + title: "QS", + headcount: 20, + totalAvailableManhours: 39520, + loadedManhours: 3760, + remainingAvailableManhours: 35760, + }, + { + grade: "Grade 3", + title: "Senior QS", + headcount: 10, + totalAvailableManhours: 19760, + loadedManhours: 1530, + remainingAvailableManhours: 18230, + }, + { + grade: "Grade 4", + title: "A. Manager / Deputy Manager / Manager / S. Manager", + headcount: 5, + totalAvailableManhours: 9880, + loadedManhours: 2760, + remainingAvailableManhours: 7120, + }, + { + grade: "Grade 5", + title: "A. Director / Deputy Director / Director", + headcount: 20, + totalAvailableManhours: 1976, + loadedManhours: 374, + remainingAvailableManhours: 1602, + }, +]; + +interface ResourceColumn { + label: string; + name: keyof ResourceItem; +} + +interface ResourceItem { + grade: string; + title: string; + headcount: number; + totalAvailableManhours: number; + loadedManhours: number; + remainingAvailableManhours: number; +} + +interface Props { + items?: ResourceItem[]; +} + +const ResourceCapacity: React.FC = ({ items = mockItems }) => { + const { t } = useTranslation(); + const columns = useMemo( + () => [ + { label: t("Grade"), name: "grade" }, + { label: t("Title"), name: "title" }, + { label: t("Headcount"), name: "headcount" }, + { label: t("Total Available Manhours"), name: "totalAvailableManhours" }, + { label: t("Loaded Manhours"), name: "loadedManhours" }, + { + label: t("Remaining Available Manhours"), + name: "remainingAvailableManhours", + }, + ], + [t], + ); + + return ( + + + {t("Resource Capacity")} + + + + + + + {columns.map((column, idx) => ( + + {column.label} + + ))} + + + + {items.map((item, index) => { + return ( + + {columns.map((column, idx) => { + const columnName = column.name; + const cellData = item[columnName]; + + return ( + + {columnName !== "headcount" && + typeof cellData === "number" + ? manhourFormatter.format(cellData) + : cellData} + + ); + })} + + ); + })} + +
+
+
+
+ ); +}; + +export default ResourceCapacity; diff --git a/src/components/CreateProject/ResourceMilestone.tsx b/src/components/CreateProject/ResourceMilestone.tsx new file mode 100644 index 0000000..9acf287 --- /dev/null +++ b/src/components/CreateProject/ResourceMilestone.tsx @@ -0,0 +1,128 @@ +"use client"; + +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import Button from "@mui/material/Button"; +import React, { useCallback, useMemo, useState } from "react"; +import CardActions from "@mui/material/CardActions"; +import RestartAlt from "@mui/icons-material/RestartAlt"; +import { + Alert, + FormControl, + InputLabel, + MenuItem, + Select, + SelectChangeEvent, +} from "@mui/material"; +import { Task, TaskGroup } from "@/app/api/tasks"; +import uniqBy from "lodash/uniqBy"; +import { useFormContext } from "react-hook-form"; +import { CreateProjectInputs } from "@/app/api/projects/actions"; +import MilestoneSection from "./MilestoneSection"; +import ResourceSection from "./ResourceSection"; +import ProjectTotalFee from "./ProjectTotalFee"; + +export interface Props { + allTasks: Task[]; + defaultManhourBreakdownByGrade?: { [gradeId: number]: number }; + isActive: boolean; +} + +const ResourceMilestone: React.FC = ({ + allTasks, + defaultManhourBreakdownByGrade, + isActive, +}) => { + const { t } = useTranslation(); + const { getValues } = useFormContext(); + const tasks = useMemo(() => { + return allTasks.filter((task) => getValues("tasks")[task.id]); + }, [allTasks, getValues]); + + const taskGroups = useMemo(() => { + return uniqBy( + tasks.map((task) => task.taskGroup), + "id", + ); + }, [tasks]); + const [currentTaskGroupId, setCurrentTaskGroupId] = useState( + taskGroups[0].id, + ); + const [currentTasks, setCurrentTasks] = useState( + tasks.filter((t) => t.taskGroup.id === currentTaskGroupId), + ); + const onSelectTaskGroup = useCallback( + (event: SelectChangeEvent) => { + const id = event.target.value; + const newTaksGroupId = typeof id === "string" ? parseInt(id) : id; + setCurrentTaskGroupId(newTaksGroupId); + setCurrentTasks(tasks.filter((t) => t.taskGroup.id === newTaksGroupId)); + }, + [tasks], + ); + + return ( + <> + + + + {t("Task Stage")} + + + + + + + + + + + + + + + + ); +}; + +const NoTaskState: React.FC> = ({ isActive }) => { + const { t } = useTranslation(); + return ( + + + + {t('Please add some tasks in "Project Task Setup" first!')} + + + + ); +}; + +const ResourceMilestoneWrapper: React.FC = (props) => { + const { getValues } = useFormContext(); + + if (Object.keys(getValues("tasks")).length === 0) { + return ; + } + + return ; +}; + +export default ResourceMilestoneWrapper; diff --git a/src/components/CreateProject/ResourceSection.tsx b/src/components/CreateProject/ResourceSection.tsx new file mode 100644 index 0000000..9b60fc1 --- /dev/null +++ b/src/components/CreateProject/ResourceSection.tsx @@ -0,0 +1,226 @@ +import { Task } from "@/app/api/tasks"; +import { + Box, + Typography, + Grid, + Paper, + List, + ListItemButton, + ListItemText, + TextField, +} from "@mui/material"; +import { useState, useCallback, useEffect, useMemo } from "react"; +import { useTranslation } from "react-i18next"; +import { Props as ResourceMilestoneProps } from "./ResourceMilestone"; +import StyledDataGrid from "../StyledDataGrid"; +import { useForm, useFormContext } from "react-hook-form"; +import { GridColDef, GridRowModel, useGridApiRef } from "@mui/x-data-grid"; +import { + CreateProjectInputs, + ManhourAllocation, +} from "@/app/api/projects/actions"; +import isEmpty from "lodash/isEmpty"; +import _reduce from "lodash/reduce"; + +const mockGrades = [1, 2, 3, 4, 5]; + +interface Props { + tasks: Task[]; + manhourBreakdownByGrade: ResourceMilestoneProps["defaultManhourBreakdownByGrade"]; +} + +type Row = ManhourAllocation & { id: "manhourAllocation" }; + +const parseValidManhours = (value: number | string): number => { + const inputNumber = Number(value); + return isNaN(inputNumber) || inputNumber < 0 ? 0 : inputNumber; +}; + +const ResourceSection: React.FC = ({ + tasks, + manhourBreakdownByGrade = mockGrades.reduce< + NonNullable + >((acc, grade) => { + return { ...acc, [grade]: 1 }; + }, {}), +}) => { + const { t } = useTranslation(); + const [selectedTaskId, setSelectedTaskId] = useState(tasks[0].id); + const makeOnTaskSelect = useCallback( + (taskId: Task["id"]): React.MouseEventHandler => + () => { + return setSelectedTaskId(taskId); + }, + [], + ); + + useEffect(() => { + setSelectedTaskId(tasks[0].id); + }, [tasks]); + + const { getValues, setValue } = useFormContext(); + + const updateTaskAllocations = useCallback( + (newAllocations: ManhourAllocation) => { + setValue("tasks", { + ...getValues("tasks"), + [selectedTaskId]: { + manhourAllocation: newAllocations, + }, + }); + }, + [getValues, selectedTaskId, setValue], + ); + + const gridApiRef = useGridApiRef(); + const columns = useMemo(() => { + return mockGrades.map((grade) => ({ + field: grade.toString(), + editable: true, + sortable: false, + width: 120, + headerName: t("Grade {{grade}}", { grade }), + type: "number", + valueParser: parseValidManhours, + valueFormatter(params) { + return Number(params.value).toFixed(2); + }, + })); + }, [t]); + + const rows = useMemo(() => { + const initialAllocation = + getValues("tasks")[selectedTaskId].manhourAllocation; + if (!isEmpty(initialAllocation)) { + return [{ ...initialAllocation, id: "manhourAllocation" }]; + } + return [ + mockGrades.reduce( + (acc, grade) => { + return { ...acc, [grade]: 0 }; + }, + { id: "manhourAllocation" }, + ), + ]; + }, [getValues, selectedTaskId]); + + const initialManhours = useMemo(() => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { id, ...allocations } = rows[0]; + return Object.values(allocations).reduce((acc, hours) => acc + hours, 0); + }, [rows]); + + const { + register, + reset, + getValues: getManhourFormValues, + setValue: setManhourFormValue, + } = useForm<{ manhour: number }>({ + defaultValues: { + manhour: initialManhours, + }, + }); + + // Reset man hour input when task changes + useEffect(() => { + reset({ manhour: initialManhours }); + }, [initialManhours, reset, selectedTaskId]); + + const updateAllocation = useCallback(() => { + const inputHour = getManhourFormValues("manhour"); + const ratioSum = Object.values(manhourBreakdownByGrade).reduce( + (acc, ratio) => acc + ratio, + 0, + ); + const newAllocations = _reduce( + manhourBreakdownByGrade, + (acc, value, key) => { + return { ...acc, [key]: (inputHour / ratioSum) * value }; + }, + {}, + ); + gridApiRef.current.updateRows([ + { id: "manhourAllocation", ...newAllocations }, + ]); + updateTaskAllocations(newAllocations); + }, [ + getManhourFormValues, + gridApiRef, + manhourBreakdownByGrade, + updateTaskAllocations, + ]); + + const processRowUpdate = useCallback( + (newRow: GridRowModel) => { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { id: rowId, ...newAllocations } = newRow; + const totalHours = Object.values( + newAllocations as ManhourAllocation, + ).reduce((acc, hour) => acc + hour, 0); + setManhourFormValue("manhour", totalHours); + updateTaskAllocations(newAllocations); + return newRow; + }, + [setManhourFormValue, updateTaskAllocations], + ); + + return ( + + + {t("Task Breakdown")} + + + + + + {tasks.map((task, index) => { + return ( + + + + ); + })} + + + + + + + + + + + + ); +}; + +export default ResourceSection; diff --git a/src/components/CreateProject/StaffAllocation.tsx b/src/components/CreateProject/StaffAllocation.tsx new file mode 100644 index 0000000..f55dc5d --- /dev/null +++ b/src/components/CreateProject/StaffAllocation.tsx @@ -0,0 +1,334 @@ +"use client"; + +import { useTranslation } from "react-i18next"; +import React, { useEffect } from "react"; +import RestartAlt from "@mui/icons-material/RestartAlt"; +import SearchResults, { Column } from "../SearchResults"; +import { Search, Clear, PersonAdd, PersonRemove } from "@mui/icons-material"; +import { + Stack, + Typography, + Grid, + TextField, + InputAdornment, + IconButton, + FormControl, + InputLabel, + Select, + MenuItem, + Box, + Button, + Card, + CardActions, + CardContent, + TabsProps, + Tab, + Tabs, + SelectChangeEvent, +} from "@mui/material"; +import differenceBy from "lodash/differenceBy"; +import uniq from "lodash/uniq"; +import ResourceCapacity from "./ResourceCapacity"; +import { useFormContext } from "react-hook-form"; +import { CreateProjectInputs } from "@/app/api/projects/actions"; + +interface StaffResult { + id: number; + name: string; + team: string; + grade: string; + title: string; +} + +const mockStaffs: StaffResult[] = [ + { + name: "Albert", + grade: "1", + id: 1, + team: "ABC", + title: "Associate Quantity Surveyor", + }, + { + name: "Bernard", + grade: "2", + id: 2, + team: "ABC", + title: "Quantity Surveyor", + }, + { + name: "Carl", + grade: "3", + id: 3, + team: "XYZ", + title: "Senior Quantity Surveyor", + }, + { name: "Denis", grade: "4", id: 4, team: "ABC", title: "Manager" }, + { name: "Edward", grade: "5", id: 5, team: "ABC", title: "Director" }, + { name: "Fred", grade: "1", id: 6, team: "XYZ", title: "General Laborer" }, + { name: "Gordon", grade: "2", id: 7, team: "ABC", title: "Inspector" }, + { + name: "Heather", + grade: "3", + id: 8, + team: "XYZ", + title: "Field Engineer", + }, + { name: "Ivan", grade: "4", id: 9, team: "ABC", title: "Senior Manager" }, + { + name: "Jackson", + grade: "5", + id: 10, + team: "XYZ", + title: "Senior Director", + }, + { + name: "Kurt", + grade: "1", + id: 11, + team: "ABC", + title: "Construction Assistant", + }, + { name: "Lawrence", grade: "2", id: 12, team: "ABC", title: "Operator" }, +]; + +interface Props { + allStaff?: StaffResult[]; + isActive: boolean; +} + +const StaffAllocation: React.FC = ({ + allStaff = mockStaffs, + isActive, +}) => { + const { t } = useTranslation(); + const { setValue, getValues } = useFormContext(); + + const [filteredStaff, setFilteredStaff] = React.useState(allStaff); + const [selectedStaff, setSelectedStaff] = React.useState< + typeof filteredStaff + >( + allStaff.filter((staff) => + getValues("allocatedStaffIds").includes(staff.id), + ), + ); + + // Adding / Removing staff + const addStaff = React.useCallback((staff: StaffResult) => { + setSelectedStaff((staffs) => [...staffs, staff]); + }, []); + const removeStaff = React.useCallback((staff: StaffResult) => { + setSelectedStaff((staffs) => staffs.filter((s) => s.id !== staff.id)); + }, []); + const clearStaff = React.useCallback(() => { + setSelectedStaff([]); + }, []); + // Sync with form + useEffect(() => { + setValue( + "allocatedStaffIds", + selectedStaff.map((staff) => staff.id), + ); + }, [selectedStaff, setValue]); + + const staffPoolColumns = React.useMemo[]>( + () => [ + { + label: t("Add"), + name: "id", + onClick: addStaff, + buttonIcon: , + }, + { label: t("Staff ID"), name: "id" }, + { label: t("Staff Name"), name: "name" }, + { label: t("Team"), name: "team" }, + { label: t("Grade"), name: "grade" }, + { label: t("Title"), name: "title" }, + ], + [addStaff, t], + ); + + const allocatedStaffColumns = React.useMemo[]>( + () => [ + { + label: t("Remove"), + name: "id", + onClick: removeStaff, + buttonIcon: , + }, + { label: t("Staff ID"), name: "id" }, + { label: t("Staff Name"), name: "name" }, + { label: t("Team"), name: "team" }, + { label: t("Grade"), name: "grade" }, + { label: t("Title"), name: "title" }, + ], + [removeStaff, t], + ); + + // Query related + const [query, setQuery] = React.useState(""); + const onQueryInputChange = React.useCallback< + React.ChangeEventHandler + >((e) => { + setQuery(e.target.value); + }, []); + const clearQueryInput = React.useCallback(() => { + setQuery(""); + }, []); + const columnFilters = React.useMemo<(keyof StaffResult)[]>( + () => ["team", "grade"], + [], + ); + const filterValues = React.useMemo(() => { + return columnFilters.reduce<{ [filter in keyof StaffResult]?: string[] }>( + (acc, filter) => { + return { + ...acc, + [filter]: uniq(allStaff.map((staff) => staff[filter])), + }; + }, + {}, + ); + }, [columnFilters, allStaff]); + const defaultFilterValues = React.useMemo(() => { + return columnFilters.reduce<{ [filter in keyof StaffResult]?: string }>( + (acc, filter) => { + return { ...acc, [filter]: "All" }; + }, + {}, + ); + }, [columnFilters]); + const [filters, setFilters] = React.useState(defaultFilterValues); + const makeFilterSelect = React.useCallback( + (filter: keyof StaffResult) => (event: SelectChangeEvent) => { + setFilters((f) => ({ ...f, [filter]: event.target.value })); + }, + [], + ); + + React.useEffect(() => { + setFilteredStaff( + allStaff.filter((staff) => { + const q = query.toLowerCase(); + return ( + (staff.name.toLowerCase().includes(q) || + staff.id.toString().includes(q) || + staff.title.toLowerCase().includes(q)) && + Object.entries(filters).every(([filterKey, filterValue]) => { + const staffColumnValue = staff[filterKey as keyof StaffResult]; + return staffColumnValue === filterValue || filterValue === "All"; + }) + ); + }), + ); + }, [allStaff, filters, query]); + + // Tab related + const [tabIndex, setTabIndex] = React.useState(0); + const handleTabChange = React.useCallback>( + (_e, newValue) => { + setTabIndex(newValue); + }, + [], + ); + + const reset = React.useCallback(() => { + clearQueryInput(); + clearStaff(); + setFilters(defaultFilterValues); + }, [clearQueryInput, clearStaff, defaultFilterValues]); + + return ( + <> + + + + + {t("Staff Allocation")} + + + + + + + + + + ), + }} + /> + + {columnFilters.map((filter, idx) => { + const label = staffPoolColumns.find( + (c) => c.name === filter, + )!.label; + + return ( + + + {label} + + + + ); + })} + + + + + + + {tabIndex === 0 && ( + + )} + {tabIndex === 1 && ( + + )} + + + + + + + + + + + + + + ); +}; + +export default StaffAllocation; diff --git a/src/components/CreateProject/TaskSetup.tsx b/src/components/CreateProject/TaskSetup.tsx new file mode 100644 index 0000000..41fa76a --- /dev/null +++ b/src/components/CreateProject/TaskSetup.tsx @@ -0,0 +1,97 @@ +"use client"; + +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Grid from "@mui/material/Grid"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import TransferList from "../TransferList"; +import Button from "@mui/material/Button"; +import React, { useMemo } from "react"; +import CardActions from "@mui/material/CardActions"; +import RestartAlt from "@mui/icons-material/RestartAlt"; +import FormControl from "@mui/material/FormControl"; +import Select from "@mui/material/Select"; +import MenuItem from "@mui/material/MenuItem"; +import InputLabel from "@mui/material/InputLabel"; +import { Task } from "@/app/api/tasks"; +import { useFormContext } from "react-hook-form"; +import { CreateProjectInputs } from "@/app/api/projects/actions"; + +interface Props { + allTasks: Task[]; + isActive: boolean; +} + +const TaskSetup: React.FC = ({ allTasks: tasks, isActive }) => { + const { t } = useTranslation(); + const { getValues, setValue } = useFormContext(); + const currentTasks = getValues("tasks"); + + const items = useMemo( + () => tasks.map((t) => ({ id: t.id, label: t.name, group: t.taskGroup })), + [tasks], + ); + const selectedItems = useMemo(() => { + return tasks + .filter((t) => currentTasks[t.id]) + .map((t) => ({ id: t.id, label: t.name, group: t.taskGroup })); + }, [currentTasks, tasks]); + + return ( + + + + {t("Task List Setup")} + + + + + {t("Task List Source")} + + + + + { + const newTasks = selectedTasks.reduce( + (acc, item) => { + // Reuse the task from currentTasks if present + return { + ...acc, + [item.id]: currentTasks[item.id] ?? { manhourAllocation: {} }, + }; + }, + {}, + ); + + setValue("tasks", newTasks); + }} + allItemsLabel={t("Task Pool")} + selectedItemsLabel={t("Project Task List")} + /> + + + + + + ); +}; + +export default TaskSetup; diff --git a/src/components/CreateProject/index.ts b/src/components/CreateProject/index.ts new file mode 100644 index 0000000..6332185 --- /dev/null +++ b/src/components/CreateProject/index.ts @@ -0,0 +1 @@ +export { default } from "./CreateProjectWrapper"; diff --git a/src/components/CreateTaskTemplate/CreateTaskTemplate.tsx b/src/components/CreateTaskTemplate/CreateTaskTemplate.tsx new file mode 100644 index 0000000..2f5543e --- /dev/null +++ b/src/components/CreateTaskTemplate/CreateTaskTemplate.tsx @@ -0,0 +1,137 @@ +"use client"; + +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Grid from "@mui/material/Grid"; +import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; +import { useTranslation } from "react-i18next"; +import TransferList from "../TransferList"; +import Button from "@mui/material/Button"; +import Check from "@mui/icons-material/Check"; +import Close from "@mui/icons-material/Close"; +import { useRouter } from "next/navigation"; +import React from "react"; +import Stack from "@mui/material/Stack"; +import { Task } from "@/app/api/tasks"; +import { + NewTaskTemplateFormInputs, + saveTaskTemplate, +} from "@/app/api/tasks/actions"; +import { SubmitHandler, useForm } from "react-hook-form"; + +interface Props { + tasks: Task[]; +} + +const CreateTaskTemplate: React.FC = ({ tasks }) => { + const { t } = useTranslation(); + + const router = useRouter(); + const handleCancel = () => { + router.back(); + }; + + const items = React.useMemo( + () => + tasks.map((task) => ({ + id: task.id, + label: task.name, + group: task.taskGroup || undefined, + })), + [tasks], + ); + + const [serverError, setServerError] = React.useState(""); + + const { + register, + handleSubmit, + setValue, + formState: { errors, isSubmitting }, + } = useForm(); + + const onSubmit: SubmitHandler = React.useCallback( + async (data) => { + try { + setServerError(""); + await saveTaskTemplate(data); + router.replace("/tasks"); + } catch (e) { + setServerError(t("An error has occurred. Please try again later.")); + } + }, + [router, t], + ); + + return ( + + + + {t("Task List Setup")} + + + + + + + + + { + setValue( + "taskIds", + selectedItems.map((item) => item.id), + ); + }} + allItemsLabel={t("Task Pool")} + selectedItemsLabel={t("Task List Template")} + /> + + + {serverError && ( + + {serverError} + + )} + + + + + + ); +}; + +export default CreateTaskTemplate; diff --git a/src/components/CreateTaskTemplate/CreateTaskTemplateWrapper.tsx b/src/components/CreateTaskTemplate/CreateTaskTemplateWrapper.tsx new file mode 100644 index 0000000..77888a2 --- /dev/null +++ b/src/components/CreateTaskTemplate/CreateTaskTemplateWrapper.tsx @@ -0,0 +1,11 @@ +import React from "react"; +import CreateTaskTemplate from "./CreateTaskTemplate"; +import { fetchAllTasks } from "@/app/api/tasks"; + +const CreateTaskTemplateWrapper: React.FC = async () => { + const tasks = await fetchAllTasks(); + + return ; +}; + +export default CreateTaskTemplateWrapper; diff --git a/src/components/CreateTaskTemplate/index.ts b/src/components/CreateTaskTemplate/index.ts new file mode 100644 index 0000000..e52ead3 --- /dev/null +++ b/src/components/CreateTaskTemplate/index.ts @@ -0,0 +1 @@ +export { default } from "./CreateTaskTemplateWrapper"; diff --git a/src/components/CustomCardGrid/CustomCardGrid.tsx b/src/components/CustomCardGrid/CustomCardGrid.tsx new file mode 100644 index 0000000..22454a2 --- /dev/null +++ b/src/components/CustomCardGrid/CustomCardGrid.tsx @@ -0,0 +1,240 @@ +import * as React from "react"; +import { + Card, + CardHeader, + CardContent, + SxProps, + Theme, + Grid, +} from "@mui/material"; +import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { PROJECT_CARD_STYLE } from "@/theme/colorConst"; +import { useRef, useEffect, useState } from "react"; +import Swal from "sweetalert2"; +import styledcmp from "styled-components"; + +const CardWrapper = styledcmp.div` + /* Styles for the card when not hovered */ + background-color: #f0f0f0; + padding: 10px; + /* ...other styles... */ + + &:hover { + /* Styles for the card when hovered */ + background-color: #c0c0c0; + /* ...other hover styles... */ + } +`; + +interface CustomCardGridProps { + Title?: string; + cardsPerRow?: number; + rows?: any[]; + columns?: any[]; + items: any[]; + columnWidth?: number; + Style?: boolean; + sx?: SxProps; + dataGridHeight?: number; + cardStyle?: any; + [key: string]: any; +} + +const CustomCardGrid: React.FC = ({ + Title, + rows, + items, + columns, + columnWidth, + cardsPerRow = 4, + Style = true, + sx, + dataGridHeight, + ...props +}) => { + const getBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7); + + const getHoverBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6); + + const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5); + + const getSelectedHoverBackgroundColor = ( + color: string, + mode: "light" | "dark", + ) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4)); + + const StyledCard = styled(Card)(({ theme }) => ({ + "& .super-app-theme--Open": { + backgroundColor: getBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--finish": { + backgroundColor: getBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--danger": { + backgroundColor: getBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--warning": { + backgroundColor: getBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + }, + }, + })); + + const CardItem = (item: any) => { + const cardItem = item.item as Record; + return ( + props.cardStyle ?? ( + // + + + {Object.keys(cardItem).map((key) => ( +

+ {key}: {cardItem[key]} +

+ ))} +
+
+ //
+ ) + ); + }; + + const containerRef = useRef(null!); + + const [cardMargin, setCardMargin] = useState(1.5); + + useEffect(() => { + console.log(CardItem); + const resizeHandler = () => { + const containerWidth = containerRef.current.offsetWidth; + const cardCount = items.length; + const rootSize = parseFloat( + getComputedStyle(document.documentElement).fontSize, + ); + setCardMargin( + (containerWidth - + cardsPerRow * + (rootSize * parseInt(PROJECT_CARD_STYLE.width.slice(0, -3), 10))) / + (2 * cardsPerRow), + ); + // Set the cardMargin value using style={{margin: `${cardMargin}px`, ...PROJECT_CARD_STYLE}} + }; + + window.addEventListener("resize", resizeHandler); + + resizeHandler(); // Initial calculation + + // Swal.fire({ + // title: 'Error! ', + // text: `Card Count is ${items.length}`, + // icon: 'success', + // confirmButtonText: 'Jus Cool' + // }) + + return () => { + window.removeEventListener("resize", resizeHandler); + }; + }, [items]); + + return ( +
+ {/*

width is {containerRef.current == null? "idk":containerRef.current.offsetWidth}, margin is {cardMargin}

*/} + {items.map((item, index) => ( +
+ {props.cardStyle ? props.cardStyle(item) : } +
+ ))} +
+ ); +}; + +export default CustomCardGrid; diff --git a/src/components/CustomCardGrid/index.ts b/src/components/CustomCardGrid/index.ts new file mode 100644 index 0000000..b051fef --- /dev/null +++ b/src/components/CustomCardGrid/index.ts @@ -0,0 +1 @@ +export { default } from "./CustomCardGrid"; diff --git a/src/components/CustomDatagrid/CustomDatagrid.tsx b/src/components/CustomDatagrid/CustomDatagrid.tsx new file mode 100644 index 0000000..151e90d --- /dev/null +++ b/src/components/CustomDatagrid/CustomDatagrid.tsx @@ -0,0 +1,309 @@ +"use client"; +import * as React from "react"; +import { Card, CardHeader, CardContent, SxProps, Theme } from "@mui/material"; +import { DataGrid, GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { useState } from "react"; + +interface CustomDatagridProps { + Title?: string; + rows: any[]; + columns: any[]; + columnWidth?: number; + Style?: boolean; + sx?: SxProps; + dataGridHeight?: number; + [key: string]: any; + checkboxSelection?: boolean; + onRowSelectionModelChange?: ( + newSelectionModel: GridRowSelectionModel, + ) => void; + selectionModel?: any; +} + +const CustomDatagrid: React.FC = ({ + Title, + rows, + columns, + columnWidth, + Style = false, + sx, + dataGridHeight, + checkboxSelection, // Destructure the new prop + onRowSelectionModelChange, // Destructure the new prop + selectionModel, + ...props +}) => { + const modifiedColumns = columns.map((column) => { + return { + ...column, + width: columnWidth ?? 150, + }; + }); + + const rowsWithDefaultValues = rows.map((row) => { + return { ...row }; + }); + + // Event handler to be called when the selection changes + const handleSelectionModelChange = ( + newSelectionModel: GridRowSelectionModel, + ) => { + // setSelectionModel(newSelectionModel); + // To log selected row data, filter rows based on the new selection model + const selectedRowsData = rows.filter((row) => + newSelectionModel.includes(row.id), + ); + console.log(selectedRowsData); + }; + + const getBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.7) : lighten(color, 0.7); + + const getHoverBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.6) : lighten(color, 0.6); + + const getSelectedBackgroundColor = (color: string, mode: "light" | "dark") => + mode === "dark" ? darken(color, 0.5) : lighten(color, 0.5); + + const getSelectedHoverBackgroundColor = ( + color: string, + mode: "light" | "dark", + ) => (mode === "dark" ? darken(color, 0.4) : lighten(color, 0.4)); + + const StyledDataGrid = styled(DataGrid)(({ theme }) => ({ + "& .super-app-theme--Open": { + backgroundColor: getBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.info.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--finish": { + backgroundColor: getBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.success.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--danger": { + backgroundColor: getBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.warning.main, + theme.palette.mode, + ), + }, + }, + }, + "& .super-app-theme--warning": { + backgroundColor: getBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + "&.Mui-selected": { + backgroundColor: getSelectedBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + "&:hover": { + backgroundColor: getSelectedHoverBackgroundColor( + theme.palette.error.main, + theme.palette.mode, + ), + }, + }, + }, + })); + + return ( +
+ {Title ? ( + + {Title && } + + {Style ? ( + + ) : ( + + )} + + + ) : Style ? ( + + ) : ( + + )} +
+ ); +}; + +export default CustomDatagrid; diff --git a/src/components/CustomDatagrid/index.ts b/src/components/CustomDatagrid/index.ts new file mode 100644 index 0000000..d34e5f0 --- /dev/null +++ b/src/components/CustomDatagrid/index.ts @@ -0,0 +1 @@ +export { default } from "./CustomDatagrid"; diff --git a/src/components/CustomModal/CustomModal.tsx b/src/components/CustomModal/CustomModal.tsx new file mode 100644 index 0000000..1004213 --- /dev/null +++ b/src/components/CustomModal/CustomModal.tsx @@ -0,0 +1,81 @@ +import * as React from "react"; +import { + Card, + CardHeader, + CardContent, + SxProps, + Theme, + Grid, + Modal, + Typography, + Button, +} from "@mui/material"; +import { DataGrid, GridColDef } from "@mui/x-data-grid"; +import { darken, lighten, styled } from "@mui/material/styles"; +import { PROJECT_MODAL_STYLE } from "@/theme/colorConst"; +import { useRef, useEffect, useState } from "react"; +import Swal from "sweetalert2"; +import styledcmp from "styled-components"; + +const CardWrapper = styledcmp.div` + /* Styles for the card when not hovered */ + background-color: #f0f0f0, + padding: 10px, + /* ...other styles... */ + + &:hover { + /* Styles for the card when hovered */ + background-color: #c0c0c0, + /* ...other hover styles... */ + } +`; + +interface CustomModalProps { + title?: string; + isOpen: boolean; + onClose: () => void; + modalStyle?: any; +} + +const CustomModal: React.FC = ({ ...props }) => { + const ModalContent = () => { + return ( + // +
+ + {props.title ?? "Modal Title"} + + + Modal Content + +
+ + +
+
+ //
+ ); + }; + + return ( + + {props.modalStyle ? : } + + ); +}; + +export default CustomModal; diff --git a/src/components/CustomModal/index.ts b/src/components/CustomModal/index.ts new file mode 100644 index 0000000..f13c96c --- /dev/null +++ b/src/components/CustomModal/index.ts @@ -0,0 +1 @@ +export { default } from "./CustomModal"; diff --git a/src/components/CustomSearchForm/CustomSearchForm.tsx b/src/components/CustomSearchForm/CustomSearchForm.tsx new file mode 100644 index 0000000..c005887 --- /dev/null +++ b/src/components/CustomSearchForm/CustomSearchForm.tsx @@ -0,0 +1,379 @@ +"use client"; +import React, { useState, FC } from "react"; +import { + Stack, + Typography, + FormControlLabel, + Checkbox, + Autocomplete, + Button, + Grid, + TextField, + CardHeader, + Card, + FormControl, + InputLabel, + Select, + MenuItem, + ThemeProvider, +} from "@mui/material"; +import { useForm, Controller } from "react-hook-form"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import SearchIcon from "@mui/icons-material/Search"; +import RefreshIcon from "@mui/icons-material/Refresh"; +import { DemoItem } from "@mui/x-date-pickers/internals/demo"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; + +interface Field { + id: any; + label: any; + type: string; + options?: Array<{ id: string; label: string }>; + setValue: ((value: any) => void) | Array<(value: any) => void>; + value?: any; + required?: boolean; +} + +interface FormComponentProps { + fields: Field[]; + onSubmit: (data: any) => void; + resetForm: () => void; + sx?: any; +} + +interface SearchFormProps { + applySearch: (data: any) => void; + fields: Field[]; + title?: string; + sx?: any; +} + +const FormComponent: FC = ({ + fields, + onSubmit, + resetForm, + sx, +}) => { + const { reset, register, handleSubmit, control } = useForm(); + const [fromDate, setFromDate] = useState(null); + const [dayRangeFromDate, setDayRangeFromDate] = useState( + null, + ); + const [dayRangeToDate, setDayRangeToDate] = useState( + null, + ); + const [value, setValue] = useState<{ [key: string]: any }>({}); + const [checkbox1, setCheckbox1] = useState(false); + + const handleFormSubmit = (data: any) => { + if (fromDate != null || fromDate != undefined) { + data.fromDate = dayjs(fromDate).format("YYYY-MM-DD"); + } + if (value !== null) { + data.dropdownCombo = value; + } + if (value !== null) { + data.checkbox = checkbox1; + } + if (dayRangeFromDate != null || dayRangeFromDate != undefined) { + data.dayRangeFromDate = dayjs(dayRangeFromDate).format("YYYY-MM-DD"); + } + if (dayRangeToDate != null || dayRangeToDate != undefined) { + data.dayRangeToDate = dayjs(dayRangeToDate).format("YYYY-MM-DD"); + } + onSubmit(data); + }; + + const handleFormReset = () => { + reset(); + resetForm(); + setFromDate(null); + fields.forEach((field) => { + if (typeof field.setValue === "function") { + field.setValue(typeof field.value === "boolean" ? false : null); + } else if (Array.isArray(field.setValue)) { + field.setValue.forEach((setFunc) => { + setFunc(null); + }); + } + }); + }; + + return ( +
+ + {fields.map((field) => { + if (field.type === "dropdown") { + return ( + + + + {field.label} + + ( + + )} + /> + + + ); + } else if (field.type === "date") { + return ( + + + + { + setFromDate(newValue); + }} + /> + + + + ); + } else if (field.type === "checkbox") { + return ( + + { + if (typeof field.setValue === "function") { + field.setValue(event.target.checked); + setCheckbox1(event.target.checked); + } + }} + color="primary" + /> + } + label={ + + {field.label} + + } + /> + + ); + } else if (field.type === "dateRange") { + return ( + + + + + + setDayRangeFromDate(newValue)} + /> + + + + + To + + + + + setDayRangeToDate(newValue)} + /> + + + + + + ); + } + return ( + + + + ); + })} + + + + + + + + + + + +
+ ); +}; + +const CustomSearchForm: FC = ({ + applySearch, + fields, + title, + sx, +}) => { + const Title = title || "Searching Criteria"; + + const handleSubmit = (data: any) => { + if (applySearch) { + applySearch(data); + } else { + console.log("applySearch function is null"); + } + }; + + const handleFormReset = () => { + console.log("Form Reset"); + }; + + return ( + + + + + ); +}; + +export default CustomSearchForm; diff --git a/src/components/CustomSearchForm/index.ts b/src/components/CustomSearchForm/index.ts new file mode 100644 index 0000000..51718f8 --- /dev/null +++ b/src/components/CustomSearchForm/index.ts @@ -0,0 +1 @@ +export { default } from "./CustomSearchForm"; diff --git a/src/components/DashboardPage/DashboardPage.tsx b/src/components/DashboardPage/DashboardPage.tsx new file mode 100644 index 0000000..d3d70c7 --- /dev/null +++ b/src/components/DashboardPage/DashboardPage.tsx @@ -0,0 +1,51 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import PageTitle from "../PageTitle/PageTitle"; +import DashboardTabButton from "./DashboardTabButton"; +import { ThemeProvider } from "@mui/material/styles"; +import theme from "../../theme"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import React, { useCallback, useState } from "react"; +import { useRouter } from "next/navigation"; +import ProgressByClient from "./ProgressByClient"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; + +const DashboardPage: React.FC = () => { + const [tabIndex, setTabIndex] = useState(0); + const { t } = useTranslation("dashboard"); + const router = useRouter(); + const handleCancel = () => { + router.back(); + }; + const handleTabChange = useCallback>( + (_e, newValue) => { + setTabIndex(newValue); + }, + [], + ); + return ( + + + + + + + + + {tabIndex === 2 && } + {/* + + + + + */} + + ); +}; + +export default DashboardPage; diff --git a/src/components/DashboardPage/DashboardTabButton.tsx b/src/components/DashboardPage/DashboardTabButton.tsx new file mode 100644 index 0000000..1f95098 --- /dev/null +++ b/src/components/DashboardPage/DashboardTabButton.tsx @@ -0,0 +1,77 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import { useState, useCallback } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import PageTitle from "../PageTitle/PageTitle"; +import ProgressByClient from "./ProgressByClient"; +import Tabs, { TabsProps } from "@mui/material/Tabs"; +import Tab from "@mui/material/Tab"; +import "../../app/global.css"; + +const DashboardTabButton: React.FC = () => { + const [activeTab, setActiveTab] = useState("financialSummary"); + const { t } = useTranslation("dashboard"); + const renderContent = () => { + switch (activeTab) { + case "financialSummary": + return
Project Financial Summary
; + case "cashFlow": + return
Project Cash Flow
; + case "progressByClient": + return ; + case "resourceUtilization": + return
Project Resource Utilization
; + case "staffUtilization": + return
Staff Utilization
; + default: + return
Project Financial Summary
; + } + }; + const [tabIndex, setTabIndex] = useState(0); + const handleTabChange = useCallback>( + (_e, newValue) => { + setTabIndex(newValue); + }, + [], + ); + return ( + // + //
+ // {activeTab !== 'financialSummary' ? + // : + // + // } + // {activeTab !== 'cashFlow' ? + // : + // + // } + // {activeTab !== 'progressByClient' ? + // : + // + // } + // {activeTab !== 'resourceUtilization' ? + // : + // + // } + // {activeTab !== 'staffUtilization' ? + // : + // + // } + //
+ //
+ // {renderContent()} + //
+ //
+ + + + + + + + ); +}; + +export default DashboardTabButton; diff --git a/src/components/DashboardPage/ProgressByClient.tsx b/src/components/DashboardPage/ProgressByClient.tsx new file mode 100644 index 0000000..6475c03 --- /dev/null +++ b/src/components/DashboardPage/ProgressByClient.tsx @@ -0,0 +1,493 @@ +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; + +const ProgressByClient: React.FC = () => { + const [activeTab, setActiveTab] = useState("financialSummary"); + const [SearchCriteria, setSearchCriteria] = React.useState({}); + const { t } = useTranslation("dashboard"); + + const [clientCode, setClientCode] = useState(""); + const [clientName, setClientName] = useState(""); + const [subsidiaryClientCode, setSubsidiaryClientCode] = useState(""); + const [subsidiaryClientName, setSubsidiaryClientName] = useState(""); + const [projectArray, setProjectArray]: any[] = useState([]); + const [percentageArray, setPercentageArray]: any[] = useState([]); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [dropdownDemo, setDropdownDemo] = useState(""); + const [dateDemo, setDateDemo] = useState(null); + const [checkboxDemo, setCheckboxDemo] = useState(false); + const [receiptFromDate, setReceiptFromDate] = useState(null); + const [receiptToDate, setReceiptToDate] = useState(null); + const [selectedRows, setSelectedRows] = useState([]); + const rows = [ + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "N/A", + clientSubsidiaryName: "N/A", + noOfProjects: "5", + }, + { + id: 2, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-001", + clientSubsidiaryName: "Subsidiary A", + noOfProjects: "5", + }, + { + id: 3, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-002", + clientSubsidiaryName: "Subsidiary B", + noOfProjects: "3", + }, + { + id: 4, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-003", + clientSubsidiaryName: "Subsidiary C", + noOfProjects: "1", + }, + ]; + const rows2 = [ + { + id: 1, + project: "Consultancy Project 123", + team: "XXX", + teamLeader: "XXX", + currentStage: "Contract Documentation", + budgetedManhour: "200.00", + spentManhour: "120.00", + remainedManhour: "80.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + }, + { + id: 2, + project: "Consultancy Project 456", + team: "XXX", + teamLeader: "XXX", + currentStage: "Report Preparation", + budgetedManhour: "400.00", + spentManhour: "200.00", + remainedManhour: "200.00", + comingPaymentMilestone: "20/02/2024", + alert: false, + }, + { + id: 3, + project: "Construction Project A", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "187.50", + spentManhour: "200.00", + remainedManhour: "12.50", + comingPaymentMilestone: "13/12/2023", + alert: true, + }, + { + id: 4, + project: "Construction Project B", + team: "XXX", + teamLeader: "XXX", + currentStage: "Post Construction", + budgetedManhour: "100.00", + spentManhour: "40.00", + remainedManhour: "60.00", + comingPaymentMilestone: "05/01/2024", + alert: false, + }, + { + id: 5, + project: "Construction Project C", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "300.00", + spentManhour: "150.00", + remainedManhour: "150.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + }, + ]; + + const columns = [ + { + id: "clientCode", + field: "clientCode", + headerName: "Client Code", + flex: 1, + }, + { + id: "clientName", + field: "clientName", + headerName: "Client Name", + flex: 1, + }, + { + id: "clientSubsidiaryCode", + field: "clientSubsidiaryCode", + headerName: "Client Subsidiary Code", + flex: 1, + }, + { + id: "noOfProjects", + field: "noOfProjects", + headerName: "No. of Projects", + flex: 1, + }, + ]; + + const columns2 = [ + { + id: "project", + field: "project", + headerName: "Project", + flex: 1, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "currentStage", + field: "currentStage", + headerName: "Current Stage", + flex: 1, + }, + { + id: "budgetedManhour", + field: "budgetedManhour", + headerName: "Budgeted Manhour", + flex: 1, + }, + { + id: "spentManhour", + field: "spentManhour", + headerName: "Spent Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + {params.row.spentManhour} + ); + } else { + return {params.row.spentManhour}; + } + }, + flex: 1, + }, + { + id: "remainedManhour", + field: "remainedManhour", + headerName: "Remained Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + ({params.row.remainedManhour}) + ); + } else { + return {params.row.remainedManhour}; + } + }, + flex: 1, + }, + { + id: "comingPaymentMilestone", + field: "comingPaymentMilestone", + headerName: "Coming Payment Milestone", + flex: 1, + }, + { + id: "alert", + field: "alert", + headerName: "Alert", + renderCell: (params: any) => { + if (params.row.alert === true) { + return ( + + + + ); + } else { + return ; + } + }, + flex: 1, + }, + ]; + + const InputFields = [ + { + id: "clientCode", + label: "Client Code", + type: "text", + value: clientCode, + setValue: setClientCode, + }, + { + id: "clientName", + label: "Client Name", + type: "text", + value: clientName, + setValue: setClientName, + }, + { + id: "subsidiaryClientCode", + label: "Subsidiary Client Code", + type: "text", + value: subsidiaryClientCode, + setValue: setSubsidiaryClientCode, + }, + { + id: "subsidiaryClientName", + label: "Subsidiary Client Name", + type: "text", + value: subsidiaryClientName, + setValue: setSubsidiaryClientName, + }, + // { id: 'dropdownDemo', label: "dropdownDemo", type: 'dropdown', options: [{id:"1", label:"1"}], value: dropdownDemo, setValue: setDropdownDemo }, + // { id: 'dateDemo', label:'dateDemo', type: 'date', value: dateDemo, setValue: setDateDemo }, + // { id: 'checkboxDemo', label:'checkboxDemo', type: 'checkbox', value: checkboxDemo, setValue: setCheckboxDemo }, + // { id: ['receiptFromDate','receiptToDate'], label: ["收貨日期","收貨日期"], value: [receiptFromDate ? receiptFromDate : null, receiptToDate ? receiptToDate : null], + // setValue: [setReceiptFromDate, setReceiptToDate],type: 'dateRange' }, + ]; + + const stageDeadline = [ + "31/03/2024", + "20/02/2024", + "01/12/2023", + "05/01/2024", + "31/03/2023", + ]; + + const series2: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + data: [17.1, 28.6, 5.7, 48.6], + }, + ]; + + const series: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + name: "Current Stage Completion Percentage", + data: [80, 55, 40, 65, 70], + }, + ]; + + const options2: ApexOptions = { + chart: { + type: "donut", + }, + plotOptions: { + pie: { + donut: { + labels: { + show: false, + }, + }, + }, + }, + labels: [projectArray], + legend: { + show: false, + }, + responsive: [ + { + breakpoint: 480, + options: { + chart: { + width: 200, + }, + legend: { + position: "bottom", + show: false, + }, + }, + }, + ], + }; + + const options: ApexOptions = { + chart: { + type: "bar", + height: 350, + }, + colors: ["#FF4560", "#00E396", "#008FFB", "#775DD0", "#FEB019"], + plotOptions: { + bar: { + horizontal: true, + distributed: true, + }, + }, + dataLabels: { + enabled: false, + }, + xaxis: { + categories: [ + "Consultancy Project 123", + "Consultancy Project 456", + "Construction Project A", + "Construction Project B", + "Construction Project C", + ], + }, + yaxis: { + title: { + text: "Projects", + }, + labels: { + maxWidth: 200, + style: { + cssClass: "apexcharts-yaxis-label", + }, + }, + }, + title: { + text: "Current Stage Completion Percentage", + align: "center", + }, + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + }; + + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { + const selectedRowsData = rows2.filter((row) => + newSelectionModel.includes(row.id), + ); + console.log(selectedRowsData); + const projectArray: any[] = []; + let otherPercentage = 100; + let totalBudgetManhour = 0; + const percentageArray = []; + for (let i = 0; i <= selectedRowsData.length; i++) { + if (i === selectedRowsData.length) { + projectArray.push("Other"); + } else { + projectArray.push(selectedRowsData[i].project); + totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour); + } + } + for (let i = 0; i <= selectedRowsData.length; i++) { + if (i === selectedRowsData.length) { + percentageArray.push(otherPercentage); + } else { + const percentage = ( + (Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) * + 100 + ).toFixed(1); + percentageArray.push(Number(percentage)); + otherPercentage -= Number(percentage); + } + } + setSelectionModel(newSelectionModel); + setProjectArray(projectArray); + setPercentageArray(percentageArray); + }; + + const applySearch = (data: any) => { + console.log(data); + setSearchCriteria(data); + }; + return ( + + {/* */} + {/* */} +
+ + + +
+ +
+ {/*
+

Stage Deadline

+ {stageDeadline.map((date, index) => { + const marginTop = index === 0 ? 25 : 20; + return ( +

{date}

+ ); + })} +
*/} + +
+ +
+
+
+
+
+ + + + + + +
+
+ ); +}; + +export default ProgressByClient; diff --git a/src/components/DashboardPage/index.ts b/src/components/DashboardPage/index.ts new file mode 100644 index 0000000..4b5c5d1 --- /dev/null +++ b/src/components/DashboardPage/index.ts @@ -0,0 +1 @@ +export { default } from "./DashboardPage"; diff --git a/src/components/EnterLeave/EnterLeaveModal.tsx b/src/components/EnterLeave/EnterLeaveModal.tsx new file mode 100644 index 0000000..a42322c --- /dev/null +++ b/src/components/EnterLeave/EnterLeaveModal.tsx @@ -0,0 +1,125 @@ +"use client"; + +// import { testing } from "@/app/api/timesheets"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import AssignedProjectGrid from "../AssignedProjectGrid/AssignedProjectGrid"; +import PageTitle from "../PageTitle/PageTitle"; +import { Suspense } from "react"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import { Add } from "@mui/icons-material"; +import Link from "next/link"; +import { t } from "i18next"; +import { Card, Modal, Typography } from "@mui/material"; +import CustomModal from "../CustomModal/CustomModal"; +import { PROJECT_MODAL_STYLE } from "@/theme/colorConst"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import { DataGrid } from "@mui/x-data-grid"; +import TimesheetInputGrid from "./LeaveInputGrid"; +import { BASE_API_URL } from "@/config/api"; + +// import { fetchLeaves } from "@/app/api/leave"; + +interface EnterTimesheetModalProps { + isOpen: boolean; + onClose: () => void; + modalStyle?: any; +} + +const EnterTimesheetModal: React.FC = ({ + ...props +}) => { + const [lockConfirm, setLockConfirm] = useState(false); + const columns = [ + { + id: "projectCode", + field: "projectCode", + headerName: "Project Code and Name", + flex: 1, + }, + { + id: "task", + field: "task", + headerName: "Task", + flex: 1, + }, + ]; + + const rows = [ + { + id: 1, + projectCode: "M1001", + task: "1.2", + }, + { + id: 2, + projectCode: "M1301", + task: "1.1", + }, + ]; + + const fetchTimesheet = async () => { + // fetchLeaves(); + // const res = await fetch(`http://localhost:8090/api/timesheets`, { + // // const res = await fetch(`${BASE_API_URL}/timesheets`, { + // method: "GET", + // mode: 'no-cors', + // }); + + // console.log(res.json); + }; + + return ( + +
+ {/* +
+ Record Leave +
+
*/} + + + +
+ + +
+
+
+
+ ); +}; + +export default EnterTimesheetModal; diff --git a/src/components/EnterLeave/LeaveInputGrid.tsx b/src/components/EnterLeave/LeaveInputGrid.tsx new file mode 100644 index 0000000..03eeaab --- /dev/null +++ b/src/components/EnterLeave/LeaveInputGrid.tsx @@ -0,0 +1,548 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { useState, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import PageTitle from "../PageTitle/PageTitle"; +import { Suspense } from "react"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Link from "next/link"; +import { t } from "i18next"; +import { + Box, + Container, + Modal, + Select, + SelectChangeEvent, + Typography, +} from "@mui/material"; +import { Close } from "@mui/icons-material"; +import AddIcon from "@mui/icons-material/Add"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/DeleteOutlined"; +import SaveIcon from "@mui/icons-material/Save"; +import CancelIcon from "@mui/icons-material/Close"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import Swal from "sweetalert2"; +import { msg } from "../Swal/CustomAlerts"; +import React from "react"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { + GridRowsProp, + GridRowModesModel, + GridRowModes, + DataGrid, + GridColDef, + GridToolbarContainer, + GridFooterContainer, + GridActionsCellItem, + GridEventListener, + GridRowId, + GridRowModel, + GridRowEditStopReasons, + GridEditInputCell, + GridValueSetterParams, +} from "@mui/x-data-grid"; +import { LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import { Props } from "react-intl/src/components/relative"; + +const weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; + +interface BottomBarProps { + getHoursTotal: (column: string) => number; + setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +interface EditToolbarProps { + // setDay: (newDay : dayjs.Dayjs) => void; + setDay: (newDay: (oldDay: dayjs.Dayjs) => dayjs.Dayjs) => void; + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +interface EditFooterProps { + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +const EditToolbar = (props: EditToolbarProps) => { + const { setDay } = props; + const [selectedDate, setSelectedDate] = useState(dayjs()); + + const handleClickLeft = () => { + if (selectedDate) { + const newDate = selectedDate.add(-7, "day"); + setSelectedDate(newDate); + } + }; + const handleClickRight = () => { + if (selectedDate) { + const newDate = + selectedDate.add(7, "day") > dayjs() + ? dayjs() + : selectedDate.add(7, "day"); + setSelectedDate(newDate); + } + }; + + const handleDateChange = (date: dayjs.Dayjs | Date | null) => { + const newDate = dayjs(date); + setSelectedDate(newDate); + }; + + useEffect(() => { + setDay((oldDay) => selectedDate); + }, [selectedDate]); + + return ( + +
+ + Record Leave + + + + +
+
+ ); +}; + +const BottomBar = (props: BottomBarProps) => { + const { setRows, setRowModesModel, getHoursTotal, setLockConfirm } = props; + // const getHoursTotal = props.getHoursTotal; + const [newId, setNewId] = useState(-1); + const [invalidDays, setInvalidDays] = useState(0); + + const handleAddClick = () => { + const id = newId; + setNewId(newId - 1); + setRows((oldRows) => [ + ...oldRows, + { id, projectCode: "", task: "", isNew: true }, + ]); + setRowModesModel((oldModel) => ({ + ...oldModel, + [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, + })); + }; + + const totalColDef = { + flex: 1, + // style: {color:getHoursTotal('mon')>24?"red":"black"} + }; + + const TotalCell = ({ value }: Props) => { + const [invalid, setInvalid] = useState(false); + + useEffect(() => { + const newInvalid = (value ?? 0) > 24; + setInvalid(newInvalid); + }, [value]); + + return ( + + {value} + + ); + }; + + const checkUnlockConfirmBtn = () => { + // setLockConfirm((oldLock)=> valid); + setLockConfirm((oldLock) => + weekdays.every((weekday) => { + getHoursTotal(weekday) <= 24; + }), + ); + }; + + return ( +
+
+ + Total: + + + + + + + + +
+ +
+ ); +}; + +const EditFooter = (props: EditFooterProps) => { + return ( +
+ + Total: + + ssss +
+ ); +}; + +interface TimesheetInputGridProps { + setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; + onClose?: () => void; +} + +const initialRows: GridRowsProp = [ + { + id: 1, + projectCode: "M1001", + task: "1.2", + mon: 2.5, + }, + { + id: 2, + projectCode: "M1002", + task: "1.3", + mon: 3.25, + }, +]; + +const options = ["M1001", "M1301", "M1354", "M1973"]; +const options2 = [ + "1.1 - Preparation of preliminary Cost Estimate / Cost Plan", + "1.2 - Cash flow forecast", + "1.3 - Cost studies fo alterative design solutions", + "1.4 = Attend design co-ordination / project review meetings", + "1.5 - Prepare / Review RIC", +]; + +const getDateForHeader = (date: dayjs.Dayjs, weekday: number) => { + if (date.day() == 0) { + return date.add(weekday - date.day() - 7, "day").format("DD MMM"); + } else { + return date.add(weekday - date.day(), "day").format("DD MMM"); + } +}; + +const TimesheetInputGrid: React.FC = ({ + ...props +}) => { + const [rows, setRows] = useState(initialRows); + const [day, setDay] = useState(dayjs()); + const [rowModesModel, setRowModesModel] = React.useState( + {}, + ); + const { setLockConfirm } = props; + + const handleRowEditStop: GridEventListener<"rowEditStop"> = ( + params, + event, + ) => { + if (params.reason === GridRowEditStopReasons.rowFocusOut) { + event.defaultMuiPrevented = true; + } + }; + + const handleEditClick = (id: GridRowId) => () => { + setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } }); + }; + + const handleSaveClick = (id: GridRowId) => () => { + setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); + }; + + const handleDeleteClick = (id: GridRowId) => () => { + setRows(rows.filter((row) => row.id !== id)); + }; + + const handleCancelClick = (id: GridRowId) => () => { + setRowModesModel({ + ...rowModesModel, + [id]: { mode: GridRowModes.View, ignoreModifications: true }, + }); + + const editedRow = rows.find((row) => row.id === id); + if (editedRow!.isNew) { + setRows(rows.filter((row) => row.id !== id)); + } + }; + + const processRowUpdate = (newRow: GridRowModel) => { + const updatedRow = { ...newRow, isNew: false }; + setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); + return updatedRow; + }; + + const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => { + setRowModesModel(newRowModesModel); + }; + + const getHoursTotal = (column: any) => { + let sum = 0; + rows.forEach((row) => { + sum += row[column] ?? 0; + }); + return sum; + }; + + const weekdayColConfig: any = { + type: "number", + // sortable: false, + //width: 100, + flex: 1, + align: "left", + headerAlign: "left", + editable: true, + renderEditCell: (value: any) => ( + + ), + }; + + const columns: GridColDef[] = [ + { + field: "actions", + type: "actions", + headerName: "Actions", + width: 100, + cellClassName: "actions", + getActions: ({ id }) => { + const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; + + if (isInEditMode) { + return [ + } + title="Save" + label="Save" + sx={{ + color: "primary.main", + }} + onClick={handleSaveClick(id)} + />, + } + title="Cancel" + label="Cancel" + className="textPrimary" + onClick={handleCancelClick(id)} + color="inherit" + />, + ]; + } + + return [ + } + title="Edit" + label="Edit" + className="textPrimary" + onClick={handleEditClick(id)} + color="inherit" + />, + } + onClick={handleDeleteClick(id)} + sx={{ color: "red" }} + />, + ]; + }, + }, + { + field: "projectCode", + headerName: "Project Code", + // width: 220, + flex: 2, + editable: true, + type: "singleSelect", + valueOptions: options, + }, + { + field: "task", + headerName: "Task", + // width: 220, + flex: 3, + editable: true, + type: "singleSelect", + valueOptions: options2, + }, + { + // Mon + field: "mon", + ...weekdayColConfig, + renderHeader: () => { + return
Mon - {getDateForHeader(day, 1)}
; + }, + }, + { + // Tue + field: "tue", + ...weekdayColConfig, + renderHeader: () => { + return
Tue - {getDateForHeader(day, 2)}
; + }, + }, + { + // Wed + field: "wed", + ...weekdayColConfig, + renderHeader: () => { + return
Wed - {getDateForHeader(day, 3)}
; + }, + }, + { + // Thu + field: "thu", + ...weekdayColConfig, + renderHeader: () => { + return
Thu - {getDateForHeader(day, 4)}
; + }, + }, + { + // Fri + field: "fri", + ...weekdayColConfig, + renderHeader: () => { + return
Fri - {getDateForHeader(day, 5)}
; + }, + }, + { + // Sat + field: "sat", + ...weekdayColConfig, + renderHeader: () => { + return
Sat - {getDateForHeader(day, 6)}
; + }, + }, + { + // Sun + field: "sun", + ...weekdayColConfig, + renderHeader: () => { + return ( +
Sun - {getDateForHeader(day, 7)}
+ ); + }, + }, + // { + // field: 'joinDate', + // headerName: 'Join date', + // type: 'date', + // width: 180, + // editable: true, + // }, + ]; + + return ( + + + + + + ); +}; + +export default TimesheetInputGrid; diff --git a/src/components/EnterLeave/index.ts b/src/components/EnterLeave/index.ts new file mode 100644 index 0000000..33541f2 --- /dev/null +++ b/src/components/EnterLeave/index.ts @@ -0,0 +1 @@ +export { default } from "./EnterLeaveModal"; diff --git a/src/components/EnterTimesheet/EnterTimesheetModal.tsx b/src/components/EnterTimesheet/EnterTimesheetModal.tsx new file mode 100644 index 0000000..c63a905 --- /dev/null +++ b/src/components/EnterTimesheet/EnterTimesheetModal.tsx @@ -0,0 +1,125 @@ +"use client"; + +// import { testing } from "@/app/api/timesheets"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import AssignedProjectGrid from "../AssignedProjectGrid/AssignedProjectGrid"; +import PageTitle from "../PageTitle/PageTitle"; +import { Suspense } from "react"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import { Add } from "@mui/icons-material"; +import Link from "next/link"; +import { t } from "i18next"; +import { Card, Modal, Typography } from "@mui/material"; +import CustomModal from "../CustomModal/CustomModal"; +import { PROJECT_MODAL_STYLE } from "@/theme/colorConst"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import { DataGrid } from "@mui/x-data-grid"; +import TimesheetInputGrid from "./TimesheetInputGrid"; +import { BASE_API_URL } from "@/config/api"; + +// import { fetchTimesheets } from "@/app/api/timesheets"; + +interface EnterTimesheetModalProps { + isOpen: boolean; + onClose: () => void; + modalStyle?: any; +} + +const EnterTimesheetModal: React.FC = ({ + ...props +}) => { + const [lockConfirm, setLockConfirm] = useState(false); + const columns = [ + { + id: "projectCode", + field: "projectCode", + headerName: "Project Code and Name", + flex: 1, + }, + { + id: "task", + field: "task", + headerName: "Task", + flex: 1, + }, + ]; + + const rows = [ + { + id: 1, + projectCode: "M1001", + task: "1.2", + }, + { + id: 2, + projectCode: "M1301", + task: "1.1", + }, + ]; + + const fetchTimesheet = async () => { + // fetchTimesheets(); + // const res = await fetch(`http://localhost:8090/api/timesheets`, { + // // const res = await fetch(`${BASE_API_URL}/timesheets`, { + // method: "GET", + // mode: 'no-cors', + // }); + + // console.log(res.json); + }; + + return ( + +
+ {/* +
+ Timesheet Input +
+
*/} + + + +
+ + +
+
+
+
+ ); +}; + +export default EnterTimesheetModal; diff --git a/src/components/EnterTimesheet/TimesheetInputGrid.tsx b/src/components/EnterTimesheet/TimesheetInputGrid.tsx new file mode 100644 index 0000000..bc64c50 --- /dev/null +++ b/src/components/EnterTimesheet/TimesheetInputGrid.tsx @@ -0,0 +1,548 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { useState, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import PageTitle from "../PageTitle/PageTitle"; +import { Suspense } from "react"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import Link from "next/link"; +import { t } from "i18next"; +import { + Box, + Container, + Modal, + Select, + SelectChangeEvent, + Typography, +} from "@mui/material"; +import { Close } from "@mui/icons-material"; +import AddIcon from "@mui/icons-material/Add"; +import EditIcon from "@mui/icons-material/Edit"; +import DeleteIcon from "@mui/icons-material/DeleteOutlined"; +import SaveIcon from "@mui/icons-material/Save"; +import CancelIcon from "@mui/icons-material/Close"; +import ArrowForwardIcon from "@mui/icons-material/ArrowForward"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import Swal from "sweetalert2"; +import { msg } from "../Swal/CustomAlerts"; +import React from "react"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { + GridRowsProp, + GridRowModesModel, + GridRowModes, + DataGrid, + GridColDef, + GridToolbarContainer, + GridFooterContainer, + GridActionsCellItem, + GridEventListener, + GridRowId, + GridRowModel, + GridRowEditStopReasons, + GridEditInputCell, + GridValueSetterParams, +} from "@mui/x-data-grid"; +import { LocalizationProvider } from "@mui/x-date-pickers"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs from "dayjs"; +import { Props } from "react-intl/src/components/relative"; + +const weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; + +interface BottomBarProps { + getHoursTotal: (column: string) => number; + setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +interface EditToolbarProps { + // setDay: (newDay : dayjs.Dayjs) => void; + setDay: (newDay: (oldDay: dayjs.Dayjs) => dayjs.Dayjs) => void; + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +interface EditFooterProps { + setRows: (newRows: (oldRows: GridRowsProp) => GridRowsProp) => void; + setRowModesModel: ( + newModel: (oldModel: GridRowModesModel) => GridRowModesModel, + ) => void; +} + +const EditToolbar = (props: EditToolbarProps) => { + const { setDay } = props; + const [selectedDate, setSelectedDate] = useState(dayjs()); + + const handleClickLeft = () => { + if (selectedDate) { + const newDate = selectedDate.add(-7, "day"); + setSelectedDate(newDate); + } + }; + const handleClickRight = () => { + if (selectedDate) { + const newDate = + selectedDate.add(7, "day") > dayjs() + ? dayjs() + : selectedDate.add(7, "day"); + setSelectedDate(newDate); + } + }; + + const handleDateChange = (date: dayjs.Dayjs | Date | null) => { + const newDate = dayjs(date); + setSelectedDate(newDate); + }; + + useEffect(() => { + setDay((oldDay) => selectedDate); + }, [selectedDate]); + + return ( + +
+ + Timesheet Input + + + + +
+
+ ); +}; + +const BottomBar = (props: BottomBarProps) => { + const { setRows, setRowModesModel, getHoursTotal, setLockConfirm } = props; + // const getHoursTotal = props.getHoursTotal; + const [newId, setNewId] = useState(-1); + const [invalidDays, setInvalidDays] = useState(0); + + const handleAddClick = () => { + const id = newId; + setNewId(newId - 1); + setRows((oldRows) => [ + ...oldRows, + { id, projectCode: "", task: "", isNew: true }, + ]); + setRowModesModel((oldModel) => ({ + ...oldModel, + [id]: { mode: GridRowModes.Edit, fieldToFocus: "projectCode" }, + })); + }; + + const totalColDef = { + flex: 1, + // style: {color:getHoursTotal('mon')>24?"red":"black"} + }; + + const TotalCell = ({ value }: Props) => { + const [invalid, setInvalid] = useState(false); + + useEffect(() => { + const newInvalid = (value ?? 0) > 24; + setInvalid(newInvalid); + }, [value]); + + return ( + + {value} + + ); + }; + + const checkUnlockConfirmBtn = () => { + // setLockConfirm((oldLock)=> valid); + setLockConfirm((oldLock) => + weekdays.every((weekday) => { + getHoursTotal(weekday) <= 24; + }), + ); + }; + + return ( +
+
+ + Total: + + + + + + + + +
+ +
+ ); +}; + +const EditFooter = (props: EditFooterProps) => { + return ( +
+ + Total: + + ssss +
+ ); +}; + +interface TimesheetInputGridProps { + setLockConfirm: (newLock: (oldLock: boolean) => boolean) => void; + onClose?: () => void; +} + +const initialRows: GridRowsProp = [ + { + id: 1, + projectCode: "M1001", + task: "1.2", + mon: 2.5, + }, + { + id: 2, + projectCode: "M1002", + task: "1.3", + mon: 3.25, + }, +]; + +const options = ["M1001", "M1301", "M1354", "M1973"]; +const options2 = [ + "1.1 - Preparation of preliminary Cost Estimate / Cost Plan", + "1.2 - Cash flow forecast", + "1.3 - Cost studies fo alterative design solutions", + "1.4 = Attend design co-ordination / project review meetings", + "1.5 - Prepare / Review RIC", +]; + +const getDateForHeader = (date: dayjs.Dayjs, weekday: number) => { + if (date.day() == 0) { + return date.add(weekday - date.day() - 7, "day").format("DD MMM"); + } else { + return date.add(weekday - date.day(), "day").format("DD MMM"); + } +}; + +const TimesheetInputGrid: React.FC = ({ + ...props +}) => { + const [rows, setRows] = useState(initialRows); + const [day, setDay] = useState(dayjs()); + const [rowModesModel, setRowModesModel] = React.useState( + {}, + ); + const { setLockConfirm } = props; + + const handleRowEditStop: GridEventListener<"rowEditStop"> = ( + params, + event, + ) => { + if (params.reason === GridRowEditStopReasons.rowFocusOut) { + event.defaultMuiPrevented = true; + } + }; + + const handleEditClick = (id: GridRowId) => () => { + setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.Edit } }); + }; + + const handleSaveClick = (id: GridRowId) => () => { + setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } }); + }; + + const handleDeleteClick = (id: GridRowId) => () => { + setRows(rows.filter((row) => row.id !== id)); + }; + + const handleCancelClick = (id: GridRowId) => () => { + setRowModesModel({ + ...rowModesModel, + [id]: { mode: GridRowModes.View, ignoreModifications: true }, + }); + + const editedRow = rows.find((row) => row.id === id); + if (editedRow!.isNew) { + setRows(rows.filter((row) => row.id !== id)); + } + }; + + const processRowUpdate = (newRow: GridRowModel) => { + const updatedRow = { ...newRow, isNew: false }; + setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row))); + return updatedRow; + }; + + const handleRowModesModelChange = (newRowModesModel: GridRowModesModel) => { + setRowModesModel(newRowModesModel); + }; + + const getHoursTotal = (column: any) => { + let sum = 0; + rows.forEach((row) => { + sum += row[column] ?? 0; + }); + return sum; + }; + + const weekdayColConfig: any = { + type: "number", + // sortable: false, + //width: 100, + flex: 1, + align: "left", + headerAlign: "left", + editable: true, + renderEditCell: (value: any) => ( + + ), + }; + + const columns: GridColDef[] = [ + { + field: "actions", + type: "actions", + headerName: "Actions", + width: 100, + cellClassName: "actions", + getActions: ({ id }) => { + const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit; + + if (isInEditMode) { + return [ + } + title="Save" + label="Save" + sx={{ + color: "primary.main", + }} + onClick={handleSaveClick(id)} + />, + } + title="Cancel" + label="Cancel" + className="textPrimary" + onClick={handleCancelClick(id)} + color="inherit" + />, + ]; + } + + return [ + } + title="Edit" + label="Edit" + className="textPrimary" + onClick={handleEditClick(id)} + color="inherit" + />, + } + onClick={handleDeleteClick(id)} + sx={{ color: "red" }} + />, + ]; + }, + }, + { + field: "projectCode", + headerName: "Project Code", + // width: 220, + flex: 2, + editable: true, + type: "singleSelect", + valueOptions: options, + }, + { + field: "task", + headerName: "Task", + // width: 220, + flex: 3, + editable: true, + type: "singleSelect", + valueOptions: options2, + }, + { + // Mon + field: "mon", + ...weekdayColConfig, + renderHeader: () => { + return
Mon - {getDateForHeader(day, 1)}
; + }, + }, + { + // Tue + field: "tue", + ...weekdayColConfig, + renderHeader: () => { + return
Tue - {getDateForHeader(day, 2)}
; + }, + }, + { + // Wed + field: "wed", + ...weekdayColConfig, + renderHeader: () => { + return
Wed - {getDateForHeader(day, 3)}
; + }, + }, + { + // Thu + field: "thu", + ...weekdayColConfig, + renderHeader: () => { + return
Thu - {getDateForHeader(day, 4)}
; + }, + }, + { + // Fri + field: "fri", + ...weekdayColConfig, + renderHeader: () => { + return
Fri - {getDateForHeader(day, 5)}
; + }, + }, + { + // Sat + field: "sat", + ...weekdayColConfig, + renderHeader: () => { + return
Sat - {getDateForHeader(day, 6)}
; + }, + }, + { + // Sun + field: "sun", + ...weekdayColConfig, + renderHeader: () => { + return ( +
Sun - {getDateForHeader(day, 7)}
+ ); + }, + }, + // { + // field: 'joinDate', + // headerName: 'Join date', + // type: 'date', + // width: 180, + // editable: true, + // }, + ]; + + return ( + + + + + + ); +}; + +export default TimesheetInputGrid; diff --git a/src/components/EnterTimesheet/index.ts b/src/components/EnterTimesheet/index.ts new file mode 100644 index 0000000..e070291 --- /dev/null +++ b/src/components/EnterTimesheet/index.ts @@ -0,0 +1 @@ +export { default } from "./EnterTimesheetModal"; diff --git a/src/components/LoginPage/LoginForm.tsx b/src/components/LoginPage/LoginForm.tsx new file mode 100644 index 0000000..38b1bab --- /dev/null +++ b/src/components/LoginPage/LoginForm.tsx @@ -0,0 +1,100 @@ +"use client"; + +import { FormHelperText } from "@mui/material"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import TextField from "@mui/material/TextField"; +import Typography from "@mui/material/Typography"; +import { TFunction } from "i18next"; +import { signIn } from "next-auth/react"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; +import { SubmitHandler, useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; + +type LoginFields = { + username: string; + password: string; +}; + +// Error codes in https://next-auth.js.org/configuration/pages#sign-in-page +const getHumanFriendlyErrorMessage = ( + t: TFunction, + serverError: string, +): string => { + switch (serverError) { + case "CredentialsSignin": + return t("Invalid username or password."); + case "Default": + default: + return t("Something went wrong. Please try again later."); + } +}; + +const LoginForm: React.FC = () => { + const { t } = useTranslation("login"); + const { + register, + handleSubmit, + formState: { errors, isSubmitting }, + } = useForm(); + + const [serverError, setServerError] = useState(); + + const router = useRouter(); + + const onSubmit: SubmitHandler = async (data) => { + const res = await signIn("credentials", { + redirect: false, + ...data, + }); + + if (res?.error) { + setServerError(res.error); + return; + } + const callbackUrl = + new URLSearchParams(window.location.search).get("callbackUrl") || "/"; + + router.push(callbackUrl); + }; + + return ( + + {t("Sign In")} + + + {serverError && ( + + {getHumanFriendlyErrorMessage(t, serverError)} + + )} + + + ); +}; + +export default LoginForm; diff --git a/src/components/LoginPage/LoginPage.tsx b/src/components/LoginPage/LoginPage.tsx new file mode 100644 index 0000000..eb65647 --- /dev/null +++ b/src/components/LoginPage/LoginPage.tsx @@ -0,0 +1,24 @@ +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import LoginForm from "./LoginForm"; +import Logo from "../Logo"; +import { Box } from "@mui/material"; + +const LoginPage = () => { + return ( + + + + + + + + + + + + + ); +}; + +export default LoginPage; diff --git a/src/components/LoginPage/index.ts b/src/components/LoginPage/index.ts new file mode 100644 index 0000000..f815230 --- /dev/null +++ b/src/components/LoginPage/index.ts @@ -0,0 +1 @@ +export { default } from "./LoginPage"; diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx new file mode 100644 index 0000000..6005307 --- /dev/null +++ b/src/components/Logo/Logo.tsx @@ -0,0 +1,44 @@ +interface Props { + width?: number; + height?: number; +} + +const Logo: React.FC = ({ width, height }) => { + return ( + + + + + + + + + + + + + ); +}; + +export default Logo; diff --git a/src/components/Logo/index.ts b/src/components/Logo/index.ts new file mode 100644 index 0000000..f252704 --- /dev/null +++ b/src/components/Logo/index.ts @@ -0,0 +1 @@ +export { default } from "./Logo"; diff --git a/src/components/LogoutPage/LogoutPage.tsx b/src/components/LogoutPage/LogoutPage.tsx new file mode 100644 index 0000000..7cc220d --- /dev/null +++ b/src/components/LogoutPage/LogoutPage.tsx @@ -0,0 +1,17 @@ +"use client"; + +import { signOut } from "next-auth/react"; +import { useSearchParams } from "next/navigation"; +import { useEffect } from "react"; + +const LogoutPage = () => { + const params = useSearchParams(); + const callbackUrl = params.get("callbackUrl"); + useEffect(() => { + signOut({ redirect: true, callbackUrl: callbackUrl || "/" }); + }); + + return null; +}; + +export default LogoutPage; diff --git a/src/components/LogoutPage/index.ts b/src/components/LogoutPage/index.ts new file mode 100644 index 0000000..8efcfe6 --- /dev/null +++ b/src/components/LogoutPage/index.ts @@ -0,0 +1 @@ +export { default } from "./LogoutPage"; diff --git a/src/components/NavigationContent/NavigationContent.tsx b/src/components/NavigationContent/NavigationContent.tsx new file mode 100644 index 0000000..1c5b640 --- /dev/null +++ b/src/components/NavigationContent/NavigationContent.tsx @@ -0,0 +1,162 @@ +import Divider from "@mui/material/Divider"; +import Box from "@mui/material/Box"; +import React from "react"; +import List from "@mui/material/List"; +import ListItemButton from "@mui/material/ListItemButton"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import WorkHistory from "@mui/icons-material/WorkHistory"; +import Dashboard from "@mui/icons-material/Dashboard"; +import SummarizeIcon from "@mui/icons-material/Summarize"; +import PaymentsIcon from "@mui/icons-material/Payments"; +import AccountTreeIcon from "@mui/icons-material/AccountTree"; +import RequestQuote from "@mui/icons-material/RequestQuote"; +import PeopleIcon from "@mui/icons-material/People"; +import Task from "@mui/icons-material/Task"; +import Assignment from "@mui/icons-material/Assignment"; +import Settings from "@mui/icons-material/Settings"; +import Analytics from "@mui/icons-material/Analytics"; +import Payments from "@mui/icons-material/Payments"; +import { useTranslation } from "react-i18next"; +import Typography from "@mui/material/Typography"; +import { usePathname } from "next/navigation"; +import Link from "next/link"; +import { NAVIGATION_CONTENT_WIDTH } from "@/config/uiConfig"; +import Logo from "../Logo"; + +interface NavigationItem { + icon: React.ReactNode; + label: string; + path: string; + children?: NavigationItem[]; +} + +const navigationItems: NavigationItem[] = [ + { icon: , label: "User Workspace", path: "/home" }, + { + icon: , + label: "Dashboard", + path: "", + children: [ + { + icon: , + label: "Project Financial Summary", + path: "/dashboard/ProjectFinancialSummary", + }, + { + icon: , + label: "Company / Team Cash Flow", + path: "/dashboard/CompanyTeamCashFlow", + }, + { + icon: , + label: "Project Cash Flow", + path: "/dashboard/ProjectCashFlow", + }, + { + icon: , + label: "Project Status by Client", + path: "/dashboard/ProjectStatusByClient", + }, + { + icon: , + label: "Staff Utilization", + path: "/dashboard/StaffUtilization", + }, + ], + }, + { + icon: , + label: "Staff Reimbursement", + path: "/staffReimbursement", + children: [ + { + icon: , + label: "ClaimApproval", + path: "/staffReimbursement/ClaimApproval", + }, + { + icon: , + label: "ClaimSummary", + path: "/staffReimbursement/ClaimSummary", + }, + ], + }, + { icon: , label: "Project Management", path: "/projects" }, + { icon: , label: "Task Template", path: "/tasks" }, + { icon: , label: "Invoice", path: "/invoice" }, + { icon: , label: "Analysis Report", path: "/analytics" }, + { icon: , label: "Setting", path: "/settings" }, +]; + +const NavigationContent: React.FC = () => { + const { t } = useTranslation("common"); + const pathname = usePathname(); + + const [openItems, setOpenItems] = React.useState([]); + const toggleItem = (path: string) => { + setOpenItems((prevOpenItems) => + prevOpenItems.includes(path) + ? prevOpenItems.filter((item) => item !== path) + : [...prevOpenItems, path], + ); + }; + + const renderNavigationItem = (item: NavigationItem) => { + const isOpen = openItems.includes(item.path); + + return ( + + item.children && toggleItem(item.path)} + > + {item.icon} + + + {item.children && isOpen && ( + + {item.children.map((child) => renderNavigationItem(child))} + + )} + + ); + }; + + return ( + + + + {/* */} + + + + {navigationItems.map((item) => renderNavigationItem(item))} + {/* {navigationItems.map(({ icon, label, path }, index) => { + return ( + + + {icon} + + + + ); + })} */} + + + ); +}; + +export default NavigationContent; diff --git a/src/components/NavigationContent/index.ts b/src/components/NavigationContent/index.ts new file mode 100644 index 0000000..bcd4bfa --- /dev/null +++ b/src/components/NavigationContent/index.ts @@ -0,0 +1 @@ +export { default } from "./NavigationContent"; diff --git a/src/components/PageTitle/PageTitle.tsx b/src/components/PageTitle/PageTitle.tsx new file mode 100644 index 0000000..d76d313 --- /dev/null +++ b/src/components/PageTitle/PageTitle.tsx @@ -0,0 +1,166 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; + +type PageTitleProps = { + BigTitle: string; + SecondTitle?: string; + ThirdTitle?: string; + FourthTitle?: string; +}; + +const PageTitle: React.FC = ({ + BigTitle, + SecondTitle = "", + ThirdTitle = "", + FourthTitle = "", +}) => { + const { t } = useTranslation("dashboard"); + return ( + +
+

+ {BigTitle} +

+    +
+    +

+ Overview +

+   +

+ {">"} +

+   +

+ {BigTitle} +

+   + {SecondTitle !== "" ? ( +

+ {">"}  +

+ ) : ( + "" + )} + {SecondTitle !== "" ? ( +

+ {SecondTitle}  +

+ ) : ( + "" + )} + {ThirdTitle !== "" ? ( +

+ {">"}  +

+ ) : ( + "" + )} + {ThirdTitle !== "" ? ( +

+ {ThirdTitle}  +

+ ) : ( + "" + )} + {FourthTitle !== "" ? ( +

+ {">"}  +

+ ) : ( + "" + )} + {FourthTitle !== "" ? ( +

+ {FourthTitle}  +

+ ) : ( + "" + )} +
+
+ ); +}; + +export default PageTitle; diff --git a/src/components/PageTitle/index.ts b/src/components/PageTitle/index.ts new file mode 100644 index 0000000..1629166 --- /dev/null +++ b/src/components/PageTitle/index.ts @@ -0,0 +1 @@ +export { default } from "./PageTitle"; diff --git a/src/components/ProgressByClient/ProgressByClient.tsx b/src/components/ProgressByClient/ProgressByClient.tsx new file mode 100644 index 0000000..939f5d3 --- /dev/null +++ b/src/components/ProgressByClient/ProgressByClient.tsx @@ -0,0 +1,643 @@ +"use client"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord, AnyCnameRecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; + +const ProgressByClient: React.FC = () => { + const [activeTab, setActiveTab] = useState("financialSummary"); + const [SearchCriteria, setSearchCriteria] = React.useState({}); + const { t } = useTranslation("dashboard"); + + const [clientCode, setClientCode] = useState(""); + const [clientName, setClientName] = useState(""); + const [subsidiaryClientCode, setSubsidiaryClientCode] = useState(""); + const [subsidiaryClientName, setSubsidiaryClientName] = useState(""); + const [projectArray, setProjectArray]: any[] = useState([]); + const [percentageArray, setPercentageArray]: any[] = useState([]); + const [colorArray, setColorArray]: any[] = useState([]); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [pieChartColor, setPieChartColor]: any[] = React.useState([]); + const [totalSpentPercentage, setTotalSpentPercentage]: any = React.useState(); + const [projectBudgetManhour, setProjectBudgetManhour]: any = + React.useState("-"); + const [actualManhourSpent, setActualManhourSpent]: any = React.useState("-"); + const [remainedManhour, setRemainedManhour]: any = React.useState("-"); + const [lastUpdate, setLastUpdate]: any = React.useState("-"); + const [dropdownDemo, setDropdownDemo] = useState(""); + const [dateDemo, setDateDemo] = useState(null); + const [checkboxDemo, setCheckboxDemo] = useState(false); + const [receiptFromDate, setReceiptFromDate] = useState(null); + const [receiptToDate, setReceiptToDate] = useState(null); + const [selectedRows, setSelectedRows] = useState([]); + const rows = [ + { + id: 1, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "N/A", + clientSubsidiaryName: "N/A", + noOfProjects: "5", + }, + { + id: 2, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-001", + clientSubsidiaryName: "Subsidiary A", + noOfProjects: "5", + }, + { + id: 3, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-002", + clientSubsidiaryName: "Subsidiary B", + noOfProjects: "3", + }, + { + id: 4, + clientCode: "CUST-001", + clientName: "Client A", + clientSubsidiaryCode: "SUBS-003", + clientSubsidiaryName: "Subsidiary C", + noOfProjects: "1", + }, + ]; + //['#f57f90', '#94f7d6', '#87c5f5', '#ab95f5', '#fcd68b'] + const rows2 = [ + { + id: 1, + project: "Consultancy Project 123", + team: "XXX", + teamLeader: "XXX", + currentStage: "Contract Documentation", + budgetedManhour: "200.00", + spentManhour: "120.00", + remainedManhour: "80.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + color: "#f57f90", + }, + { + id: 2, + project: "Consultancy Project 456", + team: "XXX", + teamLeader: "XXX", + currentStage: "Report Preparation", + budgetedManhour: "400.00", + spentManhour: "200.00", + remainedManhour: "200.00", + comingPaymentMilestone: "20/02/2024", + alert: false, + color: "#94f7d6", + }, + { + id: 3, + project: "Construction Project A", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "187.50", + spentManhour: "200.00", + remainedManhour: "12.50", + comingPaymentMilestone: "13/12/2023", + alert: true, + color: "#87c5f5", + }, + { + id: 4, + project: "Construction Project B", + team: "XXX", + teamLeader: "XXX", + currentStage: "Post Construction", + budgetedManhour: "100.00", + spentManhour: "40.00", + remainedManhour: "60.00", + comingPaymentMilestone: "05/01/2024", + alert: false, + color: "#ab95f5", + }, + { + id: 5, + project: "Construction Project C", + team: "YYY", + teamLeader: "YYY", + currentStage: "Construction", + budgetedManhour: "300.00", + spentManhour: "150.00", + remainedManhour: "150.00", + comingPaymentMilestone: "31/03/2024", + alert: false, + color: "#fcd68b", + }, + ]; + + const columns = [ + { + id: "clientCode", + field: "clientCode", + headerName: "Client Code", + flex: 1, + }, + { + id: "clientName", + field: "clientName", + headerName: "Client Name", + flex: 1, + }, + { + id: "clientSubsidiaryCode", + field: "clientSubsidiaryCode", + headerName: "Client Subsidiary Code", + flex: 1, + }, + { + id: "noOfProjects", + field: "noOfProjects", + headerName: "No. of Projects", + flex: 1, + }, + ]; + + const columns2 = [ + { + id: "color", + field: "color", + headerName: "", + renderCell: (params: any) => { + return ( + + ); + }, + flex: 0.1, + }, + { + id: "project", + field: "project", + headerName: "Project", + flex: 1, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 0.8, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 0.8, + }, + { + id: "currentStage", + field: "currentStage", + headerName: "Current Stage", + flex: 1, + }, + { + id: "budgetedManhour", + field: "budgetedManhour", + headerName: "Budgeted Manhour", + flex: 0.8, + }, + { + id: "spentManhour", + field: "spentManhour", + headerName: "Spent Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + {params.row.spentManhour} + ); + } else { + return {params.row.spentManhour}; + } + }, + flex: 0.8, + }, + { + id: "remainedManhour", + field: "remainedManhour", + headerName: "Remained Manhour", + renderCell: (params: any) => { + if (params.row.budgetedManhour - params.row.spentManhour <= 0) { + return ( + ({params.row.remainedManhour}) + ); + } else { + return {params.row.remainedManhour}; + } + }, + flex: 1, + }, + { + id: "comingPaymentMilestone", + field: "comingPaymentMilestone", + headerName: "Coming Payment Milestone", + flex: 1, + }, + { + id: "alert", + field: "alert", + headerName: "Alert", + renderCell: (params: any) => { + if (params.row.alert === true) { + return ( + + + + ); + } else { + return ; + } + }, + flex: 0.2, + }, + ]; + + const InputFields = [ + { + id: "clientCode", + label: "Client Code", + type: "text", + value: clientCode, + setValue: setClientCode, + }, + { + id: "clientName", + label: "Client Name", + type: "text", + value: clientName, + setValue: setClientName, + }, + { + id: "subsidiaryClientCode", + label: "Subsidiary Client Code", + type: "text", + value: subsidiaryClientCode, + setValue: setSubsidiaryClientCode, + }, + { + id: "subsidiaryClientName", + label: "Subsidiary Client Name", + type: "text", + value: subsidiaryClientName, + setValue: setSubsidiaryClientName, + }, + // { id: 'dropdownDemo', label: "dropdownDemo", type: 'dropdown', options: [{id:"1", label:"1"}], value: dropdownDemo, setValue: setDropdownDemo }, + // { id: 'dateDemo', label:'dateDemo', type: 'date', value: dateDemo, setValue: setDateDemo }, + // { id: 'checkboxDemo', label:'checkboxDemo', type: 'checkbox', value: checkboxDemo, setValue: setCheckboxDemo }, + // { id: ['receiptFromDate','receiptToDate'], label: ["收貨日期","收貨日期"], value: [receiptFromDate ? receiptFromDate : null, receiptToDate ? receiptToDate : null], + // setValue: [setReceiptFromDate, setReceiptToDate],type: 'dateRange' }, + ]; + + const stageDeadline = [ + "31/03/2024", + "20/02/2024", + "01/12/2023", + "05/01/2024", + "31/03/2023", + ]; + + const series2: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + data: [17.1, 28.6, 5.7, 48.6], + }, + ]; + + const series: ApexAxisChartSeries | ApexNonAxisChartSeries = [ + { + name: "Current Stage Completion Percentage", + data: [80, 55, 40, 65, 70], + }, + ]; + + const options2: ApexOptions = { + chart: { + type: "donut", + }, + colors: colorArray, + plotOptions: { + pie: { + donut: { + labels: { + show: true, + name: { + show: true, + }, + value: { + show: true, + fontWeight: 500, + fontSize: "30px", + color: "#3e98c7", + }, + total: { + show: true, + showAlways: true, + label: "Spent", + fontFamily: "sans-serif", + formatter: function (val) { + return totalSpentPercentage + "%"; + }, + }, + }, + }, + }, + }, + labels: projectArray, + legend: { + show: false, + }, + responsive: [ + { + breakpoint: 480, + options: { + chart: { + width: 200, + }, + legend: { + position: "bottom", + show: false, + }, + }, + }, + ], + }; + + const options: ApexOptions = { + chart: { + type: "bar", + height: 350, + }, + colors: ["#f57f90", "#94f7d6", "#87c5f5", "#ab95f5", "#fcd68b"], + plotOptions: { + bar: { + horizontal: true, + distributed: true, + }, + }, + dataLabels: { + enabled: false, + }, + xaxis: { + categories: [ + "Consultancy Project 123", + "Consultancy Project 456", + "Construction Project A", + "Construction Project B", + "Construction Project C", + ], + }, + yaxis: { + title: { + text: "Projects", + }, + labels: { + maxWidth: 200, + style: { + cssClass: "apexcharts-yaxis-label", + }, + }, + }, + title: { + text: "Current Stage Completion Percentage", + align: "center", + }, + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + }; + + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { + const selectedRowsData = rows2.filter((row) => + newSelectionModel.includes(row.id), + ); + console.log(selectedRowsData); + const projectArray = []; + const pieChartColorArray = []; + let totalSpent = 0; + let totalBudgetManhour = 0; + const percentageArray = []; + for (let i = 0; i <= selectedRowsData.length; i++) { + if (i === selectedRowsData.length && i > 0) { + projectArray.push("Remained"); + } else if (selectedRowsData.length > 0) { + projectArray.push(selectedRowsData[i].project); + totalBudgetManhour += Number(selectedRowsData[i].budgetedManhour); + totalSpent += Number(selectedRowsData[i].spentManhour); + pieChartColorArray.push(selectedRowsData[i].color); + } + } + for (let i = 0; i <= selectedRowsData.length; i++) { + if (i === selectedRowsData.length && i > 0) { + const remainedManhour = totalBudgetManhour - totalSpent; + percentageArray.push( + Number(((remainedManhour / totalBudgetManhour) * 100).toFixed(1)), + ); + } else if (selectedRowsData.length > 0) { + const percentage = ( + (Number(selectedRowsData[i].spentManhour) / totalBudgetManhour) * + 100 + ).toFixed(1); + percentageArray.push(Number(percentage)); + } + } + setProjectBudgetManhour(totalBudgetManhour.toFixed(2)); + setActualManhourSpent(totalSpent.toFixed(2)); + setRemainedManhour((totalBudgetManhour - totalSpent).toFixed(2)); + setLastUpdate(new Date().toLocaleDateString("en-GB")); + setSelectionModel(newSelectionModel); + console.log(projectArray); + setProjectArray(projectArray); + setPercentageArray(percentageArray); + console.log(percentageArray); + setTotalSpentPercentage( + ((totalSpent / totalBudgetManhour) * 100).toFixed(1), + ); + if (projectArray.length > 0 && projectArray.includes("Remained")) { + const nonLastRecordColors = pieChartColorArray; + setColorArray([ + ...nonLastRecordColors.slice(0, projectArray.length - 1), + "#a3a3a3", + ]); + } else { + setColorArray(pieChartColorArray); + } + }; + + const applySearch = (data: any) => { + console.log(data); + setSearchCriteria(data); + }; + return ( + + {/* */} + {/* */} +
+ + + +
+ +
+ {/*
+

Stage Deadline

+ {stageDeadline.map((date, index) => { + const marginTop = index === 0 ? 25 : 20; + return ( +

{date}

+ ); + })} +
*/} + +
+ +
+
+
+
+
+ + + + {percentageArray.length === 0 && ( +
+ Please select the project you want to check. +
+ )} + {percentageArray.length > 0 && ( + + )} +
+
+ + +
+
+ Project Budget Manhour +
+
+ {projectBudgetManhour} +
+
+
+
+
+ Actual Manhour Spent +
+
+ {actualManhourSpent} +
+
+
+
+
+ Remained Manhour +
+
+ {remainedManhour} +
+
+
+
+
+ Last Update +
+
+ {lastUpdate} +
+
+
+
+
+
+ ); +}; + +export default ProgressByClient; diff --git a/src/components/ProgressByClient/index.ts b/src/components/ProgressByClient/index.ts new file mode 100644 index 0000000..3b2ccf9 --- /dev/null +++ b/src/components/ProgressByClient/index.ts @@ -0,0 +1 @@ +export { default } from "./ProgressByClient"; diff --git a/src/components/ProgressByClientSearch/ProgressByClientSearch.tsx b/src/components/ProgressByClientSearch/ProgressByClientSearch.tsx new file mode 100644 index 0000000..7ddbb00 --- /dev/null +++ b/src/components/ProgressByClientSearch/ProgressByClientSearch.tsx @@ -0,0 +1,57 @@ +"use client"; + +import { ProjectResult } from "@/app/api/projects"; +import React, { useMemo, useState } from "react"; +import SearchBox, { Criterion } from "../SearchBox"; +import { useTranslation } from "react-i18next"; +import SearchResults, { Column } from "../SearchResults"; +import { ClientProjectResult } from "@/app/api/clientprojects"; + +interface Props { + projects: ClientProjectResult[]; +} +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +const ProgressByClientSearch: React.FC = ({ projects }) => { + const { t } = useTranslation("projects"); + + // If project searching is done on the server-side, then no need for this. + const [filteredProjects, setFilteredProjects] = useState(projects); + + const searchCriteria: Criterion[] = useMemo( + () => [ + { label: "Client Code", paramName: "clientCode", type: "text" }, + { label: "Client Name", paramName: "clientName", type: "text" }, + ], + [t], + ); + + const columns = useMemo[]>( + () => [ + { name: "clientCode", label: t("Project Code") }, + { name: "clientName", label: t("Project Name") }, + { name: "SubsidiaryClientCode", label: t("Project Category") }, + { name: "SubsidiaryClientName", label: t("Team") }, + { name: "NoOfProjects", label: t("Client") }, + ], + [t], + ); + + return ( + <> + { + console.log(query); + }} + /> + + items={filteredProjects} + columns={columns} + /> + + ); +}; + +export default ProgressByClientSearch; diff --git a/src/components/ProgressByClientSearch/ProgressByClientSearchLoading.tsx b/src/components/ProgressByClientSearch/ProgressByClientSearchLoading.tsx new file mode 100644 index 0000000..dd33fa0 --- /dev/null +++ b/src/components/ProgressByClientSearch/ProgressByClientSearchLoading.tsx @@ -0,0 +1,40 @@ +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Skeleton from "@mui/material/Skeleton"; +import Stack from "@mui/material/Stack"; +import React from "react"; + +// Can make this nicer +export const ProgressByClientSearchLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ProgressByClientSearchLoading; diff --git a/src/components/ProgressByClientSearch/ProgressByClientSearchWrapper.tsx b/src/components/ProgressByClientSearch/ProgressByClientSearchWrapper.tsx new file mode 100644 index 0000000..b644fb4 --- /dev/null +++ b/src/components/ProgressByClientSearch/ProgressByClientSearchWrapper.tsx @@ -0,0 +1,18 @@ +import { fetchClientProjects } from "@/app/api/clientprojects"; +import React from "react"; +import ProgressByClientSearch from "./ProgressByClientSearch"; +import ProgressByClientSearchLoading from "./ProgressByClientSearchLoading"; + +interface SubComponents { + Loading: typeof ProgressByClientSearchLoading; +} + +const ProgressByClientSearchWrapper: React.FC & SubComponents = async () => { + const clentprojects = await fetchClientProjects(); + + return ; +}; + +ProgressByClientSearchWrapper.Loading = ProgressByClientSearchLoading; + +export default ProgressByClientSearchWrapper; diff --git a/src/components/ProgressByClientSearch/index.ts b/src/components/ProgressByClientSearch/index.ts new file mode 100644 index 0000000..4fdbe22 --- /dev/null +++ b/src/components/ProgressByClientSearch/index.ts @@ -0,0 +1 @@ +export { default } from "./ProgressByClientSearchWrapper"; diff --git a/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx new file mode 100644 index 0000000..845c874 --- /dev/null +++ b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearch.tsx @@ -0,0 +1,156 @@ +"use client"; + +import { ProjectResult } from "@/app/api/projects"; +import React, { useMemo, useState } from "react"; +import SearchBox, { Criterion } from "../SearchBox"; +import { useTranslation } from "react-i18next"; +import SearchResults, { Column } from "../SearchResults"; +import { CashFlow } from "@/app/api/cashflow"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ProjectCashFlow from "../ProjectCashFlow"; + +interface Props { + projects: CashFlow[]; +} +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +const ProgressByClientSearch: React.FC = ({ projects }) => { + const { t } = useTranslation("projects"); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const columns = [ + { + id: "projectCode", + field: "projectCode", + headerName: "Project Code", + flex: 1, + }, + { + id: "projectName", + field: "projectName", + headerName: "Project Name", + flex: 1, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, + ]; + const rows = [ + { + id: 1, + projectCode: "M1001", + projectName: "Consultancy Project A", + team: "XXX", + teamLeader: "XXX", + startDate: "01/07/2022", + targetEndDate: "01/04/2024", + client: "Client B", + subsidiary: "N/A", + }, + { + id: 2, + projectCode: "M1301", + projectName: "Consultancy Project AAAA", + team: "XXX", + teamLeader: "XXX", + startDate: "01/09/2022", + targetEndDate: "20/02/2024", + client: "Client C", + subsidiary: "Subsidiary A", + }, + { + id: 3, + projectCode: "M1354", + projectName: "Consultancy Project BBB", + team: "YYY", + teamLeader: "YYY", + startDate: "01/02/2023", + targetEndDate: "31/01/2024", + client: "Client D", + subsidiary: "Subsidiary C", + }, + ]; + const [selectedTeamData, setSelectedTeamData]: any[] = React.useState(rows); + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { + const selectedRowsData = selectedTeamData.filter((row: any) => + newSelectionModel.includes(row.id), + ); + console.log(selectedRowsData); + }; + + // If project searching is done on the server-side, then no need for this. + const [filteredProjects, setFilteredProjects] = useState(projects); + + const searchCriteria: Criterion[] = useMemo( + () => [ + { label: "Project Code", paramName: "projectCode", type: "text" }, + { label: "Project Name", paramName: "projectName", type: "text" }, + { + label: "Start Date From", + label2: "Start Date To", + paramName: "startDateFrom", + type: "dateRange", + }, + ], + [t], + ); + + // const columns = useMemo[]>( + // () => [ + // { name: "clientCode", label: t("Project Code") }, + // { name: "clientName", label: t("Project Name") }, + // { name: "SubsidiaryClientCode", label: t("Project Category") }, + // { name: "SubsidiaryClientName", label: t("Team") }, + // { name: "NoOfProjects", label: t("Client") }, + // ], + // [t], + // ); + + return ( + <> + { + console.log(query); + }} + /> + {/* */} + + ); +}; + +export default ProgressByClientSearch; diff --git a/src/components/ProgressCashFlowSearch/ProgressCashFlowSearchLoading.tsx b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearchLoading.tsx new file mode 100644 index 0000000..7d25500 --- /dev/null +++ b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearchLoading.tsx @@ -0,0 +1,40 @@ +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Skeleton from "@mui/material/Skeleton"; +import Stack from "@mui/material/Stack"; +import React from "react"; + +// Can make this nicer +export const ProgressCashFlowSearchLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ProgressCashFlowSearchLoading; diff --git a/src/components/ProgressCashFlowSearch/ProgressCashFlowSearchWrapper.tsx b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearchWrapper.tsx new file mode 100644 index 0000000..8e99756 --- /dev/null +++ b/src/components/ProgressCashFlowSearch/ProgressCashFlowSearchWrapper.tsx @@ -0,0 +1,18 @@ +import { fetchProjectsCashFlow } from "@/app/api/cashflow"; +import React from "react"; +import ProgressCashFlowSearch from "./ProgressCashFlowSearch"; +import ProgressCashFlowSearchSearchLoading from "./ProgressCashFlowSearchLoading"; + +interface SubComponents { + Loading: typeof ProgressCashFlowSearchSearchLoading; +} + +const ProgressCashFlowSearchWrapper: React.FC & SubComponents = async () => { + const clentprojects = await fetchProjectsCashFlow(); + + return ; +}; + +ProgressCashFlowSearchWrapper.Loading = ProgressCashFlowSearchSearchLoading; + +export default ProgressCashFlowSearchWrapper; diff --git a/src/components/ProgressCashFlowSearch/index.ts b/src/components/ProgressCashFlowSearch/index.ts new file mode 100644 index 0000000..417711b --- /dev/null +++ b/src/components/ProgressCashFlowSearch/index.ts @@ -0,0 +1 @@ +export { default } from "./ProgressCashFlowSearchWrapper"; diff --git a/src/components/ProjectCashFlow/ProjectCashFlow.tsx b/src/components/ProjectCashFlow/ProjectCashFlow.tsx new file mode 100644 index 0000000..5eb455c --- /dev/null +++ b/src/components/ProjectCashFlow/ProjectCashFlow.tsx @@ -0,0 +1,638 @@ +"use client"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord, AnyCnameRecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; +import { Input, Label } from "reactstrap"; + +const ProjectCashFlow: React.FC = () => { + const todayDate = new Date(); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [cashFlowYear, setCashFlowYear]: any[] = React.useState( + todayDate.getFullYear(), + ); + const columns = [ + { + id: "projectCode", + field: "projectCode", + headerName: "Project Code", + flex: 1, + }, + { + id: "projectName", + field: "projectName", + headerName: "Project Name", + flex: 1, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, + ]; + + const ledgerColumns = [ + { + id: "date", + field: "date", + headerName: "Date", + flex: 0.5, + }, + { + id: "expenditure", + field: "expenditure", + headerName: "Expenditure (HKD)", + flex: 0.6, + }, + { + id: "income", + field: "income", + headerName: "Income (HKD)", + flex: 0.6, + }, + { + id: "cashFlowBalance", + field: "cashFlowBalance", + headerName: "Cash Flow Balance (HKD)", + flex: 0.6, + }, + { + id: "remarks", + field: "remarks", + headerName: "Remarks", + flex: 1, + }, + ]; + + const options: ApexOptions = { + chart: { + height: 350, + type: "line", + }, + stroke: { + width: [0, 0, 2, 2], + }, + plotOptions: { + bar: { + horizontal: false, + distributed: false, + }, + }, + dataLabels: { + enabled: false, + }, + xaxis: { + categories: [ + "Q1", + "Q2", + "Q3", + "Q4", + "Q5", + "Q6", + "Q7", + "Q8", + "Q9", + "Q10", + "Q11", + "Q12", + ], + }, + yaxis: [ + { + title: { + text: "Monthly Income and Expenditure(HKD)", + }, + min: 0, + max: 350000, + tickAmount: 5, + }, + { + show: false, + seriesName: "Monthly_Expenditure", + title: { + text: "Monthly Expenditure (HKD)", + }, + min: 0, + max: 350000, + tickAmount: 5, + }, + { + seriesName: "Cumulative_Income", + opposite: true, + title: { + text: "Cumulative Income and Expenditure(HKD)", + }, + min: 0, + max: 850000, + tickAmount: 5, + }, + { + show: false, + seriesName: "Cumulative_Expenditure", + opposite: true, + title: { + text: "Cumulative Expenditure (HKD)", + }, + min: 0, + max: 850000, + tickAmount: 5, + }, + ], + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + series: [ + { + name: "Monthly_Income", + type: "column", + color: "#ffde91", + data: [0, 110000, 0, 0, 185000, 0, 0, 189000, 0, 0, 300000, 0], + }, + { + name: "Monthly_Expenditure", + type: "column", + color: "#82b59a", + data: [ + 0, 160000, 120000, 120000, 55000, 55000, 55000, 55000, 55000, 70000, + 55000, 55000, + ], + }, + { + name: "Cumulative_Income", + type: "line", + color: "#EE6D7A", + data: [ + 0, 100000, 100000, 100000, 300000, 300000, 300000, 500000, 500000, + 500000, 800000, 800000, + ], + }, + { + name: "Cumulative_Expenditure", + type: "line", + color: "#7cd3f2", + data: [ + 0, 198000, 240000, 400000, 410000, 430000, 510000, 580000, 600000, + 710000, 730000, 790000, + ], + }, + ], + }; + + const accountsReceivableOptions: ApexOptions = { + colors: ["#20E647"], + series: [80], + chart: { + height: 350, + type: "radialBar", + }, + plotOptions: { + radialBar: { + hollow: { + size: "70%", + background: "#ffffff", + }, + track: { + dropShadow: { + enabled: true, + top: 2, + left: 0, + blur: 4, + opacity: 0.15, + }, + }, + dataLabels: { + name: { + show: false, + }, + value: { + color: "#3e98c7", + fontSize: "3em", + show: true, + }, + }, + }, + }, + fill: { + type: "gradient", + gradient: { + shade: "dark", + type: "vertical", + gradientToColors: ["#87D4F9"], + stops: [0, 100], + }, + }, + stroke: { + lineCap: "round", + }, + labels: ["AccountsReceivable"], + }; + + const expenditureOptions: ApexOptions = { + colors: ["#20E647"], + series: [95], + chart: { + height: 350, + type: "radialBar", + }, + plotOptions: { + radialBar: { + hollow: { + size: "70%", + background: "#ffffff", + }, + track: { + dropShadow: { + enabled: true, + top: 2, + left: 0, + blur: 4, + opacity: 0.15, + }, + }, + dataLabels: { + name: { + show: false, + }, + value: { + color: "#3e98c7", + fontSize: "3em", + show: true, + }, + }, + }, + }, + fill: { + type: "gradient", + gradient: { + shade: "dark", + type: "vertical", + gradientToColors: ["#87D4F9"], + stops: [0, 100], + }, + }, + stroke: { + lineCap: "round", + }, + labels: ["AccountsReceivable"], + }; + + const rows = [ + { + id: 1, + projectCode: "M1001", + projectName: "Consultancy Project A", + team: "XXX", + teamLeader: "XXX", + startDate: "01/07/2022", + targetEndDate: "01/04/2024", + client: "Client B", + subsidiary: "N/A", + }, + { + id: 2, + projectCode: "M1301", + projectName: "Consultancy Project AAAA", + team: "XXX", + teamLeader: "XXX", + startDate: "01/09/2022", + targetEndDate: "20/02/2024", + client: "Client C", + subsidiary: "Subsidiary A", + }, + { + id: 3, + projectCode: "M1354", + projectName: "Consultancy Project BBB", + team: "YYY", + teamLeader: "YYY", + startDate: "01/02/2023", + targetEndDate: "31/01/2024", + client: "Client D", + subsidiary: "Subsidiary C", + }, + ]; + + const ledgerRows = [ + { + id: 1, + date: "Feb 2023", + expenditure: "-", + income: "100,000.00", + cashFlowBalance: "100,000.00", + remarks: "Payment Milestone 1 (10%)", + }, + { + id: 2, + date: "Feb 2023", + expenditure: "160,000.00", + income: "-", + cashFlowBalance: "(60,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + { + id: 3, + date: "Mar 2023", + expenditure: "160,000.00", + income: "-", + cashFlowBalance: "(180,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + { + id: 4, + date: "Apr 2023", + expenditure: "120,000.00", + income: "-", + cashFlowBalance: "(300,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + { + id: 5, + date: "May 2023", + expenditure: "-", + income: "200,000.00", + cashFlowBalance: "(100,000.00)", + remarks: "Payment Milestone 2 (20%)", + }, + { + id: 6, + date: "May 2023", + expenditure: "40,000.00", + income: "-", + cashFlowBalance: "(140,000.00)", + remarks: "Monthly Manpower Expenditure", + }, + ]; + + const [projectData, setProjectData]: any[] = React.useState(rows); + const [ledgerData, setLedgerData]: any[] = React.useState(ledgerRows); + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { + const selectedRowsData = projectData.filter((row: any) => + newSelectionModel.includes(row.id), + ); + console.log(selectedRowsData); + }; + + return ( + <> + }> + + + + +
+ + + +
+
+ + +
+
+ +
+
+ +
+ +
+
+
+
+
+ + + + + +
+ Total A. Receivable +
+
+ 1,000,000.00 +
+
+
+ Amount Received +
+
+ 800,000.00 +
+
+
+ Remaining Balance +
+
+ 200,000.00 +
+
+
+
+
+
+ + + + + +
+ Budgeted Expenditure +
+
+ 800,000.00 +
+
+
+ Actual Expenditure +
+
+ 760,000.00 +
+
+
+ Remaining Balance +
+
+ 40,000.00 +
+
+
+
+
+
+ + + +
+ +
+
+
+
+
+ + ); +}; + +export default ProjectCashFlow; diff --git a/src/components/ProjectCashFlow/index.ts b/src/components/ProjectCashFlow/index.ts new file mode 100644 index 0000000..af238d3 --- /dev/null +++ b/src/components/ProjectCashFlow/index.ts @@ -0,0 +1 @@ +export { default } from "./ProjectCashFlow"; diff --git a/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx b/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx new file mode 100644 index 0000000..25ff90e --- /dev/null +++ b/src/components/ProjectFinancialSummary/ProjectFinancialCard.tsx @@ -0,0 +1,173 @@ +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord, AnyCnameRecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; + +interface Props { + Title: string; + TotalActiveProjectNumber: string; + TotalFees: string; + TotalBudget: string; + TotalCumulative: string; + TotalInvoicedAmount: string; + TotalReceivedAmount: string; + CashFlowStatus: string; + CostPerformanceIndex: string; + ClickedIndex: number; + Index: number; +} + +const ProjectFinancialCard: React.FC = ({ + Title, + TotalActiveProjectNumber, + TotalFees, + TotalBudget, + TotalCumulative, + TotalInvoicedAmount, + TotalReceivedAmount, + CashFlowStatus, + CostPerformanceIndex, + ClickedIndex, + Index, +}) => { + const [SearchCriteria, setSearchCriteria] = React.useState({}); + const { t } = useTranslation("dashboard"); + const borderColor = + CashFlowStatus === "Negative" + ? "border-red-300 border-solid" + : "border-green-200 border-solid"; + const selectedBackgroundColor = + ClickedIndex === Index ? "rgb(235 235 235)" : "rgb(255 255 255)"; + console.log(ClickedIndex); + console.log(Index); + return ( + +
+ {Title} +
+
+
+ Total Active Project +
+
+ {TotalActiveProjectNumber} +
+
+
+ Total Fees +
+
+ {TotalFees} +
+
+
+ Total Budget +
+
+ {TotalBudget} +
+
+
+ Total Cumulative Expenditure +
+
+ {TotalCumulative} +
+
+
+ Total Invoiced Amount +
+
+ {TotalInvoicedAmount} +
+
+
+ Total Received Amount +
+
+ {TotalReceivedAmount} +
+
+
+ Cash Flow Status +
+ {CashFlowStatus === "Negative" && ( + <> +
+ {CashFlowStatus} +
+
+ + )} + {CashFlowStatus === "Positive" && ( + <> +
+ {CashFlowStatus} +
+
+ + )} +
+ Cost Performance Index (CPI) +
+ {Number(CostPerformanceIndex) < 1 && ( + <> +
+ {CostPerformanceIndex} +
+ + )} + {Number(CostPerformanceIndex) >= 1 && ( + <> +
+ {CostPerformanceIndex} +
+ + )} +
+ ); +}; + +export default ProjectFinancialCard; diff --git a/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx b/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx new file mode 100644 index 0000000..e9839c9 --- /dev/null +++ b/src/components/ProjectFinancialSummary/ProjectFinancialSummary.tsx @@ -0,0 +1,465 @@ +"use client"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord, AnyCnameRecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import ProjectFinancialCard from "./ProjectFinancialCard"; + +const ProjectFinancialSummary: React.FC = () => { + const [SearchCriteria, setSearchCriteria] = React.useState({}); + const { t } = useTranslation("dashboard"); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const projectFinancialData = [ + { + id: 1, + title: "All Teams", + activeProject: "147", + fees: "22,800,000.00", + budget: "18,240,000.00", + cumulativeExpenditure: "17,950,000.00", + invoicedAmount: "18,240,000.00", + receivedAmount: "10,900,000.00", + cashFlowStatus: "Negative", + CPI: "0.69", + }, + { + id: 2, + title: "XXX Team", + activeProject: "25", + fees: "1,500,000.00", + budget: "1,200,000.00", + cumulativeExpenditure: "1,250,000.00", + invoicedAmount: "900,000.00", + receivedAmount: "650,000.00", + cashFlowStatus: "Negative", + CPI: "0.72", + }, + { + id: 3, + title: "YYY Team", + activeProject: "35", + fees: "5,000,000.00", + budget: "4,000,000.00", + cumulativeExpenditure: "3,200,000.00", + invoicedAmount: "3,500,000.00", + receivedAmount: "3,500,000.00", + cashFlowStatus: "Positive", + CPI: "1.09", + }, + { + id: 4, + title: "ZZZ Team", + activeProject: "50", + fees: "3,500,000.00", + budget: "2,800,000.00", + cumulativeExpenditure: "5,600,000.00", + invoicedAmount: "2,500,000.00", + receivedAmount: "2,200,000.00", + cashFlowStatus: "Negative", + CPI: "0.45", + }, + { + id: 5, + title: "AAA Team", + activeProject: "15", + fees: "4,800,000.00", + budget: "3,840,000.00", + cumulativeExpenditure: "2,500,000.00", + invoicedAmount: "1,500,000.00", + receivedAmount: "750,000.00", + cashFlowStatus: "Negative", + CPI: "0.60", + }, + { + id: 6, + title: "BBB Team", + activeProject: "22", + fees: "8,000,000.00", + budget: "6,400,000.00", + cumulativeExpenditure: "5,400,000.00", + invoicedAmount: "4,000,000.00", + receivedAmount: "3,800,000.00", + cashFlowStatus: "Negative", + CPI: "0.74", + }, + ]; + + const rows0 = [{id: 1,projectCode:"M1201",projectName:"Consultancy Project C", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "01/05/2024", client:"Client A", subsidiary:"N/A"}, + {id: 2,projectCode:"M1321",projectName:"Consultancy Project CCC", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "20/01/2024", client:"Client E", subsidiary:"Subsidiary B"}, + {id: 3,projectCode:"M1001",projectName:"Consultancy Project A", team:"YYY", teamLeader:"YYY", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"}, + {id: 4,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"YYY", teamLeader:"YYY", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"}, + {id: 5,projectCode:"M1354",projectName:"Consultancy Project BBB", team:"YYY", teamLeader:"YYY", startDate:"01/02/2023", targetEndDate: "31/01/2024", client:"Client D", subsidiary:"Subsidiary C"} + ] + + const rows1 = [{id: 1,projectCode:"M1201",projectName:"Consultancy Project C", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "01/05/2024", client:"Client A", subsidiary:"N/A"}, + {id: 2,projectCode:"M1321",projectName:"Consultancy Project CCC", team:"XXX", teamLeader:"XXX", startDate:"01/08/2022", targetEndDate: "20/01/2024", client:"Client E", subsidiary:"Subsidiary B"}, + ] + + const rows2 = [{id: 3,projectCode:"M1001",projectName:"Consultancy Project A", team:"YYY", teamLeader:"YYY", startDate:"01/07/2022", targetEndDate: "01/04/2024", client:"Client B", subsidiary:"N/A"}, + {id: 4,projectCode:"M1301",projectName:"Consultancy Project AAAA", team:"YYY", teamLeader:"YYY", startDate:"01/09/2022", targetEndDate: "20/02/2024", client:"Client C", subsidiary:"Subsidiary A"}, + {id: 5,projectCode:"M1354",projectName:"Consultancy Project BBB", team:"YYY", teamLeader:"YYY", startDate:"01/02/2023", targetEndDate: "31/01/2024", client:"Client D", subsidiary:"Subsidiary C"} + ] + + const projectFinancialRows = [{id: 1,projectCode:"M1354",projectName:"Consultanct Project BBB",clientName:"Client D",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"} + ] + + const clientFinancialRows =[{id: 1,clientCode:"Cust-02",clientName:"Client B",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}, + {id: 2,clientCode:"Cust-03",clientName:"Client C",totalProjectInvolved:"1",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"}, + {id: 3,clientCode:"Cust-04",clientName:"Client D",totalProjectInvolved:"4",cashFlowStatus:"Positive",cpi:"1.25", totalFees:"500,000.00", totalBudget:"400,000.00", totalCumulativeExpenditure:"280,000.00", totalInvoicedAmount: "350,000.00", totalUnInvoicedAmount:"150,000.00", totalReceivedAmount:"350,000.00"} + ] + + const [isCardClickedIndex, setIsCardClickedIndex] = React.useState(0); + + const [selectedTeamData, setSelectedTeamData]: any[] = React.useState(rows0); + + const handleCardClick = (r: any) => { + setIsCardClickedIndex(r); + if (r === 0) { + setSelectedTeamData(rows0); + } else if (r === 1) { + setSelectedTeamData(rows1); + } else if (r === 2) { + setSelectedTeamData(rows2); + } + }; + + const columns = [ + { + id: 'clientCode', + field: 'clientCode', + headerName: "Client Code", + flex: 0.7, + }, + { + id: 'clientName', + field: 'clientName', + headerName: "Client Name", + flex: 1, + }, + { + id: 'totalProjectInvolved', + field: 'totalProjectInvolved', + headerName: "Total Project Involved", + flex: 1, + }, + { + id: 'cashFlowStatus', + field: 'cashFlowStatus', + headerName: "Cash Flow Status", + flex: 1, + renderCell: (params:any) => { + if (params.row.cashFlowStatus === "Positive") { + return ( + {params.row.cashFlowStatus} + ) + } else if (params.row.cashFlowStatus === "Negative") { + return ( + {params.row.cashFlowStatus} + ) + } + }, + }, + { + id: 'cpi', + field: 'cpi', + headerName: "CPI", + flex: 0.7, + renderCell: (params:any) => { + if (params.row.cpi >= 1) { + return ( + {params.row.cpi} + ) + } else if (params.row.cpi < 1) { + return ( + {params.row.cpi} + ) + } + }, + }, + { + id: 'totalFees', + field: 'totalFees', + headerName: "Total Fees (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalFees} + ) + }, + }, + { + id: 'totalBudget', + field: 'totalBudget', + headerName: "Total Budget (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalBudget} + ) + }, + }, + { + id: 'totalCumulativeExpenditure', + field: 'totalCumulativeExpenditure', + headerName: "Total Cumulative Expenditure (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalCumulativeExpenditure} + ) + }, + }, + { + id: 'totalInvoicedAmount', + field: 'totalInvoicedAmount', + headerName: "Total Invoiced Amount (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalInvoicedAmount} + ) + }, + }, + { + id: 'totalUnInvoicedAmount', + field: 'totalUnInvoicedAmount', + headerName: "Total Un-invoiced Amount (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalUnInvoicedAmount} + ) + }, + }, + { + id: 'totalReceivedAmount', + field: 'totalReceivedAmount', + headerName: "Total Received Amount (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalReceivedAmount} + ) + }, + }, + + // { + // id: 'projectCode', + // field: 'projectCode', + // headerName: "Project Code", + // flex: 1, + // }, + // { + // id: 'projectName', + // field: 'projectName', + // headerName: "Project Name", + // flex: 1, + // }, + // { + // id: 'team', + // field: 'team', + // headerName: "Team", + // flex: 1, + // }, + // { + // id: 'teamLeader', + // field: 'teamLeader', + // headerName: "Team Leader", + // flex: 1, + // }, + // { + // id: 'startDate', + // field: 'startDate', + // headerName: "Start Date", + // flex: 1, + // }, + // { + // id: 'targetEndDate', + // field: 'targetEndDate', + // headerName: "Target End Date", + // flex: 1, + // }, + // { + // id: 'client', + // field: 'client', + // headerName: "Client", + // flex: 1, + // }, + // { + // id: 'subsidiary', + // field: 'subsidiary', + // headerName: "Subsidiary", + // flex: 1, + // }, +]; + +const columns2 = [ + { + id: 'projectCode', + field: 'projectCode', + headerName: "Project Code", + flex: 0.7, + }, + { + id: 'projectName', + field: 'projectName', + headerName: "Project Name", + flex: 1, + }, + { + id: 'clientName', + field: 'clientName', + headerName: "Client Name", + flex: 1, + }, + { + id: 'cashFlowStatus', + field: 'cashFlowStatus', + headerName: "Cash Flow Status", + flex: 1, + renderCell: (params:any) => { + if (params.row.cashFlowStatus === "Positive") { + return ( + {params.row.cashFlowStatus} + ) + } else if (params.row.cashFlowStatus === "Negative") { + return ( + {params.row.cashFlowStatus} + ) + } + }, + }, + { + id: "cpi", + field: "cpi", + headerName: "CPI", + flex: 0.7, + renderCell: (params: any) => { + if (params.row.cpi >= 1) { + return {params.row.cpi}; + } else if (params.row.cpi < 1) { + return {params.row.cpi}; + } + }, + }, + +{ + id: 'totalFees', + field: 'totalFees', + headerName: "Total Fees (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalFees} + ) + }, +}, +{ + id: 'totalBudget', + field: 'totalBudget', + headerName: "Total Budget (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalBudget} + ) +}, +}, +{ + id: 'totalCumulativeExpenditure', + field: 'totalCumulativeExpenditure', + headerName: "Total Cumulative Expenditure (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalCumulativeExpenditure} + ) + }, +}, +{ + id: 'totalInvoicedAmount', + field: 'totalInvoicedAmount', + headerName: "Total Invoiced Amount (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalInvoicedAmount} + ) + }, +}, +{ + id: 'totalUnInvoicedAmount', + field: 'totalUnInvoicedAmount', + headerName: "Total Un-invoiced Amount (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalUnInvoicedAmount} + ) + }, +}, +{ + id: 'totalReceivedAmount', + field: 'totalReceivedAmount', + headerName: "Total Received Amount (HKD)", + flex: 1, + renderCell: (params:any) => { + return ( + ${params.row.totalReceivedAmount} + ) + }, +}, +]; + + const handleSelectionChange = (newSelectionModel: GridRowSelectionModel) => { + const selectedRowsData = selectedTeamData.filter((row: any) => + newSelectionModel.includes(row.id), + ); + console.log(selectedRowsData); + }; + + return ( + + + +
+ {projectFinancialData.map((record, index) => ( +
handleCardClick(index)}> + +
+ ))} +
+
+ + +
+ {/* */} + +
+
+ + +
+ +
+
+
+ ); +}; + +export default ProjectFinancialSummary; diff --git a/src/components/ProjectFinancialSummary/index.ts b/src/components/ProjectFinancialSummary/index.ts new file mode 100644 index 0000000..724bb4a --- /dev/null +++ b/src/components/ProjectFinancialSummary/index.ts @@ -0,0 +1 @@ +export { default } from "./ProjectFinancialSummary"; diff --git a/src/components/ProjectSearch/ProjectSearch.tsx b/src/components/ProjectSearch/ProjectSearch.tsx new file mode 100644 index 0000000..903f7cc --- /dev/null +++ b/src/components/ProjectSearch/ProjectSearch.tsx @@ -0,0 +1,100 @@ +"use client"; + +import { ProjectResult } from "@/app/api/projects"; +import React, { useCallback, useMemo, useState } from "react"; +import SearchBox, { Criterion } from "../SearchBox"; +import { useTranslation } from "react-i18next"; +import SearchResults, { Column } from "../SearchResults"; +import EditNote from "@mui/icons-material/EditNote"; + +interface Props { + projects: ProjectResult[]; +} + +type SearchQuery = Partial>; +type SearchParamNames = keyof SearchQuery; + +const ProjectSearch: React.FC = ({ projects }) => { + const { t } = useTranslation("projects"); + + // If project searching is done on the server-side, then no need for this. + const [filteredProjects, setFilteredProjects] = useState(projects); + + const searchCriteria: Criterion[] = useMemo( + () => [ + { label: t("Project code"), paramName: "code", type: "text" }, + { label: t("Project name"), paramName: "name", type: "text" }, + { + label: t("Client name"), + paramName: "client", + type: "select", + options: ["Client A", "Client B", "Client C"], + }, + { + label: t("Project category"), + paramName: "category", + type: "select", + options: ["Confirmed Project", "Project to be bidded"], + }, + { + label: t("Team"), + paramName: "team", + type: "select", + options: ["TW", "WY"], + }, + ], + [t], + ); + + const onReset = useCallback(() => { + setFilteredProjects(projects); + }, [projects]); + + const onProjectClick = useCallback((project: ProjectResult) => { + console.log(project); + }, []); + + const columns = useMemo[]>( + () => [ + { + name: "id", + label: t("Details"), + onClick: onProjectClick, + buttonIcon: , + }, + { name: "code", label: t("Project Code") }, + { name: "name", label: t("Project Name") }, + { name: "category", label: t("Project Category") }, + { name: "team", label: t("Team") }, + { name: "client", label: t("Client") }, + ], + [t, onProjectClick], + ); + + return ( + <> + { + setFilteredProjects( + projects.filter( + (p) => + p.code.toLowerCase().includes(query.code.toLowerCase()) && + p.name.toLowerCase().includes(query.name.toLowerCase()) && + (query.client === "All" || p.client === query.client) && + (query.category === "All" || p.category === query.category) && + (query.team === "All" || p.team === query.team), + ), + ); + }} + onReset={onReset} + /> + + items={filteredProjects} + columns={columns} + /> + + ); +}; + +export default ProjectSearch; diff --git a/src/components/ProjectSearch/ProjectSearchLoading.tsx b/src/components/ProjectSearch/ProjectSearchLoading.tsx new file mode 100644 index 0000000..0917c75 --- /dev/null +++ b/src/components/ProjectSearch/ProjectSearchLoading.tsx @@ -0,0 +1,40 @@ +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Skeleton from "@mui/material/Skeleton"; +import Stack from "@mui/material/Stack"; +import React from "react"; + +// Can make this nicer +export const ProjectSearchLoading: React.FC = () => { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + ); +}; + +export default ProjectSearchLoading; diff --git a/src/components/ProjectSearch/ProjectSearchWrapper.tsx b/src/components/ProjectSearch/ProjectSearchWrapper.tsx new file mode 100644 index 0000000..737a1ef --- /dev/null +++ b/src/components/ProjectSearch/ProjectSearchWrapper.tsx @@ -0,0 +1,18 @@ +import { fetchProjects } from "@/app/api/projects"; +import React from "react"; +import ProjectSearch from "./ProjectSearch"; +import ProjectSearchLoading from "./ProjectSearchLoading"; + +interface SubComponents { + Loading: typeof ProjectSearchLoading; +} + +const ProjectSearchWrapper: React.FC & SubComponents = async () => { + const projects = await fetchProjects(); + + return ; +}; + +ProjectSearchWrapper.Loading = ProjectSearchLoading; + +export default ProjectSearchWrapper; diff --git a/src/components/ProjectSearch/index.ts b/src/components/ProjectSearch/index.ts new file mode 100644 index 0000000..bce975d --- /dev/null +++ b/src/components/ProjectSearch/index.ts @@ -0,0 +1 @@ +export { default } from "./ProjectSearchWrapper"; diff --git a/src/components/SearchBox/SearchBox.tsx b/src/components/SearchBox/SearchBox.tsx new file mode 100644 index 0000000..56c9b13 --- /dev/null +++ b/src/components/SearchBox/SearchBox.tsx @@ -0,0 +1,201 @@ +"use client"; + +import Grid from "@mui/material/Grid"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import Typography from "@mui/material/Typography"; +import React, { useCallback, useMemo, useState } from "react"; +import { useTranslation } from "react-i18next"; +import TextField from "@mui/material/TextField"; +import FormControl from "@mui/material/FormControl"; +import InputLabel from "@mui/material/InputLabel"; +import Select, { SelectChangeEvent } from "@mui/material/Select"; +import MenuItem from "@mui/material/MenuItem"; +import CardActions from "@mui/material/CardActions"; +import Button from "@mui/material/Button"; +import RestartAlt from "@mui/icons-material/RestartAlt"; +import Search from "@mui/icons-material/Search"; +import dayjs from "dayjs"; +import "dayjs/locale/zh-hk"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import { Box } from "@mui/material"; + +interface BaseCriterion { + label: string; + label2?: string; + paramName: T; + paramName2?: T; +} + +interface TextCriterion extends BaseCriterion { + type: "text"; +} + +interface SelectCriterion extends BaseCriterion { + type: "select"; + options: string[]; +} + +interface DateRangeCriterion extends BaseCriterion { + type: "dateRange"; +} + +export type Criterion = + | TextCriterion + | SelectCriterion + | DateRangeCriterion; + +interface Props { + criteria: Criterion[]; + onSearch: (inputs: Record) => void; + onReset?: () => void; +} + +function SearchBox({ + criteria, + onSearch, + onReset, +}: Props) { + const { t } = useTranslation("common"); + const defaultInputs = useMemo( + () => + criteria.reduce>( + (acc, c) => { + return { ...acc, [c.paramName]: c.type === "select" ? "All" : "" }; + }, + {} as Record, + ), + [criteria], + ); + const [inputs, setInputs] = useState(defaultInputs); + + const makeInputChangeHandler = useCallback( + (paramName: T): React.ChangeEventHandler => { + return (e) => { + setInputs((i) => ({ ...i, [paramName]: e.target.value })); + }; + }, + [], + ); + + const makeSelectChangeHandler = useCallback((paramName: T) => { + return (e: SelectChangeEvent) => { + setInputs((i) => ({ ...i, [paramName]: e.target.value })); + }; + }, []); + + const makeDateChangeHandler = useCallback((paramName: T) => { + return (e: any) => { + setInputs((i) => ({ ...i, [paramName]: dayjs(e).format("YYYY-MM-DD") })); + }; + }, []); + + const makeDateToChangeHandler = useCallback((paramName: T) => { + return (e: any) => { + setInputs((i) => ({ + ...i, + [paramName + "To"]: dayjs(e).format("YYYY-MM-DD"), + })); + }; + }, []); + + const handleReset = () => { + setInputs(defaultInputs); + onReset?.(); + }; + + const handleSearch = () => { + onSearch(inputs); + }; + + return ( + + + {t("Search Criteria")} + + {criteria.map((c) => { + return ( + + {c.type === "text" && ( + + )} + {c.type === "select" && ( + + {c.label} + + + )} + {c.type === "dateRange" && ( + + + + + + + {"-"} + + + + + + + )} + + ); + })} + + + + + + + + ); +} + +export default SearchBox; diff --git a/src/components/SearchBox/index.ts b/src/components/SearchBox/index.ts new file mode 100644 index 0000000..c4da6a2 --- /dev/null +++ b/src/components/SearchBox/index.ts @@ -0,0 +1,2 @@ +export { default } from "./SearchBox"; +export type { Criterion } from "./SearchBox"; diff --git a/src/components/SearchResults/SearchResults.tsx b/src/components/SearchResults/SearchResults.tsx new file mode 100644 index 0000000..4c82280 --- /dev/null +++ b/src/components/SearchResults/SearchResults.tsx @@ -0,0 +1,126 @@ +"use client"; + +import React from "react"; +import Paper from "@mui/material/Paper"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TablePagination, { + TablePaginationProps, +} from "@mui/material/TablePagination"; +import TableRow from "@mui/material/TableRow"; +import IconButton from "@mui/material/IconButton"; + +export interface ResultWithId { + id: string | number; +} + +interface BaseColumn { + name: keyof T; + label: string; +} + +interface ColumnWithAction extends BaseColumn { + onClick: (item: T) => void; + buttonIcon: React.ReactNode; +} + +export type Column = + | BaseColumn + | ColumnWithAction; + +interface Props { + items: T[]; + columns: Column[]; + noWrapper?: boolean; +} + +function isActionColumn( + column: Column, +): column is ColumnWithAction { + return Boolean((column as ColumnWithAction).onClick); +} + +function SearchResults({ + items, + columns, + noWrapper, +}: Props) { + const [page, setPage] = React.useState(0); + const [rowsPerPage, setRowsPerPage] = React.useState(10); + + const handleChangePage: TablePaginationProps["onPageChange"] = ( + _event, + newPage, + ) => { + setPage(newPage); + }; + + const handleChangeRowsPerPage: TablePaginationProps["onRowsPerPageChange"] = ( + event, + ) => { + setRowsPerPage(+event.target.value); + setPage(0); + }; + + const table = ( + <> + + + + + {columns.map((column, idx) => ( + + {column.label} + + ))} + + + + {items + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((item) => { + return ( + + {columns.map((column, idx) => { + const columnName = column.name; + + return ( + + {isActionColumn(column) ? ( + column.onClick(item)} + > + {column.buttonIcon} + + ) : ( + <>{item[columnName]} + )} + + ); + })} + + ); + })} + +
+
+ + + ); + + return noWrapper ? table : {table}; +} + +export default SearchResults; diff --git a/src/components/SearchResults/index.ts b/src/components/SearchResults/index.ts new file mode 100644 index 0000000..5671101 --- /dev/null +++ b/src/components/SearchResults/index.ts @@ -0,0 +1,2 @@ +export { default } from "./SearchResults"; +export type { Column } from "./SearchResults"; diff --git a/src/components/StaffUtilization/StaffUtilization.tsx b/src/components/StaffUtilization/StaffUtilization.tsx new file mode 100644 index 0000000..81dde4b --- /dev/null +++ b/src/components/StaffUtilization/StaffUtilization.tsx @@ -0,0 +1,1203 @@ +"use client"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useState, useEffect, useMemo } from "react"; +import Paper from "@mui/material/Paper"; +import { TFunction } from "i18next"; +import { useTranslation } from "react-i18next"; +import { Card, CardHeader } from "@mui/material"; +import CustomSearchForm from "../CustomSearchForm/CustomSearchForm"; +import CustomDatagrid from "../CustomDatagrid/CustomDatagrid"; +import ReactApexChart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { GridColDef, GridRowSelectionModel } from "@mui/x-data-grid"; +import ReportProblemIcon from "@mui/icons-material/ReportProblem"; +import dynamic from "next/dynamic"; +import "../../app/global.css"; +import { AnyARecord, AnyCnameRecord } from "dns"; +import SearchBox, { Criterion } from "../SearchBox"; +import ProgressByClientSearch from "@/components/ProgressByClientSearch"; +import { Suspense } from "react"; +import ProgressCashFlowSearch from "@/components/ProgressCashFlowSearch"; +import { Input, Label } from "reactstrap"; +import Select, { components } from "react-select"; +import { DateCalendar } from "@mui/x-date-pickers/DateCalendar"; +import { DatePicker } from "@mui/x-date-pickers/DatePicker"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; +import dayjs, { Dayjs } from "dayjs"; +import isBetweenPlugin from "dayjs/plugin/isBetween"; +import { PickersDay, PickersDayProps } from "@mui/x-date-pickers/PickersDay"; +import { styled } from "@mui/material/styles"; + +dayjs.extend(isBetweenPlugin); +interface CustomPickerDayProps extends PickersDayProps { + isSelected: boolean; + isHovered: boolean; +} + +const CustomPickersDay = styled(PickersDay, { + shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isHovered", +})(({ theme, isSelected, isHovered, day }) => ({ + borderRadius: 0, + ...(isSelected && { + backgroundColor: theme.palette.primary.main, + color: theme.palette.primary.contrastText, + "&:hover, &:focus": { + backgroundColor: theme.palette.primary.main, + }, + }), + ...(isHovered && { + backgroundColor: theme.palette.primary[theme.palette.mode], + "&:hover, &:focus": { + backgroundColor: theme.palette.primary[theme.palette.mode], + }, + }), + ...(day.day() === 0 && { + borderTopLeftRadius: "50%", + borderBottomLeftRadius: "50%", + }), + ...(day.day() === 6 && { + borderTopRightRadius: "50%", + borderBottomRightRadius: "50%", + }), +})) as React.ComponentType; + +const isInSameWeek = (dayA: Dayjs, dayB: Dayjs | null | undefined) => { + if (dayB == null) { + return false; + } + + return dayA.isSame(dayB, "week"); +}; + +function Day( + props: PickersDayProps & { + selectedDay?: Dayjs | null; + hoveredDay?: Dayjs | null; + }, +) { + const { day, selectedDay, hoveredDay, ...other } = props; + + return ( + + ); +} + +const StaffUtilization: React.FC = () => { + const todayDate = new Date(); + const firstDayOfWeek = new Date(); + const lastDayOfWeek = new Date(); + firstDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 1); + lastDayOfWeek.setDate(todayDate.getDate() - todayDate.getDay() + 7); + const firstDayOfMonth = new Date( + todayDate.getFullYear(), + todayDate.getMonth(), + 1, + ); + const lastDayOfMonth = new Date( + todayDate.getFullYear(), + todayDate.getMonth() + 1, + 0, + ); + const [firstDayOfWeekString, setFirstDayOfWeekString] = React.useState( + dayjs(firstDayOfWeek).format("DD MMM YYYY"), + ); + const [lastDayOfWeekString, setLastDayOfWeekString] = React.useState( + dayjs(lastDayOfWeek).format("DD MMM YYYY"), + ); + const [firstDayOfMonthString, setFirstDayOfMonthString] = React.useState( + dayjs(firstDayOfMonth).format("DD MMM YYYY"), + ); + const [lastDayOfMonthString, setLastDayOfMonthString] = React.useState( + dayjs(lastDayOfMonth).format("DD MMM YYYY"), + ); + const [selectionModel, setSelectionModel]: any[] = React.useState([]); + const [manHoursSpentPeriod, setManHoursSpentPeriod]: any[] = React.useState( + firstDayOfWeekString + " to " + lastDayOfWeekString, + ); + const [teamTotalManhoursSpentSelect, setTeamTotalManhoursSpentSelect]: any = + React.useState("Weekly"); + const [staffGradeManhoursSpentSelect, setStaffGradeManhoursSpentSelect]: any = + React.useState("Weekly"); + const [ + individualStaffManhoursSpentSelect, + setIndividualStaffManhoursSpentSelect, + ]: any = React.useState("Daily"); + const weekDates: any[] = []; + const monthDates: any[] = []; + const currentDate = dayjs(); + const sixMonthsAgo = currentDate.subtract(6, "month"); + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + for ( + let date = sixMonthsAgo.clone(); + date.isBefore(currentDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + } + monthDates.push(currentDate.format("MM-YYYY")); + // for (let i = firstDayOfMonth.getDate(); i <= lastDayOfMonth.getDate(); i++) { + // const currentDate = new Date(todayDate.getFullYear(), todayDate.getMonth(), i); + // const formattedDate = dayjs(currentDate).format('DD MMM'); + // monthDates.push(formattedDate); + // } + const [teamTotalManhoursSpentPeriod, setTeamTotalManhoursSpentPeriod]: any[] = + React.useState(weekDates); + const [ + teamTotalManhoursByStaffGrade, + setTeamTotalManhoursByStaffGrade, + ]: any[] = React.useState(weekDates); + const [ + individualStaffManhoursSpentPeriod, + setIndividualStaffManhoursSpentPeriod, + ]: any[] = React.useState(weekDates); + const [ + teamTotalManhoursSpentPlanData, + setTeamTotalManhoursSpentPlanData, + ]: any[] = React.useState([42, 42, 42, 42, 42, 0, 0]); + const [ + teamTotalManhoursSpentActualData, + setTeamTotalManhoursSpentActualData, + ]: any[] = React.useState([45, 42, 60, 42, 58, 0, 0]); + const [hoveredDay, setHoveredDay] = React.useState(null); + const [value, setValue] = React.useState(dayjs()); + const [weeklyValueByStaffGrade, setWeeklyValueByStaffGrade] = + React.useState(dayjs()); + const [weeklyValueByIndividualStaff, setWeeklyValueByIndividualStaff] = + React.useState(dayjs()); + const [staffGradeManhoursSpentValue, setStaffGradeManhoursSpentValue] = + React.useState(dayjs()); + const [totalManHoursMonthlyFromValue, setTotalManHoursMonthlyFromValue] = + React.useState(dayjs(new Date()).subtract(6, "month")); + const [totalManHoursMonthlyToValue, setTotalManHoursMonthlyToValue] = + React.useState(dayjs()); + const [ + totalManHoursByStaffGradeMonthlyFromValue, + setTotalManHoursByStaffGradeMonthlyFromValue, + ] = React.useState(dayjs(new Date()).subtract(6, "month")); + const [ + totalManHoursByStaffGradeMonthlyToValue, + setTotalManHoursByStaffGradeMonthlyToValue, + ] = React.useState(dayjs()); + const [ + totalManHoursByIndividualStaffMonthlyFromValue, + setTotalManHoursByIndividualStaffMonthlyFromValue, + ] = React.useState(dayjs(new Date()).subtract(6, "month")); + const [ + totalManHoursByIndividualStaffMonthlyToValue, + setTotalManHoursByIndividualStaffMonthlyToValue, + ] = React.useState(dayjs()); + const [ + totalManHoursByIndividualStaffDailyFromValue, + setTotalManHoursByIndividualStaffDailyFromValue, + ] = React.useState(dayjs(new Date()).subtract(6, "day")); + const [ + totalManHoursByIndividualStaffDailyToValue, + setTotalManHoursByIndividualStaffDailyToValue, + ] = React.useState(dayjs()); + const [totalManHoursMaxValue, setTotalManHoursMaxValue] = React.useState(75); + + const teamOptions = [ + { value: 1, label: "XXX Team" }, + { value: 2, label: "YYY Team" }, + { value: 3, label: "ZZZ Team" }, + ]; + + const columns = [ + { + id: "projectCode", + field: "projectCode", + headerName: "Project Code", + flex: 1, + }, + { + id: "projectName", + field: "projectName", + headerName: "Project Name", + flex: 1, + }, + { + id: "team", + field: "team", + headerName: "Team", + flex: 1, + }, + { + id: "teamLeader", + field: "teamLeader", + headerName: "Team Leader", + flex: 1, + }, + { + id: "startDate", + field: "startDate", + headerName: "Start Date", + flex: 1, + }, + { + id: "targetEndDate", + field: "targetEndDate", + headerName: "Target End Date", + flex: 1, + }, + { + id: "client", + field: "client", + headerName: "Client", + flex: 1, + }, + { + id: "subsidiary", + field: "subsidiary", + headerName: "Subsidiary", + flex: 1, + }, + ]; + + const options: ApexOptions = { + chart: { + height: 350, + type: "line", + }, + stroke: { + width: [2, 2], + }, + plotOptions: { + bar: { + horizontal: false, + distributed: false, + }, + }, + dataLabels: { + enabled: true, + }, + xaxis: { + categories: teamTotalManhoursSpentPeriod, + }, + yaxis: [ + { + title: { + text: "Team Total Manhours Spent (Hour)", + }, + min: 0, + max: totalManHoursMaxValue, + tickAmount: 5, + }, + ], + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + series: [ + { + name: "Planned", + type: "line", + color: "#efbe7d", + data: teamTotalManhoursSpentPlanData, + }, + { + name: "Actual", + type: "line", + color: "#7cd3f2", + data: teamTotalManhoursSpentActualData, + }, + ], + }; + + const staffGradeOptions: ApexOptions = { + chart: { + height: 350, + type: "line", + }, + stroke: { + width: [2, 2], + }, + plotOptions: { + bar: { + horizontal: true, + distributed: false, + }, + }, + dataLabels: { + enabled: true, + }, + xaxis: { + categories: [ + "Grade 1: A. QS / QS Trainee", + "Grade 2: QS", + "Grade 3: Senior QS", + "Grade 4: Manager", + "Grade 5: Director", + ], + }, + yaxis: [ + { + title: { + text: "Staff Grade", + }, + min: 0, + max: 60, + tickAmount: 5, + }, + ], + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + series: [ + { + name: "Planned", + type: "bar", + color: "#efbe7d", + data: [35, 45, 35, 20, 10], + }, + { + name: "Actual", + type: "bar", + color: "#00acb1", + data: [25, 26, 33, 20, 11], + }, + ], + }; + + const individualStaffOptions: ApexOptions = { + chart: { + height: 350, + type: "line", + }, + stroke: { + width: [1], + }, + plotOptions: { + bar: { + horizontal: true, + distributed: false, + }, + }, + dataLabels: { + enabled: true, + }, + xaxis: { + categories: [ + "Consultancy Project 123 (CUST-001, Subsidiary A)", + "Consultancy Project 456 (CUST-001, Subsidiary A)", + "Construction Project A (CUST-001, Subsidiary A)", + "Construction Project B (CUST-001, Subsidiary A)", + "Construction Project C (CUST-001, Subsidiary A)", + ], + }, + yaxis: [ + { + title: { + text: "Project", + }, + min: 0, + max: 12, + tickAmount: 5, + }, + ], + grid: { + borderColor: "#f1f1f1", + }, + annotations: {}, + series: [ + { + name: "Manhours(Hour)", + type: "bar", + color: "#00acb1", + data: [12, 12, 11, 12, 0], + }, + ], + }; + + const teamTotalManhoursSpentOnClick = (r: any) => { + setTeamTotalManhoursSpentSelect(r); + if (r === "Weekly") { + setValue(dayjs(new Date())); + setTeamTotalManhoursSpentPeriod(weekDates); + setTeamTotalManhoursSpentPlanData([42, 42, 42, 42, 42, 0, 0]); + setTeamTotalManhoursSpentActualData([45, 42, 60, 42, 58, 0, 0]); + setTotalManHoursMaxValue(75); + } else if (r === "Monthly") { + setTeamTotalManhoursSpentPeriod(monthDates); + setTeamTotalManhoursSpentPlanData([840, 840, 840, 840, 840, 840]); + setTeamTotalManhoursSpentActualData([900, 840, 1200, 840, 1160, 840]); + setTotalManHoursMaxValue(1250); + } + }; + + const individualStaffManhoursSpentOnClick = (r: any) => { + setIndividualStaffManhoursSpentSelect(r); + // if (r === "Weekly") { + // setValue(dayjs(new Date)) + // setTeamTotalManhoursSpentPeriod(weekDates) + // setTeamTotalManhoursSpentPlanData([42,42,42,42,42,0,0]) + // setTeamTotalManhoursSpentActualData([45,42,60,42,58,0,0]) + // setTotalManHoursMaxValue(75) + // } else if (r === "Monthly") { + // setTeamTotalManhoursSpentPeriod(monthDates) + // setTeamTotalManhoursSpentPlanData([840,840,840,840,840,840]) + // setTeamTotalManhoursSpentActualData([900,840,1200,840,1160,840]) + // setTotalManHoursMaxValue(1250) + // } + }; + + const selectWeeklyPeriod = (r: any) => { + const selectDate = new Date(r); + const firstDayOfWeek = new Date(); + firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); + const weekDates: any[] = []; + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + setTeamTotalManhoursSpentPeriod(weekDates); + setValue(dayjs(firstDayOfWeek)); + }; + + const selectWeeklyPeriodByStaffGrade = (r: any) => { + const selectDate = new Date(r); + const firstDayOfWeek = new Date(); + firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); + const weekDates: any[] = []; + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + setTeamTotalManhoursByStaffGrade(weekDates); + setWeeklyValueByStaffGrade(dayjs(firstDayOfWeek)); + }; + + const selectWeeklyPeriodIndividualStaff = (r: any) => { + const selectDate = new Date(r); + const firstDayOfWeek = new Date(); + firstDayOfWeek.setDate(selectDate.getDate() - selectDate.getDay() + 0); + const weekDates: any[] = []; + for (let i = 0; i < 7; i++) { + const currentDate = new Date(firstDayOfWeek); + currentDate.setDate(firstDayOfWeek.getDate() + i); + const formattedDate = dayjs(currentDate).format("DD MMM (ddd)"); + weekDates.push(formattedDate); + } + setIndividualStaffManhoursSpentPeriod(weekDates); + setWeeklyValueByIndividualStaff(dayjs(firstDayOfWeek)); + }; + + const selectMonthlyPeriodFrom = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectFromDate = dayjs(r); + for ( + let date = selectFromDate.clone(); + date.isBefore(totalManHoursMonthlyToValue, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + setTeamTotalManhoursSpentPlanData(monthPlanData); + setTeamTotalManhoursSpentActualData(monthActualData); + setTeamTotalManhoursSpentPeriod(monthDates); + }; + + const selectMonthlyPeriodTo = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectToDate = dayjs(r); + for ( + let date = totalManHoursMonthlyFromValue.clone(); + date.isBefore(selectToDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(selectToDate.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + setTeamTotalManhoursSpentPlanData(monthPlanData); + setTeamTotalManhoursSpentActualData(monthActualData); + setTeamTotalManhoursSpentPeriod(monthDates); + }; + + const selectStaffGradeMonthlyPeriodFrom = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectFromDate = dayjs(r); + for ( + let date = selectFromDate.clone(); + date.isBefore(totalManHoursMonthlyToValue, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setTeamTotalManhoursByStaffGrade(weekDates); + }; + + const selectStaffGradeMonthlyPeriodTo = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectToDate = dayjs(r); + for ( + let date = totalManHoursMonthlyFromValue.clone(); + date.isBefore(selectToDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(selectToDate.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setTeamTotalManhoursByStaffGrade(weekDates); + }; + + const selectIndividualStaffMonthlyPeriodFrom = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectFromDate = dayjs(r); + for ( + let date = selectFromDate.clone(); + date.isBefore(totalManHoursMonthlyToValue, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(totalManHoursMonthlyToValue.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setIndividualStaffManhoursSpentPeriod(weekDates); + }; + + const selectIndividualStaffMonthlyPeriodTo = (r: any) => { + const monthDates: any[] = []; + const monthPlanData: any[] = []; + const monthActualData: any[] = []; + const selectToDate = dayjs(r); + for ( + let date = totalManHoursMonthlyFromValue.clone(); + date.isBefore(selectToDate, "month"); + date = date.add(1, "month") + ) { + monthDates.push(date.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + } + monthDates.push(selectToDate.format("MM-YYYY")); + monthPlanData.push(840); + monthActualData.push(Math.floor(Math.random() * (1200 - 840) + 840)); + // setTeamTotalManhoursSpentPlanData(monthPlanData) + // setTeamTotalManhoursSpentActualData(monthActualData) + setIndividualStaffManhoursSpentPeriod(weekDates); + }; + + const options2: ApexOptions = { + chart: { + type: "donut", + }, + colors: ['#f57f90','#94f7d6','#87c5f5','#ab95f5','#ab95f5'], + plotOptions: { + pie: { + donut: { + labels: { + show: true, + name: { + show: true, + }, + value: { + show: false, + fontWeight: 500, + fontSize: "30px", + color: "#3e98c7", + }, + total: { + show: false, + showAlways: true, + label: "Spent", + fontFamily: "sans-serif", + formatter: function (val) { + return val + "%"; + }, + }, + }, + }, + }, + }, + series:[23.5,25.5,25.5,25.5], + labels: ["Consultancy Project 123","Consultancy Project ABC","Consultancy Project A","Consultancy Project B"], + legend: { + show: false, + }, + responsive: [ + { + breakpoint: 480, + options: { + chart: { + width: 200, + }, + legend: { + position: "bottom", + show: false, + }, + }, + }, + ], + }; + + return ( + <> + +
+
+ + + +
+
+ {teamTotalManhoursSpentSelect === "Weekly" && ( + <> + + + + )} + {teamTotalManhoursSpentSelect === "Monthly" && ( + <> + + + + )} +
+
+
+ +
+
+ */} +
+
+ +
+
+
+
+
+
+ + + + +
+
+ {individualStaffManhoursSpentSelect === "Daily" && ( + <> + + + + + )} + {individualStaffManhoursSpentSelect === "Weekly" && ( + <> + + + + + )} + {individualStaffManhoursSpentSelect === "Monthly" && ( + <> + + + + + )} +
+
+
+ +
+
+ { + return ( + + {values.toSorted(compareFn).map((value) => ( + + {sortMap[value].label} + + ))} + + ); + }} + MenuProps={{ + slotProps: { + paper: { + sx: { maxHeight: 400 }, + }, + }, + anchorOrigin: { + vertical: "top", + horizontal: "left", + }, + transformOrigin: { + vertical: "top", + horizontal: "left", + }, + }} + > + + + + + + + {allItemsLabel} + {`${selectedItems.length}/${allItems.length} selected`} + + + + + {groups.flatMap((group) => { + const groupItems = groupedItems[group.id]; + if (!groupItems) return null; + + return [ + + {group.name} + , + ...groupItems.map((item) => { + return ( + + + + {item.label} + + + ); + }), + ]; + })} + + + + ); +}; + +export default MultiSelectList; diff --git a/src/components/TransferList/TransferList.tsx b/src/components/TransferList/TransferList.tsx new file mode 100644 index 0000000..c6ca4fb --- /dev/null +++ b/src/components/TransferList/TransferList.tsx @@ -0,0 +1,260 @@ +"use client"; + +import * as React from "react"; +import List from "@mui/material/List"; +import ListItem from "@mui/material/ListItem"; +import ListItemText from "@mui/material/ListItemText"; +import ListItemIcon from "@mui/material/ListItemIcon"; +import Checkbox from "@mui/material/Checkbox"; +import IconButton from "@mui/material/Fab"; +import Divider from "@mui/material/Divider"; +import ChevronLeft from "@mui/icons-material/ChevronLeft"; +import ChevronRight from "@mui/icons-material/ChevronRight"; +import intersection from "lodash/intersection"; +import differenceBy from "lodash/differenceBy"; +import Stack from "@mui/material/Stack"; +import Paper from "@mui/material/Paper"; +import Typography from "@mui/material/Typography"; +import ListSubheader from "@mui/material/ListSubheader"; +import groupBy from "lodash/groupBy"; +import uniqBy from "lodash/uniqBy"; +import { useTranslation } from "react-i18next"; + +export interface LabelGroup { + id: number; + name: string; +} + +export interface LabelWithId { + id: number; + label: string; + group?: LabelGroup; +} + +export interface TransferListProps { + allItems: LabelWithId[]; + initiallySelectedItems: LabelWithId[]; + onChange: (selectedItems: LabelWithId[]) => void; + allItemsLabel: string; + selectedItemsLabel: string; +} + +interface ItemListProps { + items: LabelWithId[]; + checkedItems: LabelWithId[]; + label: string; + handleToggleAll: ( + items: LabelWithId[], + checkedItems: LabelWithId[], + ) => React.MouseEventHandler; + handleToggle: (item: LabelWithId) => React.MouseEventHandler; +} + +const ItemList: React.FC = ({ + items, + checkedItems, + label, + handleToggle, + handleToggleAll, +}) => { + const { t } = useTranslation(); + const groups: LabelGroup[] = uniqBy( + [ + ...items.reduce((acc, item) => { + return item.group ? [...acc, item.group] : acc; + }, []), + // Items with no group + { id: 0, name: t("Ungrouped") }, + ], + "id", + ); + const groupedItems = groupBy(items, (item) => item.group?.id ?? 0); + + return ( + + + + + + + + {label} + {`${checkedItems.length}/${items.length} selected`} + + + + + } + > + {groups.map((group) => { + const groupItems = groupedItems[group.id]; + if (!groupItems) return null; + + return ( + + + {group.name} + + {groupItems.map((item) => { + return ( + + + + + + + ); + })} + + ); + })} + + + ); +}; + +const TransferList: React.FC = ({ + allItems, + initiallySelectedItems, + allItemsLabel, + selectedItemsLabel, + onChange, +}) => { + // Keep a map for the original order of items + const sortMap = React.useMemo(() => { + return allItems.reduce<{ [id: string]: number }>( + (acc, item, index) => ({ ...acc, [item.id]: index }), + {}, + ); + }, [allItems]); + const compareFn = React.useCallback( + (a: LabelWithId, b: LabelWithId) => sortMap[a.id] - sortMap[b.id], + [sortMap], + ); + + const [checkedList, setCheckedList] = React.useState([]); + const [leftList, setLeftList] = React.useState( + differenceBy(allItems, initiallySelectedItems, "id"), + ); + const [rightList, setRightList] = React.useState( + initiallySelectedItems, + ); + + const leftListChecked = intersection(checkedList, leftList); + const rightListChecked = intersection(checkedList, rightList); + + const handleToggle = React.useCallback( + (value: LabelWithId) => () => { + const isChecked = checkedList.includes(value); + const newCheckedList = isChecked + ? differenceBy(checkedList, [value], "id") + : [...checkedList, value]; + + setCheckedList(newCheckedList); + }, + [checkedList], + ); + + const handleToggleAll = React.useCallback( + (items: LabelWithId[], checkedItems: LabelWithId[]) => () => { + if (checkedItems.length === items.length) { + setCheckedList(differenceBy(checkedList, checkedItems, "id")); + } else { + setCheckedList([...checkedList, ...items]); + } + }, + [checkedList], + ); + + const handleCheckedRight = () => { + setRightList([...rightList, ...leftListChecked].sort(compareFn)); + setLeftList(differenceBy(leftList, leftListChecked, "id").sort(compareFn)); + setCheckedList(differenceBy(checkedList, leftListChecked, "id")); + }; + + const handleCheckedLeft = () => { + setLeftList([...leftList, ...rightListChecked].sort(compareFn)); + setRightList( + differenceBy(rightList, rightListChecked, "id").sort(compareFn), + ); + setCheckedList(differenceBy(checkedList, rightListChecked, "id")); + }; + + React.useEffect(() => { + onChange(rightList); + }, [onChange, rightList]); + + return ( + + + + + + + + + + + + + ); +}; + +export default TransferList; diff --git a/src/components/TransferList/TransferListWrapper.tsx b/src/components/TransferList/TransferListWrapper.tsx new file mode 100644 index 0000000..4668c47 --- /dev/null +++ b/src/components/TransferList/TransferListWrapper.tsx @@ -0,0 +1,15 @@ +"use client"; + +import React from "react"; +import TransferList, { TransferListProps } from "./TransferList"; +import { useMediaQuery, useTheme } from "@mui/material"; +import MultiSelectList from "./MultiSelectList"; + +const TransferListWrapper: React.FC = (props) => { + const theme = useTheme(); + const matches = useMediaQuery(theme.breakpoints.up("sm")); + + return matches ? : ; +}; + +export default TransferListWrapper; diff --git a/src/components/TransferList/index.ts b/src/components/TransferList/index.ts new file mode 100644 index 0000000..24888b4 --- /dev/null +++ b/src/components/TransferList/index.ts @@ -0,0 +1 @@ +export { default } from "./TransferListWrapper"; diff --git a/src/components/UserWorkspacePage/ProjectGrid.tsx b/src/components/UserWorkspacePage/ProjectGrid.tsx new file mode 100644 index 0000000..8cc37d5 --- /dev/null +++ b/src/components/UserWorkspacePage/ProjectGrid.tsx @@ -0,0 +1,100 @@ +"use client"; +import * as React from "react"; +import Grid from "@mui/material/Grid"; +import { useEffect } from "react"; +import { Card, CardContent, CardHeader } from "@mui/material"; +import CustomCardGrid from "../CustomCardGrid/CustomCardGrid"; +import "../../app/global.css"; +import { PROJECT_CARD_STYLE } from "@/theme/colorConst"; + +interface ProjectGridProps { + tab: number; +} + +const cards = [ + { + code: "M1001 (C)", + name: "Consultancy Project A", + hr_spent: 12.75, + hr_spent_normal: 0.0, + hr_alloc: 150.0, + hr_alloc_normal: 30.0, + }, + { + code: "M1301 (C)", + name: "Consultancy Project AAA", + hr_spent: 4.25, + hr_spent_normal: 0.25, + hr_alloc: 30.0, + hr_alloc_normal: 0.0, + }, + { + code: "M1354 (C)", + name: "Consultancy Project BBB", + hr_spent: 57.0, + hr_spent_normal: 6.5, + hr_alloc: 100.0, + hr_alloc_normal: 20.0, + }, + { + code: "M1973 (C)", + name: "Construction Project CCC", + hr_spent: 12.75, + hr_spent_normal: 0.0, + hr_alloc: 150.0, + hr_alloc_normal: 30.0, + }, + { + code: "M2014 (T)", + name: "Consultancy Project DDD", + hr_spent: 1.0, + hr_spent_normal: 0.0, + hr_alloc: 10.0, + hr_alloc_normal: 0.0, + }, +]; + +const ProjectGrid: React.FC = (props) => { + const [items, setItems] = React.useState([]); + + useEffect(() => { + if (props.tab == 0) { + setItems(cards); + } else { + const filteredItems = cards; //cards.filter(item => (item.track == props.tab)); + setItems(filteredItems); + } + }, [props.tab]); + + const cardLayout = (item: Record) => { + return ( + + + +

Hours Spent: {item.hr_spent}

+

Normal (Others): {item.hr_spent_normal}

+

Hours Allocated: {item.hr_alloc}

+

Normal (Others): {item.hr_alloc_normal}

+
+
+ ); + }; + // Apply the preset style to the cards in child, if not specified // + return ( + + {/* */} + {/* item count = {items?.length??"idk"} , track/tab = {props.tab} */} + + {/* */} + + ); +}; + +export default ProjectGrid; diff --git a/src/components/UserWorkspacePage/UserWorkspacePage.tsx b/src/components/UserWorkspacePage/UserWorkspacePage.tsx new file mode 100644 index 0000000..8fdb1cf --- /dev/null +++ b/src/components/UserWorkspacePage/UserWorkspacePage.tsx @@ -0,0 +1,81 @@ +"use client"; +import Grid from "@mui/material/Grid"; +import Paper from "@mui/material/Paper"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import AssignedProjectGrid from "../AssignedProjectGrid/AssignedProjectGrid"; +import PageTitle from "../PageTitle/PageTitle"; +import { Suspense } from "react"; +import Button from "@mui/material/Button"; +import Stack from "@mui/material/Stack"; +import { Add } from "@mui/icons-material"; +import Link from "next/link"; +import { t } from "i18next"; +import { Modal } from "@mui/material"; +import CustomModal from "../CustomModal/CustomModal"; +import EnterTimesheetModal from "../EnterTimesheet/EnterTimesheetModal"; +import EnterLeaveModal from "../EnterLeave/EnterLeaveModal"; + +const UserWorkspacePage: React.FC = () => { + const [isTimeheetModalVisible, setTimeheetModalVisible] = useState(false); + const [isLeaveModalVisible, setLeaveModalVisible] = useState(false); + const { t } = useTranslation("home"); + + const handleAddTimesheetButtonClick = () => { + setTimeheetModalVisible(true); + }; + + const handleCloseTimesheetModal = () => { + setTimeheetModalVisible(false); + }; + + const handleAddLeaveButtonClick = () => { + setLeaveModalVisible(true); + }; + + const handleCloseLeaveModal = () => { + setLeaveModalVisible(false); + }; + + return ( + + + +
+ + + + + {/*fallback={}>*/} +
+ + + +
+
+ ); +}; + +export default UserWorkspacePage; diff --git a/src/components/UserWorkspacePage/index.ts b/src/components/UserWorkspacePage/index.ts new file mode 100644 index 0000000..ec65d8f --- /dev/null +++ b/src/components/UserWorkspacePage/index.ts @@ -0,0 +1 @@ +export { default } from "./UserWorkspacePage"; diff --git a/src/config/api.ts b/src/config/api.ts new file mode 100644 index 0000000..376fd05 --- /dev/null +++ b/src/config/api.ts @@ -0,0 +1,2 @@ +export const BASE_API_URL = `${process.env.API_URL}`; +export const LOGIN_API_PATH = `${BASE_API_URL}/login`; diff --git a/src/config/authConfig.ts b/src/config/authConfig.ts new file mode 100644 index 0000000..e0c2860 --- /dev/null +++ b/src/config/authConfig.ts @@ -0,0 +1,58 @@ +import { AuthOptions, Session } from "next-auth"; +import CredentialsProvider from "next-auth/providers/credentials"; +import { LOGIN_API_PATH } from "./api"; + +export interface SessionWithTokens extends Session { + accessToken?: string; + refreshToken?: string; +} + +export const authOptions: AuthOptions = { + debug: process.env.NODE_ENV === "development", + providers: [ + CredentialsProvider({ + id: "credentials", + name: "Credentials", + credentials: { + username: { label: "Username", type: "text" }, + password: { label: "Password", type: "password" }, + }, + async authorize(credentials, req) { + const res = await fetch(LOGIN_API_PATH, { + method: "POST", + body: JSON.stringify(credentials), + headers: { "Content-Type": "application/json" }, + }); + + const user = await res.json(); + + if (res.ok && user) { + return user; + } + return null; + }, + }), + ], + pages: { + signIn: "/login", + }, + callbacks: { + jwt(params) { + // Add the data from user to the token + const { token, user } = params; + const newToken = { ...token, ...user }; + + return newToken; + }, + session({ session, token }) { + const sessionWithToken: SessionWithTokens = { + ...session, + // Add the data from the token to the session + accessToken: token.accessToken as string | undefined, + refreshToken: token.refreshToken as string | undefined, + }; + + return sessionWithToken; + }, + }, +}; diff --git a/src/config/uiConfig.ts b/src/config/uiConfig.ts new file mode 100644 index 0000000..f9d60b3 --- /dev/null +++ b/src/config/uiConfig.ts @@ -0,0 +1 @@ +export const NAVIGATION_CONTENT_WIDTH = "20rem"; diff --git a/src/i18n/I18nClientProvider.tsx b/src/i18n/I18nClientProvider.tsx new file mode 100644 index 0000000..0d2c13a --- /dev/null +++ b/src/i18n/I18nClientProvider.tsx @@ -0,0 +1,43 @@ +"use client"; + +import { createInstance, i18n } from "i18next"; +import React, { useMemo } from "react"; +import { I18nextProvider } from "react-i18next"; + +interface Props { + children: React.ReactNode; + language: string; + resources: { [ns: string]: any }; + namespaces: string[]; +} + +export const I18nContext = React.createContext(null); + +const I18nProvider: React.FC = ({ + children, + language, + resources, + namespaces, +}) => { + const i18n = useMemo(() => { + const instance = createInstance(); + instance.init({ + resources: { + [language]: resources, + }, + fallbackLng: language, + interpolation: { + escapeValue: false, + }, + ns: namespaces, + }); + return instance as i18n; + // No need to check dependencies since this + // should only be created once from the server + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return {children}; +}; + +export default I18nProvider; diff --git a/src/i18n/en/common.json b/src/i18n/en/common.json new file mode 100644 index 0000000..2b2f3a3 --- /dev/null +++ b/src/i18n/en/common.json @@ -0,0 +1,3 @@ +{ + "Grade {{grade}}": "Grade {{grade}}" +} \ No newline at end of file diff --git a/src/i18n/en/dashboard.json b/src/i18n/en/dashboard.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/src/i18n/en/dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/en/login.json b/src/i18n/en/login.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/src/i18n/en/login.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/en/projects.json b/src/i18n/en/projects.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/src/i18n/en/projects.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/index.tsx b/src/i18n/index.tsx new file mode 100644 index 0000000..b404524 --- /dev/null +++ b/src/i18n/index.tsx @@ -0,0 +1,92 @@ +import { cookies, headers } from "next/headers"; +import { createInstance, i18n, LanguageDetectorAsyncModule } from "i18next"; +import resourcesToBackend from "i18next-resources-to-backend"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/config/authConfig"; +import I18nClientProvider from "./I18nClientProvider"; +import universalLanguageDetect from "@unly/universal-language-detector"; + +const FALLBACK_LANG = "en"; +const SUPPORTED_LANGUAGES = ["en", "zh"]; + +export const detectLanguage = async (): Promise => { + // Logic to get language preference from cookies/headers/session + const cookiesList = cookies(); + const cookiesObj = cookiesList + .getAll() + .reduce<{ [name: string]: string }>( + (acc, cookie) => ({ ...acc, [cookie.name]: cookie.value }), + {}, + ); + const headersList = headers(); + const session = await getServerSession(authOptions); + + const lang = universalLanguageDetect({ + supportedLanguages: SUPPORTED_LANGUAGES, + fallbackLanguage: FALLBACK_LANG, + acceptLanguageHeader: headersList.get("accept-language") || undefined, + serverCookies: cookiesObj, + }); + + return lang; +}; + +const languageDetector: LanguageDetectorAsyncModule = { + type: "languageDetector", + detect: detectLanguage, + async: true, +}; + +const initI18next = async (namespaces: string[]): Promise => { + const i18nInstance = createInstance(); + await i18nInstance + .use(languageDetector) + .use( + resourcesToBackend((language: string, namespace: string) => { + return import(`./${language}/${namespace}.json`); + }), + ) + .init({ + fallbackLng: "en", + interpolation: { + escapeValue: false, + }, + ns: namespaces, + }); + return i18nInstance as i18n; +}; + +export const getServerI18n = async (...namespaces: string[]) => { + return initI18next(namespaces); +}; + +interface Props { + children: React.ReactNode; + namespaces: string[]; +} + +// Provides the resources for the client +export const I18nProvider: React.FC = async ({ + children, + namespaces, +}) => { + const i18n = await getServerI18n(...namespaces); + const language = i18n.language; + const resources = namespaces.reduce<{ [ns: string]: any }>( + (acc, ns) => ({ + ...acc, + [ns]: i18n.getResourceBundle(language, ns), + }), + {}, + ); + + return ( + + {children} + + ); +}; diff --git a/src/i18n/zh/common.json b/src/i18n/zh/common.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/src/i18n/zh/common.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/i18n/zh/dashboard.json b/src/i18n/zh/dashboard.json new file mode 100644 index 0000000..d80cb57 --- /dev/null +++ b/src/i18n/zh/dashboard.json @@ -0,0 +1,3 @@ +{ + "Dashboard": "儀表板" +} \ No newline at end of file diff --git a/src/i18n/zh/login.json b/src/i18n/zh/login.json new file mode 100644 index 0000000..da69471 --- /dev/null +++ b/src/i18n/zh/login.json @@ -0,0 +1,10 @@ +{ + "Invalid username or password.": "帳號或密碼錯誤。", + "Something went wrong. Please try again later.": "出了些問題。請稍後再試。", + "Username": "帳號", + "Password": "密碼", + "Please enter a username": "請輸入帳號", + "Please enter a password": "請輸入密碼", + "Login": "登入", + "Sign In": "登入" +} \ No newline at end of file diff --git a/src/i18n/zh/projects.json b/src/i18n/zh/projects.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/src/i18n/zh/projects.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..85204dd --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,39 @@ +import { NextRequestWithAuth, withAuth } from "next-auth/middleware"; +import { authOptions } from "@/config/authConfig"; +import { NextFetchEvent, NextResponse } from "next/server"; + +const PRIVATE_ROUTES = [ + "/analytics", + "/dashboard", + "/home", + "/invoice", + "/projects", + "/tasks", + "/settings", + "/staffReimbursement", +]; +const LANG_QUERY_PARAM = "lang"; + +const authMiddleware = withAuth({ + pages: authOptions.pages, +}); + +export default async function middleware( + req: NextRequestWithAuth, + event: NextFetchEvent, +) { + const langPref = req.nextUrl.searchParams.get(LANG_QUERY_PARAM); + if (langPref) { + // Redirect to same url without the lang query param + set cookies + const newUrl = new URL(req.nextUrl); + newUrl.searchParams.delete(LANG_QUERY_PARAM); + const response = NextResponse.redirect(newUrl); + response.cookies.set("i18next", langPref); + return response; + } + + // Matcher for using the auth middleware + return PRIVATE_ROUTES.some((route) => req.nextUrl.pathname.startsWith(route)) + ? await authMiddleware(req, event) // Let auth middleware handle response + : NextResponse.next(); // Return normal response +} diff --git a/src/theme.ts b/src/theme.ts new file mode 100644 index 0000000..12ce360 --- /dev/null +++ b/src/theme.ts @@ -0,0 +1,11 @@ +import { createTheme } from "@mui/material/styles"; + +const theme = createTheme({ + palette: { + background: { + default: "#fcfcfc", + }, + }, +}); + +export default theme; diff --git a/src/theme/EmotionCache.tsx b/src/theme/EmotionCache.tsx new file mode 100644 index 0000000..8f13bef --- /dev/null +++ b/src/theme/EmotionCache.tsx @@ -0,0 +1,100 @@ +"use client"; +import * as React from "react"; +import createCache from "@emotion/cache"; +import { useServerInsertedHTML } from "next/navigation"; +import { CacheProvider as DefaultCacheProvider } from "@emotion/react"; +import type { + EmotionCache, + Options as OptionsOfCreateCache, +} from "@emotion/cache"; + +// Copied from https://github.com/mui/material-ui/blob/master/examples/material-ui-nextjs-ts/src/components/ThemeRegistry/EmotionCache.tsx +export type NextAppDirEmotionCacheProviderProps = { + /** This is the options passed to createCache() from 'import createCache from "@emotion/cache"' */ + options: Omit; + /** By default from 'import { CacheProvider } from "@emotion/react"' */ + CacheProvider?: (props: { + value: EmotionCache; + children: React.ReactNode; + }) => React.JSX.Element | null; + children: React.ReactNode; +}; + +// Adapted from https://github.com/garronej/tss-react/blob/main/src/next/appDir.tsx +export default function NextAppDirEmotionCacheProvider( + props: NextAppDirEmotionCacheProviderProps, +) { + const { options, CacheProvider = DefaultCacheProvider, children } = props; + + const [registry] = React.useState(() => { + const cache = createCache(options); + cache.compat = true; + const prevInsert = cache.insert; + let inserted: { name: string; isGlobal: boolean }[] = []; + cache.insert = (...args) => { + const [selector, serialized] = args; + if (cache.inserted[serialized.name] === undefined) { + inserted.push({ + name: serialized.name, + isGlobal: !selector, + }); + } + return prevInsert(...args); + }; + const flush = () => { + const prevInserted = inserted; + inserted = []; + return prevInserted; + }; + return { cache, flush }; + }); + + useServerInsertedHTML(() => { + const inserted = registry.flush(); + if (inserted.length === 0) { + return null; + } + let styles = ""; + let dataEmotionAttribute = registry.cache.key; + + const globals: { + name: string; + style: string; + }[] = []; + + inserted.forEach(({ name, isGlobal }) => { + const style = registry.cache.inserted[name]; + + if (typeof style !== "boolean") { + if (isGlobal) { + globals.push({ name, style }); + } else { + styles += style; + dataEmotionAttribute += ` ${name}`; + } + } + }); + + return ( + + {globals.map(({ name, style }) => ( +