diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 399f5df4..07936727 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -84,10 +84,6 @@ jobs: platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} - build-args: | - "SERVER_HOST=${{ vars.SERVER_HOST }}" - "KEYCLOAK_HOST=${{ vars.KEYCLOAK_HOST }}" - "KEYCLOAK_REALM_NAME=${{ vars.KEYCLOAK_REALM_NAME }}" - id: output-tag-client run: | diff --git a/.github/workflows/deploy_docker.yml b/.github/workflows/deploy_docker.yml index 648f0e8e..e19ab293 100644 --- a/.github/workflows/deploy_docker.yml +++ b/.github/workflows/deploy_docker.yml @@ -80,7 +80,7 @@ jobs: source: "master.cf" target: /home/${{ vars.VM_USERNAME }}/postfix-config/ - - name: SSH to VM and create .env.prod file + - name: SSH to VM and create .env.prod uses: appleboy/ssh-action@v1.0.3 with: host: ${{ vars.VM_HOST }} @@ -91,7 +91,7 @@ jobs: proxy_key: ${{ secrets.DEPLOYMENT_GATEWAY_SSH_KEY }} proxy_port: ${{ vars.DEPLOYMENT_GATEWAY_PORT }} script: | - touch .env.prod + touch .env.prod echo "SPRING_DATASOURCE_URL=${{ vars.SPRING_DATASOURCE_URL }}" > .env.prod echo "SPRING_DATASOURCE_USERNAME=${{ vars.SPRING_DATASOURCE_USERNAME }}" >> .env.prod @@ -110,6 +110,10 @@ jobs: echo "SERVER_IMAGE_TAG=${{ inputs.server_image_tag }}" >> .env.prod echo "CLIENT_IMAGE_TAG=${{ inputs.client_image_tag }}" >> .env.prod + + echo "API_SERVER_HOST=${{ vars.API_SERVER_HOST }}" >> .env.prod + echo "KEYCLOAK_REALM_NAME=${{ vars.KEYCLOAK_REALM_NAME }}" >> .env.prod + echo "KEYCLOAK_CLIENT_ID=${{ vars.KEYCLOAK_CLIENT_ID }}" >> .env.prod - name: SSH to VM and Execute Docker-Compose Up uses: appleboy/ssh-action@v1.0.3 diff --git a/.gitignore b/.gitignore index 97aaa2d5..65e0141f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ -.env +.env* db_backups +uploads # User-specific stuff .idea diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 13566b81..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549e..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 519c5514..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/thesis-track.iml b/.idea/thesis-track.iml deleted file mode 100644 index d6ebd480..00000000 --- a/.idea/thesis-track.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddf..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/client/Dockerfile b/client/Dockerfile index 988cc014..40787004 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -1,24 +1,33 @@ FROM node:20-alpine as build WORKDIR /app + COPY package.json ./ COPY package-lock.json ./ -RUN npm install -ARG SERVER_HOST -ARG KEYCLOAK_HOST -ARG KEYCLOAK_REALM_NAME +RUN npm install -ENV REACT_APP_SERVER_HOST $SERVER_HOST -ENV REACT_APP_KEYCLOAK_HOST $KEYCLOAK_HOST -ENV REACT_APP_KEYCLOAK_REALM_NAME $KEYCLOAK_REALM_NAME +ENV CI 1 COPY . ./ + RUN npm install RUN npm run build FROM nginx:stable-alpine + COPY --from=build /app/build /usr/share/nginx/html COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf + +# use same node version like in the build image +COPY --from=build /usr/lib /usr/lib +COPY --from=build /usr/local/share /usr/local/share +COPY --from=build /usr/local/lib /usr/local/lib +COPY --from=build /usr/local/include /usr/local/include +COPY --from=build /usr/local/bin /usr/local/bin + +WORKDIR /usr/share/nginx/html + EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] + +CMD ["/bin/sh", "-c", "node generate-runtime-env.js && nginx -g \"daemon off;\""] diff --git a/client/eslint.config.mjs b/client/eslint.config.mjs index 27d3e567..dfb13e80 100644 --- a/client/eslint.config.mjs +++ b/client/eslint.config.mjs @@ -3,7 +3,7 @@ import typescriptEslint from "@typescript-eslint/eslint-plugin"; import react from "eslint-plugin-react"; import reactHooks from "eslint-plugin-react-hooks"; import globals from "globals"; -import tsParser from '@typescript-eslint/parser' +import tsParser from "@typescript-eslint/parser"; import path from "node:path"; import { fileURLToPath } from "node:url"; import js from "@eslint/js"; @@ -12,80 +12,80 @@ import { FlatCompat } from "@eslint/eslintrc"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const compat = new FlatCompat({ - baseDirectory: __dirname, - recommendedConfig: js.configs.recommended, - allConfig: js.configs.all + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all }); export default [...fixupConfigRules(compat.extends( - "plugin:react/recommended", - "plugin:@typescript-eslint/recommended", - "prettier", - "plugin:prettier/recommended" + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "prettier", + "plugin:prettier/recommended" )), { - files: [ - "src/**/*.js", - "src/**/*.jsx", - "src/**/*.ts", - "src/**/*.tsx", - ], + files: [ + "src/**/*.js", + "src/**/*.jsx", + "src/**/*.ts", + "src/**/*.tsx", + ], - plugins: { - "@typescript-eslint": fixupPluginRules(typescriptEslint), - react: fixupPluginRules(react), - "react-hooks": fixupPluginRules(reactHooks), - }, - - languageOptions: { - globals: { - ...globals.browser, - ...globals.jest, + plugins: { + "@typescript-eslint": fixupPluginRules(typescriptEslint), + react: fixupPluginRules(react), + "react-hooks": fixupPluginRules(reactHooks), }, - parser: tsParser, - ecmaVersion: "latest", - sourceType: "module", + languageOptions: { + globals: { + ...globals.browser, + ...globals.jest, + }, + + parser: tsParser, + ecmaVersion: "latest", + sourceType: "module", - parserOptions: { - ecmaFeatures: { - jsx: true, - }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, - project: ["tsconfig.json"], + project: ["tsconfig.json"], + }, }, - }, - settings: { - react: { - version: "detect", + settings: { + react: { + version: "detect", + }, }, - }, - rules: { - "no-shadow": "off", - "@typescript-eslint/no-shadow": ["error"], + rules: { + "no-shadow": "off", + "@typescript-eslint/no-shadow": ["error"], - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/strict-boolean-expressions": "off", - "@typescript-eslint/return-await": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/strict-boolean-expressions": "off", + "@typescript-eslint/return-await": "off", - "max-len": ["warn", { - code: 160, - ignoreComments: true, - ignoreUrls: true, - }], + "max-len": ["warn", { + code: 160, + ignoreComments: true, + ignoreUrls: true, + }], - "react/react-in-jsx-scope": "off", + "react/react-in-jsx-scope": "off", - "react/jsx-filename-extension": [1, { - extensions: [".tsx", ".jsx"], - }], + "react/jsx-filename-extension": [1, { + extensions: [".tsx", ".jsx"], + }], - "react-hooks/rules-of-hooks": "error", - "react-hooks/exhaustive-deps": "warn", + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "off", - "prettier/prettier": ["error", { - endOfLine: "auto", - }] - }, + "prettier/prettier": ["error", { + endOfLine: "auto", + }] + }, }]; \ No newline at end of file diff --git a/client/package-lock.json b/client/package-lock.json index 6e09efe8..a0b2f7e0 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -1,95 +1,181 @@ { - "name": "client", - "version": "2.0.0", + "name": "thesis-management", + "version": "3.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "client", - "version": "2.0.0", + "name": "thesis-management", + "version": "3.0.0", "license": "MIT", "dependencies": { - "@formkit/auto-animate": "0.8.2", - "@mantine/core": "7.11.0", - "@mantine/dates": "7.11.0", - "@mantine/dropzone": "7.11.0", - "@mantine/form": "7.11.0", - "@mantine/hooks": "7.11.0", - "@mantine/notifications": "7.11.0", - "@mantine/tiptap": "7.11.0", - "@tabler/icons-react": "3.7.0", - "@tanstack/react-query": "5.48.0", - "@tanstack/react-query-devtools": "5.48.0", - "@tiptap/core": "2.4.0", - "@tiptap/extension-highlight": "2.4.0", - "@tiptap/extension-link": "2.4.0", - "@tiptap/extension-subscript": "2.4.0", - "@tiptap/extension-superscript": "2.4.0", - "@tiptap/extension-text-align": "2.4.0", - "@tiptap/extension-underline": "2.4.0", - "@tiptap/pm": "2.4.0", - "@tiptap/react": "2.4.0", - "@tiptap/starter-kit": "2.4.0", - "axios": "1.7.2", - "css-loader": "7.1.2", - "dayjs": "1.11.11", - "file-loader": "6.2.0", - "i18n-iso-countries": "7.11.2", - "jwt-decode": "4.0.0", - "keycloak-js": "22.0.5", - "mantine-contextmenu": "7.10.2", - "mantine-datatable": "7.10.4", - "moment": "2.30.1", - "react": "18.3.1", - "react-dom": "18.3.1", - "react-router-dom": "6.24.0", - "zustand": "4.5.4" + "@formkit/auto-animate": "^0.8.2", + "@mantine/core": "^7.11.2", + "@mantine/dates": "^7.11.2", + "@mantine/dropzone": "^7.11.2", + "@mantine/form": "^7.11.2", + "@mantine/hooks": "^7.11.2", + "@mantine/notifications": "^7.11.2", + "@mantine/tiptap": "^7.11.2", + "i18n-iso-countries": "^7.11.3", + "jwt-decode": "^4.0.0", + "keycloak-js": "^25.0.2", + "mantine-datatable": "^7.11.2", + "phosphor-react": "^1.4.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.25.1" }, "devDependencies": { - "@eslint/compat": "1.1.0", - "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.5.0", - "@tanstack/eslint-plugin-query": "5.47.0", - "@types/copy-webpack-plugin": "10.1.0", - "@types/dotenv-webpack": "7.0.7", - "@types/eslint": "8.56.10", - "@types/node": "20.12.12", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", - "@types/webpack": "5.28.5", - "@types/webpack-bundle-analyzer": "4.7.0", - "@typescript-eslint/eslint-plugin": "7.14.1", - "@typescript-eslint/parser": "7.14.1", + "@eslint/compat": "^1.1.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^8.57.0", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "clean-webpack-plugin": "^4.0.0", - "compression-webpack-plugin": "11.1.0", - "css-minimizer-webpack-plugin": "7.0.0", - "dotenv-webpack": "8.1.0", - "eslint": "8.57.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.29.1", - "eslint-plugin-n": "17.9.0", - "eslint-plugin-prettier": "5.1.3", - "eslint-plugin-react": "7.34.3", - "eslint-plugin-react-hooks": "4.6.2", - "globals": "15.6.0", - "html-webpack-plugin": "5.6.0", - "prettier": "3.3.2", - "sass": "1.75.0", - "sass-loader": "14.2.1", - "style-loader": "4.0.0", - "ts-loader": "9.5.1", - "ts-node": "10.9.2", - "typescript": "5.4.5", - "webpack": "5.91.0", - "webpack-bundle-analyzer": "4.10.2", - "webpack-cli": "5.1.4", - "webpack-dev-server": "5.0.4" + "compression-webpack-plugin": "^11.1.0", + "copy-webpack-plugin": "^12.0.2", + "css-loader": "^7.1.2", + "css-minimizer-webpack-plugin": "^7.0.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^4.6.2", + "fork-ts-checker-webpack-plugin": "^9.0.2", + "globals": "^15.8.0", + "html-webpack-plugin": "^5.6.0", + "mini-css-extract-plugin": "^2.9.0", + "prettier": "^3.3.3", + "sass": "^1.77.8", + "sass-loader": "^14.2.1", + "speed-measure-webpack-plugin": "^1.5.0", + "style-loader": "^4.0.0", + "terser-webpack-plugin": "^5.3.10", + "ts-loader": "^9.5.1", + "ts-node": "^10.9.2", + "typescript": "^5.5.3", + "webpack": "^5.93.0", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.0.4", + "webpackbar": "^6.0.1" } }, - "node_modules/@babel/runtime": { + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", - "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/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==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/runtime": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -153,9 +239,9 @@ } }, "node_modules/@eslint/compat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.0.tgz", - "integrity": "sha512-s9Wi/p25+KbzxKlDm3VshQdImhWk+cbdblhwGNnyCU5lpSwtWa4v7VQCxSki0FAUrGA3s8nCWgYzAH41mwQVKQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.1.tgz", + "integrity": "sha512-lpHyRyplhGPL5mGEh6M9O5nnKk0Gz4bFI+Zu6tKlPpDUN7XshWvH9C/px4UVm87IAANE0W81CEsNGbS1KlzXpA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -197,38 +283,38 @@ } }, "node_modules/@eslint/js": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.5.0.tgz", - "integrity": "sha512-A7+AOT2ICkodvtsWnxZP4Xxk3NbZ3VMHd8oihydLRGrJgqqdEz1qSeEgXYyT/Cu8h1TWWsQRejIx48mtjZ5y1w==", + "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": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@floating-ui/core": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.3.tgz", - "integrity": "sha512-1ZpCvYf788/ZXOhRQGFxnYQOVgeU+pi0i+d0Ow34La7qjIXETi6RNswGVKkA6KcDO8/+Ysu2E/CeUmmeEBDvTg==", + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", + "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", "dependencies": { - "@floating-ui/utils": "^0.2.3" + "@floating-ui/utils": "^0.2.4" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.6.tgz", - "integrity": "sha512-qiTYajAnh3P+38kECeffMSQgbvXty2VB6rS+42iWR4FPIlZjLK84E9qtLnMTLIpPz2znD/TaFqaiavMUrS+Hcw==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", + "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.3" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.4" } }, "node_modules/@floating-ui/react": { - "version": "0.26.18", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.18.tgz", - "integrity": "sha512-enDDX09Jpi3kmhcXXpvs+fvRXOfBj1jUV2KF6uDMf5HjS+SOZJzNTFUW71lKbFcxz0BkmQqwbvqdmHIxMq/fyQ==", + "version": "0.26.19", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.19.tgz", + "integrity": "sha512-Jk6zITdjjIvjO/VdQFvpRaD3qPwOHH6AoDHxjhpy+oK4KFgaSP871HYWUAPdnLmx1gQ+w/pB312co3tVml+BXA==", "dependencies": { - "@floating-ui/react-dom": "^2.1.0", - "@floating-ui/utils": "^0.2.3", + "@floating-ui/react-dom": "^2.1.1", + "@floating-ui/utils": "^0.2.4", "tabbable": "^6.0.0" }, "peerDependencies": { @@ -249,9 +335,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.3.tgz", - "integrity": "sha512-XGndio0l5/Gvd6CLIABvsav9HHezgDFFhDfHk1bvLfr9ni8dojqLSvBbotJEjmIwNHL7vK4QzBJTdBRoB+c1ww==" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", + "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" }, "node_modules/@formkit/auto-animate": { "version": "0.8.2", @@ -370,6 +456,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -383,6 +470,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -391,6 +479,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, "engines": { "node": ">=6.0.0" } @@ -399,20 +488,23 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "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==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true }, "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==", + "dev": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -479,9 +571,9 @@ "dev": true }, "node_modules/@mantine/core": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.11.0.tgz", - "integrity": "sha512-yw2Llww9mw8rDWZtucdEuvkqqjHdreUibos7JCUpejL721FW1Tn9L91nsxO/YQFSS7jn4Q0CP+1YbQ/PMULmwA==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.11.2.tgz", + "integrity": "sha512-T64RjdgY8UPAv249miW1lQyPPot1JbCcKKsAZMNQHgcttcxLhrFpKVvglc4/48hdSoxI4LYJPNvqp7zciZmucQ==", "dependencies": { "@floating-ui/react": "^0.26.9", "clsx": "^2.1.1", @@ -491,44 +583,44 @@ "type-fest": "^4.12.0" }, "peerDependencies": { - "@mantine/hooks": "7.11.0", + "@mantine/hooks": "7.11.2", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/dates": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-7.11.0.tgz", - "integrity": "sha512-4wKzOyOvDDh8/TV1SYGHDWydflweRiem4cJt3S49LO1Forpy2SiJ18Gn4ylGiqZdWxz1HY4Jb5kl7GAzxLD4tQ==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-7.11.2.tgz", + "integrity": "sha512-BEZs949EvfIG1fRNsEpcB0YqSe53z/KObwHyBwiqFjFHJ2eFPVMpxw6Rpy1Bud0/FZRV+QBokebxaf6+2tbCCw==", "dependencies": { "clsx": "^2.1.1" }, "peerDependencies": { - "@mantine/core": "7.11.0", - "@mantine/hooks": "7.11.0", + "@mantine/core": "7.11.2", + "@mantine/hooks": "7.11.2", "dayjs": ">=1.0.0", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/dropzone": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-7.11.0.tgz", - "integrity": "sha512-8vZgm8+NlBrQFJlWckaoqz55zjk8GVX0GDn1bZUunUtIJ5uv/wJPAInq3IlRdzvWVfz5MA+4oxd32fa5oxsBSA==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-7.11.2.tgz", + "integrity": "sha512-/X29ym1uM1ca7ZMLVSSxm9KBbDNIpXBwZbzNIpopH0hxjbo2bSpPTbNUVB3EjRAVWDx9RGlyNxQV2jkhCos7QQ==", "dependencies": { "react-dropzone-esm": "15.0.1" }, "peerDependencies": { - "@mantine/core": "7.11.0", - "@mantine/hooks": "7.11.0", + "@mantine/core": "7.11.2", + "@mantine/hooks": "7.11.2", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/form": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-7.11.0.tgz", - "integrity": "sha512-BmkzRp57O1zZuxCYH76w6zeBNhczq7OeRtkG/zvMo35BJp1K5u8eetN3AC1WwkGLmrNid2BCIsvTFHDP9DYnaQ==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-7.11.2.tgz", + "integrity": "sha512-NRY4HDgcArDEP+wUaHITnoVh0Ce3rM3Blo9fLNj2VYO8k7AfuSWp+fQdqrjDI0k9wGU3YEj4/dbwOjKbtXEhxw==", "dependencies": { "fast-deep-equal": "^3.1.3", "klona": "^2.0.6" @@ -538,43 +630,43 @@ } }, "node_modules/@mantine/hooks": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.11.0.tgz", - "integrity": "sha512-T3472GhUXFhuhXUHlxjHv0wfb73lFyNuaw631c7Ddtgvewq0WKtNqYd7j/Zz/k02DuS3r0QXA7e12/XgqHBZjg==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-7.11.2.tgz", + "integrity": "sha512-jhyVe/sbDEG2U8rr2lMecUPgQxcfr5hh9HazqGfkS7ZRIMDO7uJ947yAcTMGGkp5Lxtt5TBFt1Cb6tiB2/1agg==", "peerDependencies": { "react": "^18.2.0" } }, "node_modules/@mantine/notifications": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-7.11.0.tgz", - "integrity": "sha512-UtAHJoSi4s+lfVZrkUDWMlg6j0w1LZaiMEOBMG9p5MV5dP38W75LeCy2cio2Znji2S5YzXaZolOkHBT5ZONKAw==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-7.11.2.tgz", + "integrity": "sha512-KB/6mp3mU3LvcFlfMc5zK5mWcrAO+zAGeiBb1oUjNFXBECCn9xizqqUeT0YbWBHL7wysq9IThDJxLwUBnQt+8Q==", "dependencies": { - "@mantine/store": "7.11.0", + "@mantine/store": "7.11.2", "react-transition-group": "4.4.5" }, "peerDependencies": { - "@mantine/core": "7.11.0", - "@mantine/hooks": "7.11.0", + "@mantine/core": "7.11.2", + "@mantine/hooks": "7.11.2", "react": "^18.2.0", "react-dom": "^18.2.0" } }, "node_modules/@mantine/store": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/store/-/store-7.11.0.tgz", - "integrity": "sha512-zPmOpdFgvkUqYKSK7NNKbhgXsh2QPw51m3iypTaj0mw+rZbk3WSH9vZvaEx59X0QG+ahwUg2/HezbjfXFUbvrA==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/store/-/store-7.11.2.tgz", + "integrity": "sha512-FfkmnOnCivOjqwNaTZeV4TgDANUs7fP+0uSgzp0GuvwTuDfQNVafPBRzPkjKuz5ug+Nn9l6WwjfJ6LBDv9U0LQ==", "peerDependencies": { "react": "^18.2.0" } }, "node_modules/@mantine/tiptap": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@mantine/tiptap/-/tiptap-7.11.0.tgz", - "integrity": "sha512-6AXSteD22B4gqscEKLejJ8v1QQsl7Q/2XLYSHwrT8T4l9JVeL881SG5wl23TOKp2K23BqULZbDmm4hhEKmnCZA==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@mantine/tiptap/-/tiptap-7.11.2.tgz", + "integrity": "sha512-ZAnxq9YC693PLV1PyN0FhuG3iUEazlbZenqkyi7ziUZwSiWhqOM94BT/VP/R0zWjsQjAeQcq9yt8gpLfsTbDig==", "peerDependencies": { - "@mantine/core": "7.11.0", - "@mantine/hooks": "7.11.0", + "@mantine/core": "7.11.2", + "@mantine/hooks": "7.11.2", "@tiptap/extension-link": ">=2.1.12", "@tiptap/react": ">=2.1.12", "react": "^18.2.0", @@ -648,6 +740,7 @@ "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -656,12 +749,13 @@ "node_modules/@remirror/core-constants": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-2.0.2.tgz", - "integrity": "sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==" + "integrity": "sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==", + "peer": true }, "node_modules/@remix-run/router": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.17.0.tgz", - "integrity": "sha512-2D6XaHEVvkCn682XBnipbJjgZUU7xjLtA4dGJRBVUKpEaDYOZMENZoZjAOSb7qirxt5RupjzZxz4fK2FO+EFPw==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", + "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", "engines": { "node": ">=14.0.0" } @@ -684,135 +778,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@tabler/icons": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.7.0.tgz", - "integrity": "sha512-lJGIZLSWrPO6VygRUbaVvQjWgL2EaiBMD8e6leCYUQ8ZPO4LIzKMq358C8KlhXJcyNiRz1Io3YWoc/DNTcWqSg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/codecalm" - } - }, - "node_modules/@tabler/icons-react": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.7.0.tgz", - "integrity": "sha512-8AU4oO9pgLhHLOSGAJIsRhsTy7w8D7uKBlR0DIFxaILFA1fe2rC4wrNGYUtIFei82y41OuXz9vMk0Oe+IWT3SA==", - "dependencies": { - "@tabler/icons": "3.7.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/codecalm" - }, - "peerDependencies": { - "react": ">= 16" - } - }, - "node_modules/@tanstack/eslint-plugin-query": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@tanstack/eslint-plugin-query/-/eslint-plugin-query-5.47.0.tgz", - "integrity": "sha512-Y56KKu0DoftFkCd3H0xckDbvm38kg9UrGF2CABqMYr7yo94XUZhBYE8R3Gq7N4JxRvPha+lUg37eypECY5u2kA==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "8.0.0-alpha.30" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "eslint": "^8 || ^9" - } - }, - "node_modules/@tanstack/query-core": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.48.0.tgz", - "integrity": "sha512-lZAfPPeVIqXCswE9SSbG33B6/91XOWt/Iq41bFeWb/mnHwQSIfFRbkS4bfs+WhIk9abRArF9Id2fp0Mgo+hq6Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/query-devtools": { - "version": "5.47.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.47.0.tgz", - "integrity": "sha512-oo10s7Nqaf/Q3QF4vuSwS0xw7zuYr5nXef4RHQIXVJKvRQeo9WowPLAnB0SF/voB0c4GTX6Vq8wfQ1G72ezEdw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/react-query": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.48.0.tgz", - "integrity": "sha512-GDExbjYWzvDokyRqMSWXdrPiYpp95Aig0oeMIrxTaruOJJgWiWfUP//OAaowm2RrRkGVsavSZdko/XmIrrV2Nw==", - "dependencies": { - "@tanstack/query-core": "5.48.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^18.0.0" - } - }, - "node_modules/@tanstack/react-query-devtools": { - "version": "5.48.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.48.0.tgz", - "integrity": "sha512-0xvk8KDvEfQuLz3dy9jqtP0f6iR724d57Br7KtrtClbyqB53cy3Iy6BiTsiHaSsYnex/+cxWJZIX1UJWeV8Amw==", - "dependencies": { - "@tanstack/query-devtools": "5.47.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "@tanstack/react-query": "^5.48.0", - "react": "^18 || ^19" - } - }, "node_modules/@tiptap/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.4.0.tgz", - "integrity": "sha512-YJSahk8pkxpCs8SflCZfTnJpE7IPyUWIylfgXM2DefjRQa5DZ+c6sNY0s/zbxKYFQ6AuHVX40r9pCfcqHChGxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-blockquote": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.4.0.tgz", - "integrity": "sha512-nJJy4KsPgQqWTTDOWzFRdjCfG5+QExfZj44dulgDFNh+E66xhamnbM70PklllXJgEcge7xmT5oKM0gKls5XgFw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.5.4.tgz", + "integrity": "sha512-Zs/hShr4+W02+0nOlpmr5cS2YjDRLqd+XMt+jsiQH0QNr3s1Lc82pfF6C3CjgLEZtdUzImZrW2ABtLlpvbogaA==", + "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-bold": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.4.0.tgz", - "integrity": "sha512-csnW6hMDEHoRfxcPRLSqeJn+j35Lgtt1YRiOwn7DlS66sAECGRuoGfCvQSPij0TCDp4VCR9if5Sf8EymhnQumQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" + "@tiptap/pm": "^2.5.4" } }, "node_modules/@tiptap/extension-bubble-menu": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.4.0.tgz", - "integrity": "sha512-s99HmttUtpW3rScWq8rqk4+CGCwergNZbHLTkF6Rp6TSboMwfp+rwL5Q/JkcAG9KGLso1vGyXKbt1xHOvm8zMw==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.5.4.tgz", + "integrity": "sha512-GHwef912K1yd75pp9JGDnKSp1DvdOHH8BcHQv0no+a3q2ePFPYcgaSwVRR59jHRX9WzdVfoLcqDSAeoNGOrISw==", + "peer": true, "dependencies": { "tippy.js": "^6.3.7" }, @@ -821,76 +804,15 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-bullet-list": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.4.0.tgz", - "integrity": "sha512-9S5DLIvFRBoExvmZ+/ErpTvs4Wf1yOEs8WXlKYUCcZssK7brTFj99XDwpHFA29HKDwma5q9UHhr2OB2o0JYAdw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-code": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.4.0.tgz", - "integrity": "sha512-wjhBukuiyJMq4cTcK3RBTzUPV24k5n1eEPlpmzku6ThwwkMdwynnMGMAmSF3fErh3AOyOUPoTTjgMYN2d10SJA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-code-block": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.4.0.tgz", - "integrity": "sha512-QWGdv1D56TBGbbJSj2cIiXGJEKguPiAl9ONzJ/Ql1ZksiQsYwx0YHriXX6TOC//T4VIf6NSClHEtwtxWBQ/Csg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-document": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.4.0.tgz", - "integrity": "sha512-3jRodQJZDGbXlRPERaloS+IERg/VwzpC1IO6YSJR9jVIsBO6xC29P3cKTQlg1XO7p6ZH/0ksK73VC5BzzTwoHg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-dropcursor": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.4.0.tgz", - "integrity": "sha512-c46HoG2PEEpSZv5rmS5UX/lJ6/kP1iVO0Ax+6JrNfLEIiDULUoi20NqdjolEa38La2VhWvs+o20OviiTOKEE9g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" + "@tiptap/core": "^2.5.4", + "@tiptap/pm": "^2.5.4" } }, "node_modules/@tiptap/extension-floating-menu": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.4.0.tgz", - "integrity": "sha512-vLb9v+htbHhXyty0oaXjT3VC8St4xuGSHWUB9GuAJAQ+NajIO6rBPbLUmm9qM0Eh2zico5mpSD1Qtn5FM6xYzg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.5.4.tgz", + "integrity": "sha512-EqD4rgi3UhnDcV3H1+ndAS4Ue2zpsU7hFKoevOIV6GS7xVnWN70AGt6swH24QzuHKKISFtWoLpKjrwRORNIxuA==", + "peer": true, "dependencies": { "tippy.js": "^6.3.7" }, @@ -899,101 +821,15 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-gapcursor": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.4.0.tgz", - "integrity": "sha512-F4y/0J2lseohkFUw9P2OpKhrJ6dHz69ZScABUvcHxjznJLd6+0Zt7014Lw5PA8/m2d/w0fX8LZQ88pZr4quZPQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-hard-break": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.4.0.tgz", - "integrity": "sha512-3+Z6zxevtHza5IsDBZ4lZqvNR3Kvdqwxq/QKCKu9UhJN1DUjsg/l1Jn2NilSQ3NYkBYh2yJjT8CMo9pQIu776g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-heading": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.4.0.tgz", - "integrity": "sha512-fYkyP/VMo7YHO76YVrUjd95Qeo0cubWn/Spavmwm1gLTHH/q7xMtbod2Z/F0wd6QHnc7+HGhO7XAjjKWDjldaw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-highlight": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.4.0.tgz", - "integrity": "sha512-p2I/CaMrs6hzpj/dSw6UNobOWTV38yTjPK+B4ShJQ7IN2u/C82KOTOeFfJoFd9KykmpVOVW3w3nKG3ad0HXPuQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-history": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.4.0.tgz", - "integrity": "sha512-gr5qsKAXEVGr1Lyk1598F7drTaEtAxqZiuuSwTCzZzkiwgEQsWMWTWc9F8FlneCEaqe1aIYg6WKWlmYPaFwr0w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-horizontal-rule": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.4.0.tgz", - "integrity": "sha512-yDgxy+YxagcEsBbdWvbQiXYxsv3noS1VTuGwc9G7ZK9xPmBHJ5y0agOkB7HskwsZvJHoaSqNRsh7oZTkf0VR3g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-italic": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.4.0.tgz", - "integrity": "sha512-aaW/L9q+KNHHK+X73MPloHeIsT191n3VLd3xm6uUcFDnUNvzYJ/q65/1ZicdtCaOLvTutxdrEvhbkrVREX6a8g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" + "@tiptap/core": "^2.5.4", + "@tiptap/pm": "^2.5.4" } }, "node_modules/@tiptap/extension-link": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.4.0.tgz", - "integrity": "sha512-r3PjT0bjSKAorHAEBPA0icSMOlqALbxVlWU9vAc+Q3ndzt7ht0CTPNewzFF9kjzARABVt1cblXP/2+c0qGzcsg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.5.4.tgz", + "integrity": "sha512-xTB/+T6SHHCXInJni8WdqOfF40a/MiFUf5OoWW9cPrApx3I7TzJ9j8/WDshM0BOnDDw80w1bl9F2zkUQjC0Y2A==", + "peer": true, "dependencies": { "linkifyjs": "^4.1.0" }, @@ -1002,141 +838,34 @@ "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-list-item": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.4.0.tgz", - "integrity": "sha512-reUVUx+2cI2NIAqMZhlJ9uK/+zvRzm1GTmlU2Wvzwc7AwLN4yemj6mBDsmBLEXAKPvitfLh6EkeHaruOGymQtg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-ordered-list": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.4.0.tgz", - "integrity": "sha512-Zo0c9M0aowv+2+jExZiAvhCB83GZMjZsxywmuOrdUbq5EGYKb7q8hDyN3hkrktVHr9UPXdPAYTmLAHztTOHYRA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-paragraph": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.4.0.tgz", - "integrity": "sha512-+yse0Ow67IRwcACd9K/CzBcxlpr9OFnmf0x9uqpaWt1eHck1sJnti6jrw5DVVkyEBHDh/cnkkV49gvctT/NyCw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-strike": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.4.0.tgz", - "integrity": "sha512-pE1uN/fQPOMS3i+zxPYMmPmI3keubnR6ivwM+KdXWOMnBiHl9N4cNpJgq1n2eUUGKLurC2qrQHpnVyGAwBS6Vg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-subscript": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-subscript/-/extension-subscript-2.4.0.tgz", - "integrity": "sha512-exLSmSFmYN6AVww5oyroFL3KCwstT0U+ojvVhRD6DQ+Hc81d++lBKANfsWAcllXjZVGPWeMNdE66bV7oFCtQcQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-superscript": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-superscript/-/extension-superscript-2.4.0.tgz", - "integrity": "sha512-s+GsbbERNQCn/hyaw5/82y3wHQ7o5byc/eFAKYo1p3p5eESlDaHY/xVYPt3CGOX2TJWZalgSFEFqBVdTSI8mUQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-text": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.4.0.tgz", - "integrity": "sha512-LV0bvE+VowE8IgLca7pM8ll7quNH+AgEHRbSrsI3SHKDCYB9gTHMjWaAkgkUVaO1u0IfCrjnCLym/PqFKa+vvg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-text-align": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.4.0.tgz", - "integrity": "sha512-wpRe2OiLXTK4kTy4RZEPnPjFbK16kYHPAx1552hLXrOdyxbS7Sdbo+w4x7aGLLZZqZdudCFfkdtnqrc7PDVZdA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" - } - }, - "node_modules/@tiptap/extension-underline": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.4.0.tgz", - "integrity": "sha512-guWojb7JxUwLz4OKzwNExJwOkhZjgw/ttkXCMBT0PVe55k998MMYe1nvN0m2SeTW9IxurEPtScH4kYJ0XuSm8Q==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - }, - "peerDependencies": { - "@tiptap/core": "^2.0.0" + "@tiptap/core": "^2.5.4", + "@tiptap/pm": "^2.5.4" } }, "node_modules/@tiptap/pm": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.4.0.tgz", - "integrity": "sha512-B1HMEqGS4MzIVXnpgRZDLm30mxDWj51LkBT/if1XD+hj5gm8B9Q0c84bhvODX6KIs+c6z+zsY9VkVu8w9Yfgxg==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.5.4.tgz", + "integrity": "sha512-oFIsuniptdUXn93x4aM2sVN3hYKo9Fj55zAkYrWhwxFYUYcPxd5ibra2we+wRK5TaiPu098wpC+yMSTZ/KKMpA==", + "peer": true, "dependencies": { "prosemirror-changeset": "^2.2.1", "prosemirror-collab": "^1.3.1", "prosemirror-commands": "^1.5.2", "prosemirror-dropcursor": "^1.8.1", "prosemirror-gapcursor": "^1.3.2", - "prosemirror-history": "^1.3.2", - "prosemirror-inputrules": "^1.3.0", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", "prosemirror-keymap": "^1.2.2", - "prosemirror-markdown": "^1.12.0", + "prosemirror-markdown": "^1.13.0", "prosemirror-menu": "^1.2.4", - "prosemirror-model": "^1.19.4", - "prosemirror-schema-basic": "^1.2.2", - "prosemirror-schema-list": "^1.3.0", + "prosemirror-model": "^1.22.1", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", "prosemirror-state": "^1.4.3", - "prosemirror-tables": "^1.3.5", - "prosemirror-trailing-node": "^2.0.7", - "prosemirror-transform": "^1.8.0", - "prosemirror-view": "^1.32.7" + "prosemirror-tables": "^1.3.7", + "prosemirror-trailing-node": "^2.0.8", + "prosemirror-transform": "^1.9.0", + "prosemirror-view": "^1.33.8" }, "funding": { "type": "github", @@ -1144,54 +873,27 @@ } }, "node_modules/@tiptap/react": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.4.0.tgz", - "integrity": "sha512-baxnIr6Dy+5iGagOEIKFeHzdl1ZRa6Cg+SJ3GDL/BVLpO6KiCM3Mm5ymB726UKP1w7icrBiQD2fGY3Bx8KaiSA==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.5.4.tgz", + "integrity": "sha512-2HPHt2lEK6Z4jOV3HHVTee8hD4NS6eEj0zRZWSFjt1zDzXtFqX8VIv7qC1iDYsQgyiFnFnOucOQtAlDewBb23A==", + "peer": true, "dependencies": { - "@tiptap/extension-bubble-menu": "^2.4.0", - "@tiptap/extension-floating-menu": "^2.4.0" + "@tiptap/extension-bubble-menu": "^2.5.4", + "@tiptap/extension-floating-menu": "^2.5.4", + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "@tiptap/core": "^2.0.0", - "@tiptap/pm": "^2.0.0", + "@tiptap/core": "^2.5.4", + "@tiptap/pm": "^2.5.4", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" } }, - "node_modules/@tiptap/starter-kit": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.4.0.tgz", - "integrity": "sha512-DYYzMZdTEnRn9oZhKOeRCcB+TjhNz5icLlvJKoHoOGL9kCbuUyEf8WRR2OSPckI0+KUIPJL3oHRqO4SqSdTjfg==", - "dependencies": { - "@tiptap/core": "^2.4.0", - "@tiptap/extension-blockquote": "^2.4.0", - "@tiptap/extension-bold": "^2.4.0", - "@tiptap/extension-bullet-list": "^2.4.0", - "@tiptap/extension-code": "^2.4.0", - "@tiptap/extension-code-block": "^2.4.0", - "@tiptap/extension-document": "^2.4.0", - "@tiptap/extension-dropcursor": "^2.4.0", - "@tiptap/extension-gapcursor": "^2.4.0", - "@tiptap/extension-hard-break": "^2.4.0", - "@tiptap/extension-heading": "^2.4.0", - "@tiptap/extension-history": "^2.4.0", - "@tiptap/extension-horizontal-rule": "^2.4.0", - "@tiptap/extension-italic": "^2.4.0", - "@tiptap/extension-list-item": "^2.4.0", - "@tiptap/extension-ordered-list": "^2.4.0", - "@tiptap/extension-paragraph": "^2.4.0", - "@tiptap/extension-strike": "^2.4.0", - "@tiptap/extension-text": "^2.4.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ueberdosis" - } - }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -1263,31 +965,11 @@ "@types/node": "*" } }, - "node_modules/@types/copy-webpack-plugin": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/@types/copy-webpack-plugin/-/copy-webpack-plugin-10.1.0.tgz", - "integrity": "sha512-Dk0NUW3X6hVQdkH2n9R7NejjPNCocZBiv8XF8Ac5su2d6EKzCcG/yWDwnWGrEsAWvogoADJyUKULwncx0G9Jkg==", - "deprecated": "This is a stub types definition. copy-webpack-plugin provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "copy-webpack-plugin": "*" - } - }, - "node_modules/@types/dotenv-webpack": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/dotenv-webpack/-/dotenv-webpack-7.0.7.tgz", - "integrity": "sha512-tltVokFUeYuSjNmHc6N892Asu/JIQcnH2iUF5A29/VKqv9opq6KlrmnKd/Lt/bBikV/z0YN2K0kguTwWirYCMQ==", - "dev": true, - "dependencies": { - "@types/node": "*", - "tapable": "^2.2.0", - "webpack": "^5" - } - }, "node_modules/@types/eslint": { "version": "8.56.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -1297,6 +979,7 @@ "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==", + "dev": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -1305,7 +988,8 @@ "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==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, "node_modules/@types/express": { "version": "4.17.21", @@ -1389,12 +1073,7 @@ "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==", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/mime": { @@ -1410,9 +1089,10 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -1508,32 +1188,16 @@ "@types/node": "*" } }, - "node_modules/@types/webpack": { - "version": "5.28.5", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-5.28.5.tgz", - "integrity": "sha512-wR87cgvxj3p6D0Crt1r5avwqffqPXUkNlnQ1mjU93G7gCuFjufZR4I6j8cz5g1F1tTYpfOOFvly+cmIQwL9wvw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "tapable": "^2.2.0", - "webpack": "^5" - } - }, - "node_modules/@types/webpack-bundle-analyzer": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz", - "integrity": "sha512-c5i2ThslSNSG8W891BRvOd/RoCjI2zwph8maD22b1adtSns20j+0azDDMCK06DiVrzTgnwiDl5Ntmu1YRJw8Sg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "tapable": "^2.2.0", - "webpack": "^5" - } + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "peer": true }, "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "version": "8.5.11", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.11.tgz", + "integrity": "sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==", "dev": true, "dependencies": { "@types/node": "*" @@ -1555,16 +1219,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", - "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/type-utils": "7.14.1", - "@typescript-eslint/utils": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1588,15 +1252,15 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1610,15 +1274,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -1638,13 +1302,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1655,13 +1319,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", - "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1682,15 +1346,15 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1704,9 +1368,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1717,13 +1381,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1768,134 +1432,13 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.0-alpha.30.tgz", - "integrity": "sha512-rfhqfLqFyXhHNDwMnHiVGxl/Z2q/3guQ1jLlGQ0hi9Rb7inmwz42crM+NnLPR+2vEnwyw1P/g7fnQgQ3qvFx4g==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.0-alpha.30", - "@typescript-eslint/types": "8.0.0-alpha.30", - "@typescript-eslint/typescript-estree": "8.0.0-alpha.30" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.0-alpha.30.tgz", - "integrity": "sha512-FGW/iPWGyPFamAVZ60oCAthMqQrqafUGebF8UKuq/ha+e9SVG6YhJoRzurlQXOVf8dHfOhJ0ADMXyFnMc53clg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.0.0-alpha.30", - "@typescript-eslint/visitor-keys": "8.0.0-alpha.30" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.0-alpha.30.tgz", - "integrity": "sha512-4WzLlw27SO9pK9UFj/Hu7WGo8WveT0SEiIpFVsV2WwtQmLps6kouwtVCB8GJPZKJyurhZhcqCoQVQFmpv441Vg==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.0-alpha.30.tgz", - "integrity": "sha512-WSXbc9ZcXI+7yC+6q95u77i8FXz6HOLsw3ST+vMUlFy1lFbXyFL/3e6HDKQCm2Clt0krnoCPiTGvIn+GkYPn4Q==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.0.0-alpha.30", - "@typescript-eslint/visitor-keys": "8.0.0-alpha.30", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.0.0-alpha.30", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.0-alpha.30.tgz", - "integrity": "sha512-XZuNurZxBqmr6ZIRIwWFq7j5RZd6ZlkId/HZEWyfciK+CWoyOxSF9Pv2VXH9Rlu2ZG2PfbhLz2Veszl4Pfn7yA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.0.0-alpha.30", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/types": "7.16.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -1916,6 +1459,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -1924,22 +1468,26 @@ "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==" + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": 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==" + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==" + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": 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==", + "dev": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1949,12 +1497,14 @@ "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==" + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -1966,6 +1516,7 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -1974,6 +1525,7 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -1981,12 +1533,14 @@ "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==" + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -2002,6 +1556,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -2014,6 +1569,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-buffer": "1.12.1", @@ -2025,6 +1581,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, "dependencies": { "@webassemblyjs/ast": "1.12.1", "@webassemblyjs/helper-api-error": "1.11.6", @@ -2038,6 +1595,7 @@ "version": "1.12.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, "dependencies": { "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" @@ -2090,12 +1648,14 @@ "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==" + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": 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==" + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", @@ -2111,9 +1671,10 @@ } }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -2121,10 +1682,11 @@ "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==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, "peerDependencies": { "acorn": "^8" } @@ -2154,6 +1716,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2183,15 +1746,15 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -2208,10 +1771,38 @@ "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, "peerDependencies": { "ajv": "^6.9.1" } }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", @@ -2352,26 +1943,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -2408,18 +1979,6 @@ "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.4", "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", @@ -2458,11 +2017,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", @@ -2478,55 +2032,18 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.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==", "dev": true }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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/batch": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, - "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.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -2626,9 +2143,10 @@ } }, "node_modules/browserslist": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", - "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -2644,10 +2162,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001629", - "electron-to-chromium": "^1.4.796", + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.16" + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2659,7 +2177,8 @@ "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==" + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, "node_modules/bundle-name": { "version": "4.1.0", @@ -2736,9 +2255,10 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001638", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz", - "integrity": "sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==", + "version": "1.0.30001642", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", + "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", + "dev": true, "funding": [ { "type": "opencollective", @@ -2810,6 +2330,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, "engines": { "node": ">=6.0" } @@ -2908,17 +2429,6 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/commander": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", @@ -3014,6 +2524,15 @@ "node": ">=0.8" } }, + "node_modules/consola": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.2.3.tgz", + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==", + "dev": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -3075,9 +2594,9 @@ } }, "node_modules/copy-webpack-plugin/node_modules/globby": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz", - "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==", + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", "dev": true, "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", @@ -3124,6 +2643,32 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -3133,7 +2678,8 @@ "node_modules/crelt": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", - "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "peer": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -3165,6 +2711,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", @@ -3284,6 +2831,7 @@ "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" }, @@ -3292,12 +2840,12 @@ } }, "node_modules/cssnano": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.3.tgz", - "integrity": "sha512-lsekJctOTqdCn4cNrtrSwsuMR/fHC+oiVMHkp/OugBWtwjH8XJag1/OtGaYJGtz0un1fQcRy4ryfYTQsfh+KSQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.4.tgz", + "integrity": "sha512-rQgpZra72iFjiheNreXn77q1haS2GEy69zCMbu4cpXCFPMQF+D4Ik5V7ktMzUF/sA7xCIgcqHwGPnCD+0a1vHg==", "dev": true, "dependencies": { - "cssnano-preset-default": "^7.0.3", + "cssnano-preset-default": "^7.0.4", "lilconfig": "^3.1.2" }, "engines": { @@ -3312,9 +2860,9 @@ } }, "node_modules/cssnano-preset-default": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.3.tgz", - "integrity": "sha512-dQ3Ba1p/oewICp/szF1XjFFgql8OlOBrI2YNBUUwhHQnJNoMOcQTa+Bi7jSJN8r/eM1egW0Ud1se/S7qlduWKA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.4.tgz", + "integrity": "sha512-jQ6zY9GAomQX7/YNLibMEsRZguqMUGuupXcEk2zZ+p3GUxwCAsobqPYE62VrJ9qZ0l9ltrv2rgjwZPBIFIjYtw==", "dev": true, "dependencies": { "browserslist": "^4.23.1", @@ -3322,7 +2870,7 @@ "cssnano-utils": "^5.0.0", "postcss-calc": "^10.0.0", "postcss-colormin": "^7.0.1", - "postcss-convert-values": "^7.0.1", + "postcss-convert-values": "^7.0.2", "postcss-discard-comments": "^7.0.1", "postcss-discard-duplicates": "^7.0.0", "postcss-discard-empty": "^7.0.0", @@ -3457,9 +3005,10 @@ } }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==" + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", + "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==", + "peer": true }, "node_modules/debounce": { "version": "1.2.1", @@ -3490,6 +3039,15 @@ "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/default-browser": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", @@ -3631,27 +3189,6 @@ "node": ">=0.10.0" } }, - "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==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3824,39 +3361,6 @@ "tslib": "^2.0.3" } }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/dotenv-defaults": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dotenv-defaults/-/dotenv-defaults-2.0.2.tgz", - "integrity": "sha512-iOIzovWfsUHU91L5i8bJce3NYK5JXeAwH50Jh6+ARUdLiiGlYWfGw6UkzsYqaXZH/hjE/eCd/PlfM/qqyK0AMg==", - "dev": true, - "dependencies": { - "dotenv": "^8.2.0" - } - }, - "node_modules/dotenv-webpack": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/dotenv-webpack/-/dotenv-webpack-8.1.0.tgz", - "integrity": "sha512-owK1JcsPkIobeqjVrk6h7jPED/W6ZpdFsMPR+5ursB7/SdgDyO+VzAU+szK8C8u3qUhtENyYnj8eyXMR5kkGag==", - "dev": true, - "dependencies": { - "dotenv-defaults": "^2.0.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "webpack": "^4 || ^5" - } - }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -3876,9 +3380,10 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.814", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.814.tgz", - "integrity": "sha512-GVulpHjFu1Y9ZvikvbArHmAhZXtm3wHlpjTMcXNGKl4IQ4jMQjlnz8yMQYYqdLHKi/jEL2+CBC2akWVCoIGUdw==" + "version": "1.4.830", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.830.tgz", + "integrity": "sha512-TrPKKH20HeN0J1LHzsYLs2qwXrp8TF4nHdu4sq61ozGbzMpWhI7iIOPYPPkxeq1azMT9PZ8enPFcftbs/Npcjg==", + "dev": true }, "node_modules/emoji-regex": { "version": "9.2.2", @@ -3886,14 +3391,6 @@ "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/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -3907,6 +3404,7 @@ "version": "5.17.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "dev": true, "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -3938,6 +3436,15 @@ "node": ">=4" } }, + "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==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.23.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", @@ -4047,7 +3554,8 @@ "node_modules/es-module-lexer": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==" + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", + "dev": true }, "node_modules/es-object-atoms": { "version": "1.0.0", @@ -4105,6 +3613,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, "engines": { "node": ">=6" } @@ -4166,233 +3675,41 @@ "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-compat-utils": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", - "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", - "dev": true, - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "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-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-es-x": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.7.0.tgz", - "integrity": "sha512-aP3qj8BwiEDPttxQkZdI221DLKq9sI/qHolE2YSQL1/9+xk7dTV+tB1Fz8/IaCA+lnLA1bDEnvaS2LKs0k2Uig==", - "dev": true, - "funding": [ - "https://github.com/sponsors/ota-meshi", - "https://opencollective.com/eslint" - ], - "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0", - "eslint-compat-utils": "^0.5.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": ">=8" - } - }, - "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/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" + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-n": { - "version": "17.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.9.0.tgz", - "integrity": "sha512-CPSaXDXdrT4nsrOrO4mT4VB6FMUkoySRkHWuuJJHVqsIEjIeZgMY1H7AzSwPbDScikBmLN82KeM1u7ixV7PzGg==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "enhanced-resolve": "^5.17.0", - "eslint-plugin-es-x": "^7.5.0", - "get-tsconfig": "^4.7.0", - "globals": "^15.0.0", - "ignore": "^5.2.4", - "minimatch": "^9.0.0", - "semver": "^7.5.3" + "eslint": "bin/eslint.js" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": ">=8.23.0" - } - }, - "node_modules/eslint-plugin-n/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" } }, - "node_modules/eslint-plugin-n/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "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, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "eslint": ">=7.0.0" } }, "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==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", "dev": true, "dependencies": { "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" + "synckit": "^0.9.1" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -4416,35 +3733,35 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.3.tgz", - "integrity": "sha512-aoW4MV891jkUulwDApQbPYTVZmeuSyFrudpbTAQuj5Fv8VL+o6df2xIGpw8B0hPjAaih1/Fb0om9grCdyFYemA==", + "version": "7.35.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", + "integrity": "sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA==", "dev": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", - "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", "object.entries": "^1.1.8", "object.fromentries": "^2.0.8", - "object.hasown": "^1.1.4", "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11" + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { @@ -4548,15 +3865,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/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/eslint/node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -4631,9 +3939,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -4646,6 +3954,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -4657,6 +3966,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, "engines": { "node": ">=4.0" } @@ -4689,6 +3999,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, "engines": { "node": ">=0.8.x" } @@ -4815,7 +4126,8 @@ "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==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -4823,6 +4135,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -4853,52 +4171,40 @@ "node": ">=0.8.0" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, + "node_modules/figures/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==", + "dev": true, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "node": ">=0.8.0" } }, - "node_modules/file-loader/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==", + "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": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { @@ -4985,6 +4291,22 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", @@ -4995,6 +4317,7 @@ "version": "1.15.6", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, "funding": [ { "type": "individual", @@ -5047,17 +4370,62 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", + "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", + "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" }, "engines": { - "node": ">= 6" + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/fork-ts-checker-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==", + "dev": 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/forwarded": { @@ -5078,6 +4446,26 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "dev": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -5190,18 +4578,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz", - "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==", - "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", @@ -5238,12 +4614,13 @@ "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==" + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true }, "node_modules/globals": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.6.0.tgz", - "integrity": "sha512-UzcJi88Hw//CurUIRa9Jxb0vgOCcuD/MNjwmXp633cyaRKkCWACkoqHCtfZv43b1kqXGg/fpOa8bwgacCeXsVg==", + "version": "15.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.8.0.tgz", + "integrity": "sha512-VZAJ4cewHTExBWDHR6yptdIBlx9YSSZuwojj9Nt5mBRXQzrKakDsVKQ1J63sklLvzAJm0X5+RpO4i3Y2hcOnFw==", "dev": true, "engines": { "node": ">=18" @@ -5303,7 +4680,8 @@ "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==" + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true }, "node_modules/graphemer": { "version": "1.4.0", @@ -5345,6 +4723,7 @@ "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" } @@ -5657,9 +5036,9 @@ } }, "node_modules/i18n-iso-countries": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.11.2.tgz", - "integrity": "sha512-aquYZvUqNW968dFDezDpnz8/b0qRosO3A1XBXlVAdZREABcMKU+zdu7+ckLeWrCdF6YYPVkwsdktPaZOIHdIAA==", + "version": "7.11.3", + "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.11.3.tgz", + "integrity": "sha512-yxQVzNvxEaspSqNnCbqLvwTZNXXkGydWcSxytJYZYb0KH5pn13fdywuX0vFxmOg57Z8ff416AuKDx6Oqnx+j9w==", "dependencies": { "diacritics": "1.3.0" }, @@ -5683,6 +5062,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -5822,6 +5202,12 @@ "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==", + "dev": true + }, "node_modules/is-async-function": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", @@ -5890,9 +5276,9 @@ } }, "node_modules/is-core-module": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz", - "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dev": true, "dependencies": { "hasown": "^2.0.2" @@ -6340,16 +5726,13 @@ } }, "node_modules/jackspeak": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", - "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -6405,9 +5788,9 @@ } }, "node_modules/js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.11.0.tgz", + "integrity": "sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -6435,12 +5818,14 @@ "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==" + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "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==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -6448,15 +5833,16 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "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" + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" }, - "engines": { - "node": ">=6" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, "node_modules/jsx-ast-utils": { @@ -6483,12 +5869,12 @@ } }, "node_modules/keycloak-js": { - "version": "22.0.5", - "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-22.0.5.tgz", - "integrity": "sha512-a7ZwCZeHl8tpeJBy102tZtAnHslDUOA1Nf/sHNF3HYLchKpwoDuaitwIUiS2GnNUe+tlNKLlCqZS+Mi5K79m1w==", + "version": "25.0.2", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-25.0.2.tgz", + "integrity": "sha512-ACLf5O5PqzfDJwGqvLpqM0kflYWmyl3+T7M2C23gztJYccDxdfNP54+B9OkXz2GnDpLUId0ceoA+lbHw9t4Wng==", "dependencies": { - "base64-js": "^1.5.1", - "js-sha256": "^0.9.0" + "js-sha256": "^0.11.0", + "jwt-decode": "^4.0.0" } }, "node_modules/keyv": { @@ -6552,10 +5938,17 @@ "url": "https://github.com/sponsors/antonk52" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "peer": true, "dependencies": { "uc.micro": "^2.0.0" } @@ -6563,29 +5956,18 @@ "node_modules/linkifyjs": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz", - "integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==" + "integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==", + "peer": true }, "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==", + "dev": 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/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -6646,13 +6028,10 @@ } }, "node_modules/lru-cache": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", - "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "node_modules/make-error": { "version": "1.3.6", @@ -6660,25 +6039,10 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/mantine-contextmenu": { - "version": "7.10.2", - "resolved": "https://registry.npmjs.org/mantine-contextmenu/-/mantine-contextmenu-7.10.2.tgz", - "integrity": "sha512-xJIEJl5y9ZJ9emaArVFMl2fipKX3HUqyfWR5BmdNgI4c00TtBM9c887eRZafhVr4g14JpmZMu1l5JrtPNq0KGQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/icflorescu" - }, - "peerDependencies": { - "@mantine/core": ">=7", - "@mantine/hooks": ">=7", - "clsx": ">=2", - "react": ">=18.2" - } - }, "node_modules/mantine-datatable": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/mantine-datatable/-/mantine-datatable-7.10.4.tgz", - "integrity": "sha512-pVRVzU645mIKJXZrmE9rWyJG4ycxcfmfIJS4afrNfU7FhvhIEsJcZTGN+mT1xqwaHaGBwugWM6CqFVYdzwzJug==", + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/mantine-datatable/-/mantine-datatable-7.11.2.tgz", + "integrity": "sha512-4TUBw/LXJF+S5DpES26c+0CDFfVwUsO5or2bChHBZqg04Hpoev87i/JvRpuNgzvqRJaZ/EKqkSCuc1ldOrFgWg==", "funding": { "type": "github", "url": "https://github.com/sponsors/icflorescu" @@ -6694,6 +6058,7 @@ "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "peer": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -6706,6 +6071,19 @@ "markdown-it": "bin/markdown-it.mjs" } }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dev": true, + "dependencies": { + "repeat-string": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", @@ -6715,7 +6093,8 @@ "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "peer": true }, "node_modules/media-typer": { "version": "0.3.0", @@ -6754,7 +6133,8 @@ "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==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/merge2": { "version": "1.4.1", @@ -6803,6 +6183,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, "engines": { "node": ">= 0.6" } @@ -6811,6 +6192,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -6824,7 +6206,27 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "engines": { - "node": ">=6" + "node": ">=6" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" } }, "node_modules/minimalistic-assert": { @@ -6845,15 +6247,6 @@ "node": "*" } }, - "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.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", @@ -6863,14 +6256,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "engines": { - "node": "*" - } - }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -6903,6 +6288,7 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, "funding": [ { "type": "github", @@ -6934,7 +6320,8 @@ "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==" + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, "node_modules/no-case": { "version": "3.0.4", @@ -6946,6 +6333,12 @@ "tslib": "^2.0.3" } }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -6956,9 +6349,10 @@ } }, "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==" + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.17.tgz", + "integrity": "sha512-Ww6ZlOiEQfPfXM45v17oabk77Z7mg5bOt7AjDyzy7RjK9OrLrLC8dyZQoAPEOtFX9SaNf1Tdvr5gRJWdTJj7GA==", + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -7072,37 +6466,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.hasown": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.4.tgz", - "integrity": "sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -7218,7 +6581,8 @@ "node_modules/orderedmap": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", - "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==" + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", + "peer": true }, "node_modules/p-limit": { "version": "3.1.0", @@ -7313,6 +6677,24 @@ "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==", + "dev": true, + "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/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -7402,10 +6784,22 @@ "node": ">=8" } }, + "node_modules/phosphor-react": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/phosphor-react/-/phosphor-react-1.4.1.tgz", + "integrity": "sha512-gO5j7U0xZrdglTAYDYPACU4xDOFBTJmptrrB/GeR+tHhCZF3nUMyGmV/0hnloKjuTrOmpSFlbfOY78H39rgjUQ==", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=16" + } + }, "node_modules/picocolors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -7523,9 +6917,10 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -7542,7 +6937,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -7584,9 +6979,9 @@ } }, "node_modules/postcss-convert-values": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.1.tgz", - "integrity": "sha512-9x2ofb+hYPwHWMlWAzyWys2yMDZYGfkX9LodbaVTmLdlupmtH2AGvj8Up95wzzNPRDEzPIxQIkUaPJew3bT6xA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.2.tgz", + "integrity": "sha512-MuZIF6HJ4izko07Q0TgW6pClalI4al6wHRNPkFzqQdwAwG7hPn0lA58VZdxyb2Vl5AYjJ1piO+jgF9EnTjQwQQ==", "dev": true, "dependencies": { "browserslist": "^4.23.1", @@ -7753,6 +7148,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, "engines": { "node": "^10 || ^12 || >= 14" }, @@ -7764,6 +7160,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz", "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==", + "dev": true, "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -7780,6 +7177,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz", "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==", + "dev": true, "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -7794,6 +7192,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, "dependencies": { "icss-utils": "^5.0.0" }, @@ -7985,9 +7384,10 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", + "dev": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -8030,7 +7430,8 @@ "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==" + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -8042,9 +7443,9 @@ } }, "node_modules/prettier": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", - "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -8078,6 +7479,15 @@ "renderkid": "^3.0.0" } }, + "node_modules/pretty-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", + "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -8098,6 +7508,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "peer": true, "dependencies": { "prosemirror-transform": "^1.0.0" } @@ -8106,6 +7517,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0" } @@ -8114,6 +7526,7 @@ "version": "1.5.2", "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz", "integrity": "sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==", + "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -8124,6 +7537,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0", @@ -8134,6 +7548,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "peer": true, "dependencies": { "prosemirror-keymap": "^1.0.0", "prosemirror-model": "^1.0.0", @@ -8142,9 +7557,10 @@ } }, "node_modules/prosemirror-history": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.0.tgz", - "integrity": "sha512-UUiGzDVcqo1lovOPdi9YxxUps3oBFWAIYkXLu3Ot+JPv1qzVogRbcizxK3LhHmtaUxclohgiOVesRw5QSlMnbQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "peer": true, "dependencies": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", @@ -8156,6 +7572,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" @@ -8165,6 +7582,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" @@ -8174,6 +7592,7 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.0.tgz", "integrity": "sha512-UziddX3ZYSYibgx8042hfGKmukq5Aljp2qoBiJRejD/8MH70siQNz5RB1TrdTPheqLMy4aCe4GYNF10/3lQS5g==", + "peer": true, "dependencies": { "markdown-it": "^14.0.0", "prosemirror-model": "^1.20.0" @@ -8183,6 +7602,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "peer": true, "dependencies": { "crelt": "^1.0.0", "prosemirror-commands": "^1.0.0", @@ -8191,25 +7611,28 @@ } }, "node_modules/prosemirror-model": { - "version": "1.21.3", - "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.21.3.tgz", - "integrity": "sha512-nt2Xs/RNGepD9hrrkzXvtCm1mpGJoQfFSPktGa0BF/aav6XsnmVGZ9sTXNWRLupAz5SCLa3EyKlFeK7zJWROKg==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.2.tgz", + "integrity": "sha512-I4lS7HHIW47D0Xv/gWmi4iUWcQIDYaJKd8Hk4+lcSps+553FlQrhmxtItpEvTr75iAruhzVShVp6WUwsT6Boww==", + "peer": true, "dependencies": { "orderedmap": "^2.0.0" } }, "node_modules/prosemirror-schema-basic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.2.tgz", - "integrity": "sha512-/dT4JFEGyO7QnNTe9UaKUhjDXbTNkiWTq/N4VpKaF79bBjSExVV2NXmJpcM7z/gD7mbqNjxbmWW5nf1iNSSGnw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", + "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", + "peer": true, "dependencies": { "prosemirror-model": "^1.19.0" } }, "node_modules/prosemirror-schema-list": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.0.tgz", - "integrity": "sha512-nZOIq/AkBSzCENxUyLm5ltWE53e2PLk65ghMN8qLQptOmDVixZlPqtMeQdiNw0odL9vNpalEjl3upgRkuJ/Jyw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz", + "integrity": "sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==", + "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -8220,6 +7643,7 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -8230,6 +7654,7 @@ "version": "1.3.7", "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.3.7.tgz", "integrity": "sha512-oEwX1wrziuxMtwFvdDWSFHVUWrFJWt929kVVfHvtTi8yvw+5ppxjXZkMG/fuTdFo+3DXyIPSKfid+Be1npKXDA==", + "peer": true, "dependencies": { "prosemirror-keymap": "^1.1.2", "prosemirror-model": "^1.8.1", @@ -8239,31 +7664,34 @@ } }, "node_modules/prosemirror-trailing-node": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.8.tgz", - "integrity": "sha512-ujRYhSuhQb1Jsarh1IHqb2KoSnRiD7wAMDGucP35DN7j5af6X7B18PfdPIrbwsPTqIAj0fyOvxbuPsWhNvylmA==", + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.9.tgz", + "integrity": "sha512-YvyIn3/UaLFlFKrlJB6cObvUhmwFNZVhy1Q8OpW/avoTbD/Y7H5EcjK4AZFKhmuS6/N6WkGgt7gWtBWDnmFvHg==", + "peer": true, "dependencies": { "@remirror/core-constants": "^2.0.2", "escape-string-regexp": "^4.0.0" }, "peerDependencies": { - "prosemirror-model": "^1.19.0", + "prosemirror-model": "^1.22.1", "prosemirror-state": "^1.4.2", - "prosemirror-view": "^1.31.2" + "prosemirror-view": "^1.33.8" } }, "node_modules/prosemirror-transform": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz", "integrity": "sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==", + "peer": true, "dependencies": { "prosemirror-model": "^1.21.0" } }, "node_modules/prosemirror-view": { - "version": "1.33.8", - "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.8.tgz", - "integrity": "sha512-4PhMr/ufz2cdvFgpUAnZfs+0xij3RsFysreeG9V/utpwX7AJtYCDVyuRxzWoMJIEf4C7wVihuBNMPpFLPCiLQw==", + "version": "1.33.9", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.9.tgz", + "integrity": "sha512-xV1A0Vz9cIcEnwmMhKKFAOkfIp8XmJRnaZoPqNXrPS7EK5n11Ov8V76KhR0RsfQd/SIzmWY+bg+M44A2Lx/Nnw==", + "peer": true, "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -8292,15 +7720,11 @@ "node": ">= 0.10" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -8309,6 +7733,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "peer": true, "engines": { "node": ">=6" } @@ -8352,6 +7777,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -8489,11 +7915,11 @@ } }, "node_modules/react-router": { - "version": "6.24.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.24.0.tgz", - "integrity": "sha512-sQrgJ5bXk7vbcC4BxQxeNa5UmboFm35we1AFK0VvQaz9g0LzxEIuLOhHIoZ8rnu9BO21ishGeL9no1WB76W/eg==", + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz", + "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", "dependencies": { - "@remix-run/router": "1.17.0" + "@remix-run/router": "1.18.0" }, "engines": { "node": ">=14.0.0" @@ -8503,12 +7929,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.24.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.24.0.tgz", - "integrity": "sha512-960sKuau6/yEwS8e+NVEidYQb1hNjAYM327gjEyXlc6r3Skf2vtwuJ2l7lssdegD2YjoKG5l8MsVyeTDlVeY8g==", + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", + "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", "dependencies": { - "@remix-run/router": "1.17.0", - "react-router": "6.24.0" + "@remix-run/router": "1.18.0", + "react-router": "6.25.1" }, "engines": { "node": ">=14.0.0" @@ -8675,6 +8101,15 @@ "strip-ansi": "^6.0.1" } }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -8737,15 +8172,6 @@ "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/retry": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", @@ -8766,9 +8192,9 @@ } }, "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { @@ -8776,15 +8202,13 @@ }, "bin": { "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rope-sequence": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", - "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==" + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "peer": true }, "node_modules/run-applescript": { "version": "7.0.0", @@ -8843,6 +8267,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -8882,9 +8307,9 @@ "dev": true }, "node_modules/sass": { - "version": "1.75.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz", - "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==", + "version": "1.77.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.8.tgz", + "integrity": "sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -8966,15 +8391,15 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", - "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -9019,9 +8444,10 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -9078,6 +8504,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, "dependencies": { "randombytes": "^2.1.0" } @@ -9317,6 +8744,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -9325,6 +8753,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -9333,6 +8762,7 @@ "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==", + "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -9368,6 +8798,21 @@ "wbuf": "^1.7.3" } }, + "node_modules/speed-measure-webpack-plugin": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.5.0.tgz", + "integrity": "sha512-Re0wX5CtM6gW7bZA64ONOfEPEhwbiSF/vz6e2GvadjuaPrQcHTQdRGsD8+BE7iUOysXH8tIenkPCQBEcspXsNg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "webpack": "^1 || ^2 || ^3 || ^4 || ^5" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -9377,6 +8822,12 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -9477,6 +8928,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", @@ -9551,15 +9012,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -9731,9 +9183,9 @@ } }, "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", "dev": true, "dependencies": { "@pkgr/core": "^0.1.0", @@ -9746,6 +9198,12 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/synckit/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", @@ -9755,14 +9213,16 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, "engines": { "node": ">=6" } }, "node_modules/terser": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz", - "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==", + "version": "5.31.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.3.tgz", + "integrity": "sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==", + "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -9780,6 +9240,7 @@ "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==", + "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -9813,6 +9274,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -9826,6 +9288,7 @@ "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==", + "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -9843,6 +9306,7 @@ "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -9856,7 +9320,8 @@ "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==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "node_modules/text-table": { "version": "0.2.0", @@ -9886,6 +9351,7 @@ "version": "6.3.7", "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "peer": true, "dependencies": { "@popperjs/core": "^2.9.0" } @@ -10020,34 +9486,10 @@ } } }, - "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/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/tslib": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" }, "node_modules/type-check": { "version": "0.4.0", @@ -10062,9 +9504,9 @@ } }, "node_modules/type-fest": { - "version": "4.20.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz", - "integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==", + "version": "4.22.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.22.1.tgz", + "integrity": "sha512-9tHNEa0Ov81YOopiVkcCJVz5TM6AEQ+CHHjFIktqPnE3NV0AHIkx+gh9tiCl58m/66wWxkOC9eltpa75J4lQPA==", "engines": { "node": ">=16" }, @@ -10159,9 +9601,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10174,7 +9616,8 @@ "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "peer": true }, "node_modules/unbox-primitive": { "version": "1.0.2", @@ -10194,7 +9637,8 @@ "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==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/unicorn-magic": { "version": "0.1.0", @@ -10208,6 +9652,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -10218,9 +9671,10 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", - "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "dev": true, "funding": [ { "type": "opencollective", @@ -10250,6 +9704,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -10333,9 +9788,10 @@ } }, "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peer": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } @@ -10343,7 +9799,8 @@ "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==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/utila": { "version": "0.4.0", @@ -10387,12 +9844,14 @@ "node_modules/w3c-keyname": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "peer": true }, "node_modules/watchpack": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -10411,9 +9870,10 @@ } }, "node_modules/webpack": { - "version": "5.91.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.91.0.tgz", - "integrity": "sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==", + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -10421,10 +9881,10 @@ "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", + "acorn-import-attributes": "^1.9.5", "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -10546,9 +10006,9 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.2.1.tgz", - "integrity": "sha512-hRLz+jPQXo999Nx9fXVdKlg/aehsw1ajA9skAneGmT03xwmyuhvF93p6HUKKbWhXdcERtGTzUCtIQr+2IQegrA==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.3.0.tgz", + "integrity": "sha512-xD2qnNew+F6KwOGZR7kWdbIou/ud7cVqLEXeK1q0nHcNsX/u7ul/fSdlOTX4ntSL5FNFy7ZJJXbf0piF591JYw==", "dev": true, "dependencies": { "colorette": "^2.0.10", @@ -10643,9 +10103,9 @@ } }, "node_modules/webpack-dev-server/node_modules/glob": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", - "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", @@ -10658,9 +10118,6 @@ "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -10681,9 +10138,9 @@ } }, "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.7.tgz", - "integrity": "sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.9.tgz", + "integrity": "sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==", "dev": true, "dependencies": { "glob": "^10.3.7" @@ -10692,16 +10149,16 @@ "rimraf": "dist/esm/bin.mjs" }, "engines": { - "node": ">=14.18" + "node": "14 >=14.20 || 16 >=16.20 || >=18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -10737,6 +10194,7 @@ "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==", + "dev": true, "engines": { "node": ">=10.13.0" } @@ -10745,6 +10203,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -10757,6 +10216,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, "engines": { "node": ">=4.0" } @@ -10765,6 +10225,7 @@ "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==", + "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -10778,6 +10239,65 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/webpackbar": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", + "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "consola": "^3.2.3", + "figures": "^3.2.0", + "markdown-table": "^2.0.0", + "pretty-time": "^1.1.0", + "std-env": "^3.7.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "webpack": "3 || 4 || 5" + } + }, + "node_modules/webpackbar/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/webpackbar/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/webpackbar/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/websocket-driver": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", @@ -11051,33 +10571,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zustand": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz", - "integrity": "sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg==", - "dependencies": { - "use-sync-external-store": "1.2.0" - }, - "engines": { - "node": ">=12.7.0" - }, - "peerDependencies": { - "@types/react": ">=16.8", - "immer": ">=9.0.6", - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - } - } } } } diff --git a/client/package.json b/client/package.json index 2b090377..0b570f4e 100644 --- a/client/package.json +++ b/client/package.json @@ -1,91 +1,71 @@ { - "name": "client", - "version": "2.0.0", + "name": "thesis-management", + "version": "3.0.0", "main": "src/index.tsx", "license": "MIT", + "sideEffects": false, + "packageManager": "npm@7.24.0", "scripts": { - "dev": "webpack serve --open --mode development", + "dev": "webpack serve --open --env NODE_ENV=development", "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"", "lint:fix": "eslint \"src/**/*.{js,jsx,ts,tsx}\" --fix", - "build": "webpack --mode=production --env NODE_ENV=production", - "check-performance": "webpack --mode=production --env NODE_ENV=production --env BUNDLE_SIZE=true" + "build": "webpack --env NODE_ENV=production", + "check-bundle-size": "webpack --env NODE_ENV=production --env BUNDLE_SIZE=true", + "check-build-speed": "BUILD_SPEED=true webpack --env NODE_ENV=production" }, "dependencies": { "@formkit/auto-animate": "0.8.2", - "@mantine/core": "7.11.0", - "@mantine/dates": "7.11.0", - "@mantine/dropzone": "7.11.0", - "@mantine/form": "7.11.0", - "@mantine/hooks": "7.11.0", - "@mantine/notifications": "7.11.0", - "@mantine/tiptap": "7.11.0", - "@tabler/icons-react": "3.7.0", - "@tanstack/react-query": "5.48.0", - "@tanstack/react-query-devtools": "5.48.0", - "@tiptap/core": "2.4.0", - "@tiptap/extension-highlight": "2.4.0", - "@tiptap/extension-link": "2.4.0", - "@tiptap/extension-subscript": "2.4.0", - "@tiptap/extension-superscript": "2.4.0", - "@tiptap/extension-text-align": "2.4.0", - "@tiptap/extension-underline": "2.4.0", - "@tiptap/pm": "2.4.0", - "@tiptap/react": "2.4.0", - "@tiptap/starter-kit": "2.4.0", - "axios": "1.7.2", - "css-loader": "7.1.2", - "dayjs": "1.11.11", - "file-loader": "6.2.0", - "i18n-iso-countries": "7.11.2", + "@mantine/core": "7.11.2", + "@mantine/dates": "7.11.2", + "@mantine/dropzone": "7.11.2", + "@mantine/form": "7.11.2", + "@mantine/hooks": "7.11.2", + "@mantine/notifications": "7.11.2", + "@mantine/tiptap": "7.11.2", + "i18n-iso-countries": "7.11.3", "jwt-decode": "4.0.0", - "keycloak-js": "22.0.5", - "mantine-contextmenu": "7.10.2", - "mantine-datatable": "7.10.4", - "moment": "2.30.1", + "keycloak-js": "25.0.2", + "mantine-datatable": "7.11.2", + "phosphor-react": "1.4.1", "react": "18.3.1", "react-dom": "18.3.1", - "react-router-dom": "6.24.0", - "zustand": "4.5.4" + "react-router-dom": "6.25.1" }, "devDependencies": { - "@eslint/compat": "1.1.0", + "@eslint/compat": "1.1.1", "@eslint/eslintrc": "3.1.0", - "@eslint/js": "9.5.0", - "@tanstack/eslint-plugin-query": "5.47.0", - "@types/copy-webpack-plugin": "10.1.0", - "@types/dotenv-webpack": "7.0.7", - "@types/eslint": "8.56.10", - "@types/node": "20.12.12", + "@eslint/js": "8.57.0", "@types/react": "18.3.3", "@types/react-dom": "18.3.0", - "@types/webpack": "5.28.5", - "@types/webpack-bundle-analyzer": "4.7.0", - "@typescript-eslint/eslint-plugin": "7.14.1", - "@typescript-eslint/parser": "7.14.1", - "clean-webpack-plugin": "^4.0.0", + "@typescript-eslint/eslint-plugin": "7.16.1", + "@typescript-eslint/parser": "7.16.1", + "clean-webpack-plugin": "4.0.0", "compression-webpack-plugin": "11.1.0", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", "css-minimizer-webpack-plugin": "7.0.0", - "dotenv-webpack": "8.1.0", "eslint": "8.57.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "2.29.1", - "eslint-plugin-n": "17.9.0", - "eslint-plugin-prettier": "5.1.3", - "eslint-plugin-react": "7.34.3", + "eslint-plugin-prettier": "5.2.1", + "eslint-plugin-react": "7.35.0", "eslint-plugin-react-hooks": "4.6.2", - "globals": "15.6.0", + "fork-ts-checker-webpack-plugin": "9.0.2", + "globals": "15.8.0", "html-webpack-plugin": "5.6.0", - "prettier": "3.3.2", - "sass": "1.75.0", + "mini-css-extract-plugin": "2.9.0", + "prettier": "3.3.3", + "sass": "1.77.8", "sass-loader": "14.2.1", + "speed-measure-webpack-plugin": "1.5.0", "style-loader": "4.0.0", + "terser-webpack-plugin": "5.3.10", "ts-loader": "9.5.1", "ts-node": "10.9.2", - "typescript": "5.4.5", - "webpack": "5.91.0", + "typescript": "5.5.3", + "webpack": "5.93.0", "webpack-bundle-analyzer": "4.10.2", "webpack-cli": "5.1.4", - "webpack-dev-server": "5.0.4" - }, - "packageManager": "yarn@4.1.0" + "webpack-dev-server": "5.0.4", + "webpackbar": "6.0.1" + } } diff --git a/client/public/generate-runtime-env.js b/client/public/generate-runtime-env.js new file mode 100644 index 00000000..b4046cfc --- /dev/null +++ b/client/public/generate-runtime-env.js @@ -0,0 +1,30 @@ +const { promises: fsp } = require('fs'); + +const ALLOWED_ENVIRONMENT_VARIABLES = [ + 'API_SERVER_HOST', + 'KEYCLOAK_HOST', + 'KEYCLOAK_REALM_NAME', + 'KEYCLOAK_CLIENT_ID', + // optional + 'APPLICATION_TITLE', + 'FOCUS_TOPICS', + 'RESEARCH_AREAS', + 'GENDERS', + 'STUDY_DEGREES', + 'STUDY_PROGRAMS', + 'UNIVERSITY_ID_JWT_FIELD' +]; + +async function generateConfig() { + const runtimeEnvironment = {}; + + for (const key of ALLOWED_ENVIRONMENT_VARIABLES) { + if (process.env[key]) { + runtimeEnvironment[key] = process.env[key]; + } + } + + await fsp.writeFile('runtime-env.js', `window.RUNTIME_ENVIRONMENT_VARIABLES=${JSON.stringify(runtimeEnvironment)};`, 'utf-8'); +} + +void generateConfig(); \ No newline at end of file diff --git a/client/public/runtime-env.js b/client/public/runtime-env.js new file mode 100644 index 00000000..c342e834 --- /dev/null +++ b/client/public/runtime-env.js @@ -0,0 +1 @@ +window.RUNTIME_ENVIRONMENT_VARIABLES={}; \ No newline at end of file diff --git a/client/scripts/data/german-names.json b/client/scripts/data/german-names.json new file mode 100644 index 00000000..d510cb07 --- /dev/null +++ b/client/scripts/data/german-names.json @@ -0,0 +1,8 @@ +[ + "Melanie Kortig", + "Gabriele Gloeckner", + "Wolfgang Papst", + "Tim Eberhardt", + "Daniela Wirth", + "Tobias Kirsch" +] \ No newline at end of file diff --git a/client/scripts/data/international-names.json b/client/scripts/data/international-names.json new file mode 100644 index 00000000..0fb82811 --- /dev/null +++ b/client/scripts/data/international-names.json @@ -0,0 +1,102 @@ +[ + "Remington Krajcik", + "Kiarra Gottlieb", + "Derek Toy", + "Mrs. Mertie Graham", + "Garnett Kerluke", + "Art Jacobi", + "Cicero Fisher", + "Vita Padberg", + "Susie Fisher", + "Rebekah Schmitt", + "Caesar Aufderhar", + "Dayton Shields Jr.", + "Tanner Bailey", + "Margret Gaylord", + "Richard Graham", + "Nicolette Considine", + "Miss Beau McClure", + "Georgette Kshlerin", + "Mr. Theresa Nienow", + "Joanne Runolfsdottir", + "Mellie Larson", + "Bell Von", + "Valerie Jenkins", + "Giovanna Tromp", + "Brandy Rau", + "Krista Grant", + "Kaia Reichel", + "Connie Hessel", + "Miss Graham Reichel", + "Dr. Wanda Herzog", + "Lilla Heidenreich", + "Jaquan Rogahn", + "Vance Smitham", + "Anderson Hansen", + "Newell Beahan", + "Ms. Penelope Dickinson", + "Waldo O'Keefe", + "Mrs. Jacklyn Altenwerth", + "Jillian Swift", + "Ms. Idell Jast", + "Ms. Emily Crist", + "Kim Dach", + "Tyrique Luettgen", + "Candice Conn", + "Mallie Feest", + "Nayeli Erdman", + "Pete Gulgowski V", + "Eric Satterfield", + "Zane Fadel", + "Ms. Adelle Abshire", + "Bernita Koss", + "Raphael Strosin", + "Joshuah Schultz", + "Toby Crist", + "Carissa Pouros IV", + "Brenna Wyman", + "Theresia Pagac", + "Kelsie Hegmann", + "Miss Modesta Sporer", + "Aidan Botsford", + "Tyshawn Klocko", + "Sasha Lueilwitz", + "Tony Kihn", + "Johnathan Hoppe", + "Johanna Daniel", + "Albertha Hilll III", + "Laisha Marvin MD", + "Nikolas Rodriguez", + "Miss Mozelle Bergnaum", + "Ubaldo Roberts", + "Kolby Hickle", + "Dandre McDermott", + "Laney Schimmel", + "Alba Goodwin", + "Pamela Hickle", + "Zetta Halvorson", + "Leilani Upton", + "Bertrand Hyatt Sr.", + "Michele Morar", + "Maryam Pacocha", + "Nigel Thiel", + "Dr. Ariel Bashirian", + "Einar Larkin", + "Coty Herzog", + "Ms. Jonathan Predovic", + "Dorthy Rutherford MD", + "Molly Upton", + "Ceasar Littel", + "Mrs. Deron Swaniawski", + "Mr. Dominic Gottlieb", + "Miracle Gusikowski", + "Angel Lebsack", + "Miss Gia Stoltenberg", + "Berry DuBuque", + "Alisa Vandervort", + "Adelle VonRueden MD", + "Florencio Torphy", + "Maurine Kertzmann", + "Dr. Joshuah Kuhlman", + "Idell Lebsack" +] \ No newline at end of file diff --git a/client/scripts/data/topics.json b/client/scripts/data/topics.json new file mode 100644 index 00000000..9612be2a --- /dev/null +++ b/client/scripts/data/topics.json @@ -0,0 +1,99 @@ +[ + "The Impact of Climate Change on Global Agricultural Productivity", + "Artificial Intelligence in Healthcare: Opportunities and Challenges", + "Cybersecurity in the Age of Digital Transformation", + "Sustainable Urban Development: Case Studies and Future Prospects", + "The Role of Big Data in Modern Business Decision Making", + "Renewable Energy Technologies: A Comparative Analysis", + "Social Media Influence on Political Campaigns", + "Blockchain Technology in Financial Services", + "Educational Inequality and Policy Interventions", + "Mental Health and Well-being in the Workplace", + "The Future of Remote Work: Trends and Implications", + "Cultural Heritage Preservation in the Digital Age", + "The Economics of Renewable Energy Adoption", + "The Evolution of E-commerce in the Digital Age", + "Nanotechnology in Medicine: Applications and Ethical Considerations", + "The Role of Microbiomes in Human Health", + "Climate Change Adaptation Strategies for Coastal Cities", + "The Ethics of Artificial Intelligence and Machine Learning", + "Gender Disparities in STEM Fields: Causes and Solutions", + "The Effectiveness of Online Learning in Higher Education", + "Consumer Behavior and Marketing Strategies in the Digital Age", + "The Role of Artificial Intelligence in Predictive Analytics", + "The Impact of Globalization on Local Cultures", + "Sustainable Supply Chain Management", + "Smart Cities: Technologies, Challenges, and Opportunities", + "The Intersection of Art and Technology in Contemporary Society", + "Food Security and Sustainable Agriculture", + "The Role of Genetics in Personalized Medicine", + "Public Health Strategies for Pandemic Preparedness", + "The Future of Autonomous Vehicles", + "The Role of Social Enterprises in Economic Development", + "The Impact of Social Media on Mental Health", + "Renewable Energy Policy and Implementation", + "The Influence of Technology on Modern Education", + "Corporate Social Responsibility in the Global Economy", + "The Development of Quantum Computing", + "The Impact of Immigration on National Economies", + "Sustainable Tourism Practices and Their Impacts", + "The Role of Artificial Intelligence in Creative Industries", + "Climate Policy and Environmental Justice", + "The Future of Space Exploration", + "The Impact of Telemedicine on Healthcare Delivery", + "Urbanization and its Environmental Impacts", + "The Ethics of Genetic Engineering", + "The Role of Public Policy in Reducing Income Inequality", + "The Impact of Digital Media on Journalism", + "Environmental Sustainability in the Fashion Industry", + "The Role of Machine Learning in Financial Forecasting", + "The Impact of Technological Advancements on Employment", + "The Role of Education in Sustainable Development", + "The Influence of Cultural Diversity on Organizational Performance", + "The Economics of Health Care Systems", + "The Role of Innovation in Economic Growth", + "The Impact of Artificial Intelligence on Consumer Privacy", + "Strategies for Mitigating Climate Change", + "The Role of Technology in Modern Warfare", + "The Influence of Corporate Governance on Financial Performance", + "The Impact of Environmental Regulations on Business Practices", + "The Role of Media in Shaping Public Opinion", + "The Future of Renewable Energy Storage Solutions", + "The Role of Biotechnology in Agriculture", + "The Impact of Digital Transformation on Customer Experience", + "The Role of Data Analytics in Sports Performance", + "The Influence of Global Trade Policies on Emerging Markets", + "The Role of Artificial Intelligence in Cybersecurity", + "The Impact of Climate Change on Biodiversity", + "The Role of Financial Technology in Banking", + "The Ethics of Data Privacy in the Digital Age", + "The Impact of Urban Green Spaces on Public Health", + "The Role of Blockchain in Supply Chain Management", + "The Influence of Social Media on Brand Loyalty", + "The Role of Innovation in the Pharmaceutical Industry", + "The Impact of Climate Change on Water Resources", + "The Role of Government Policy in Renewable Energy Adoption", + "The Influence of Artificial Intelligence on Human Creativity", + "The Impact of E-commerce on Traditional Retail", + "The Role of Environmental Education in Schools", + "The Influence of Corporate Culture on Employee Engagement", + "The Impact of Technology on Modern Healthcare", + "The Role of Artificial Intelligence in Drug Discovery", + "The Influence of Media Coverage on Public Perception of Climate Change", + "The Role of International Organizations in Global Health", + "The Impact of Technology on the Music Industry", + "The Role of Leadership in Organizational Change", + "The Influence of Social Networks on Consumer Behavior", + "The Impact of Climate Change on Migration Patterns", + "The Role of Policy in Promoting Sustainable Development", + "The Influence of Technology on Cultural Identity", + "The Impact of Renewable Energy on Economic Growth", + "The Role of Social Innovation in Addressing Social Issues", + "The Influence of Environmental Policies on Corporate Strategy", + "The Impact of Climate Change on Food Security", + "The Role of Artificial Intelligence in Enhancing User Experience", + "The Influence of Globalization on Higher Education", + "The Impact of Digital Technologies on the Creative Process", + "The Role of Financial Markets in Economic Stability", + "The Influence of Public Opinion on Environmental Policy" +] \ No newline at end of file diff --git a/client/scripts/generate-thesis-graph-data.ts b/client/scripts/generate-thesis-graph-data.ts new file mode 100644 index 00000000..c5c016ea --- /dev/null +++ b/client/scripts/generate-thesis-graph-data.ts @@ -0,0 +1,77 @@ +import topics from './data/topics.json' +import germanNames from './data/german-names.json' +import internationalNames from './data/international-names.json' +import { + IThesisProgressChartDataElement, + ThesisState, +} from '../src/pages/ThesisOverviewPage/types/chart' +import { randomArrayElement } from '../src/utils/array' + +const states: ThesisState[] = [ + ThesisState.proposal, + ThesisState.active, + ThesisState.submitted, + ThesisState.graded, + ThesisState.finished, +] +const duration: Record = { + [ThesisState.proposal]: 1000 * 3600 * 24 * 30, + [ThesisState.active]: 1000 * 3600 * 24 * 30 * 4, + [ThesisState.submitted]: 1000 * 3600 * 24 * 30, + [ThesisState.graded]: 1000 * 3600 * 24 * 15, + [ThesisState.finished]: 1000 * 3600 * 24 * 15, +} + +const currentTime = Date.now() +const data: IThesisProgressChartDataElement[] = [] + +for (let a = 0; a < Math.min(internationalNames.length, topics.length); a++) { + const state = randomArrayElement(states) + + const startTime = + state === ThesisState.finished + ? currentTime - Math.floor(1000 * 3600 * 24 * 30 * (4 + Math.random() * 8)) + : currentTime - Math.floor(1000 * 3600 * 24 * 30 * Math.random() * 4) + let timeCounter = startTime + + const element: IThesisProgressChartDataElement = { + advisor: randomArrayElement(germanNames), + student: internationalNames[a], + topic: topics[a], + started_at: timeCounter, + ended_at: null, + state: state, + timeline: [], + } + + for (let b = 0; b <= states.indexOf(state); b++) { + element.timeline.push({ + state: states[b], + started_at: timeCounter, + }) + + timeCounter += Math.floor(duration[states[b]] * (0.5 + Math.random())) + + if (timeCounter >= currentTime) { + const timeRatio = (currentTime - startTime) / (timeCounter - startTime) + + let lastStartedAt = startTime + + for (const c of element.timeline) { + c.started_at = c.started_at - Math.floor((c.started_at - lastStartedAt) * timeRatio) + + lastStartedAt = c.started_at + } + + timeCounter = timeCounter - Math.floor((timeCounter - lastStartedAt) * timeRatio) + } + } + + if (state === ThesisState.finished) { + element.ended_at = Math.min(currentTime, timeCounter) + } + + data.push(element) +} + +console.log(JSON.stringify({ advisors: germanNames, data })) diff --git a/client/src/App.tsx b/client/src/App.tsx deleted file mode 100644 index f9ee74ac..00000000 --- a/client/src/App.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { MantineProvider } from '@mantine/core' -import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom' -import { ApplicationSubmissionPage } from './student/ApplicationSubmission/ApplicationSubmissionPage' -import { Notifications } from '@mantine/notifications' -import { ApplicationFormAccessMode } from './student/form/ThesisApplicationForm' -import { ThesisApplicationForm } from './student/form/ThesisApplicationForm' -import { ManagementConsole } from './management/ManagementConsole' -import { ContextMenuProvider } from 'mantine-contextmenu' -import '../public/favicon.svg' -import { Fallback } from './utilities/Fallback/Fallback' - -import '@mantine/core/styles.layer.css' -import '@mantine/dates/styles.layer.css' -import '@mantine/notifications/styles.css' -import '@mantine/tiptap/styles.css' -import '@mantine/dropzone/styles.css' -import 'mantine-contextmenu/styles.layer.css' -import 'mantine-datatable/styles.layer.css' -import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import { ReactQueryDevtools } from '@tanstack/react-query-devtools' - -const queryClient = new QueryClient({ - defaultOptions: { - queries: { - refetchOnWindowFocus: false, - }, - }, -}) - -export const App = (): JSX.Element => { - return ( - - - - - - - - } - /> - } - /> - } - /> - } /> - } /> - - - - - - ) -} - -export default App diff --git a/client/src/app/App.tsx b/client/src/app/App.tsx new file mode 100644 index 00000000..d897cd94 --- /dev/null +++ b/client/src/app/App.tsx @@ -0,0 +1,28 @@ +import React from 'react' +import { MantineProvider } from '@mantine/core' +import { Notifications } from '@mantine/notifications' +import '../../public/favicon.svg' +import AppRoutes from './Routes' +import AuthenticationProvider from '../contexts/AuthenticationContext/AuthenticationProvider' + +import '@mantine/core/styles.layer.css' +import '@mantine/dates/styles.layer.css' +import '@mantine/notifications/styles.css' +import '@mantine/tiptap/styles.css' +import '@mantine/dropzone/styles.css' +import 'mantine-datatable/styles.layer.css' + +import './styles.scss' + +const App = () => { + return ( + + + + + + + ) +} + +export default App diff --git a/client/src/app/Routes.tsx b/client/src/app/Routes.tsx new file mode 100644 index 00000000..1373c2eb --- /dev/null +++ b/client/src/app/Routes.tsx @@ -0,0 +1,174 @@ +import React, { lazy, Suspense } from 'react' +import { BrowserRouter, Route, Routes } from 'react-router-dom' +import AuthenticatedArea from './layout/AuthenticatedArea/AuthenticatedArea' +import { LegacyApplicationFormAccessMode } from '../legacy/interfaces/application' +import { Center, Loader } from '@mantine/core' + +const LegacyThesisApplicationForm = lazy( + () => import('../pages/LegacySubmitApplicationPage/LegacyThesisApplicationForm'), +) +const LegacyApplicationReviewPage = lazy( + () => import('../pages/LegacyApplicationReviewPage/LegacyApplicationReviewPage'), +) +const NotFoundPage = lazy(() => import('../pages/NotFoundPage/NotFoundPage')) +const ThesisOverviewPage = lazy(() => import('../pages/ThesisOverviewPage/ThesisOverviewPage')) +const DashboardPage = lazy(() => import('../pages/DashboardPage/DashboardPage')) +const LogoutPage = lazy(() => import('../pages/LogoutPage/LogoutPage')) +const MyInformationPage = lazy(() => import('../pages/MyInformationPage/MyInformationPage')) +const SubmitApplicationStepOnePage = lazy( + () => import('../pages/SubmitApplicationPage/SubmitApplicationStepOnePage'), +) +const SubmitApplicationStepTwoPage = lazy( + () => import('../pages/SubmitApplicationPage/SubmitApplicationStepTwoPage'), +) +const CreateTopicPage = lazy(() => import('../pages/CreateTopicPage/CreateTopicPage')) +const TopicPage = lazy(() => import('../pages/TopicPage/TopicPage')) +const ReviewApplicationPage = lazy( + () => import('../pages/ReviewApplicationPage/ReviewApplicationPage'), +) +const ThesisPage = lazy(() => import('../pages/ThesisPage/ThesisPage')) +const SubmitProposalPage = lazy(() => import('../pages/SubmitProposalPage/SubmitProposalPage')) +const SubmitAssessmentPage = lazy( + () => import('../pages/SubmitAssessmentPage/SubmitAssessmentPage'), +) +const LandingPage = lazy(() => import('../pages/LandingPage/LandingPage')) + +const AppRoutes = () => { + return ( + + + + } + > + + + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + } /> + } /> + } /> + + + + ) +} + +export default AppRoutes diff --git a/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.module.scss b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.module.scss new file mode 100644 index 00000000..76e43a0c --- /dev/null +++ b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.module.scss @@ -0,0 +1,31 @@ +.link { + display: flex; + align-items: center; + text-decoration: none; + font-size: var(--mantine-font-size-sm); + color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-1)); + padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm); + border-radius: var(--mantine-radius-sm); + font-weight: 500; + margin-bottom: 5px; + + &[data-active], &:hover { + background-color: var(--mantine-color-blue-light); + color: var(--mantine-color-blue-light-color); + + .linkIcon { + color: var(--mantine-color-blue-light-color); + } + } +} + +.linkIcon { + color: light-dark(var(--mantine-color-gray-6), var(--mantine-color-dark-2)); + margin-right: var(--mantine-spacing-sm); + width: 25px; + height: 25px; +} + +.fullHeight { + height: 100vh; +} diff --git a/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx new file mode 100644 index 00000000..857e4261 --- /dev/null +++ b/client/src/app/layout/AuthenticatedArea/AuthenticatedArea.tsx @@ -0,0 +1,162 @@ +import { PropsWithChildren, Suspense, useEffect } from 'react' +import { AppShell, Burger, Center, Group, Loader } from '@mantine/core' +import * as styles from './AuthenticatedArea.module.scss' +import { Link, useLocation } from 'react-router-dom' +import { useDisclosure } from '@mantine/hooks' +import { + FolderSimplePlus, + Kanban, + NewspaperClipping, + PaperPlaneTilt, + Scroll, + SignOut, + User, +} from 'phosphor-react' +import { useIsSmallerBreakpoint } from '../../../hooks/theme' +import { useAuthenticationContext } from '../../../hooks/authentication' + +export interface IAuthenticatedAreaProps { + requireAuthentication?: boolean + collapseNavigation?: boolean + requiredRoles?: string[] +} + +const links: Array<{ + link: string + label: string + icon: any + roles: string[] | undefined +}> = [ + { link: '/dashboard', label: 'Dashboard', icon: NewspaperClipping, roles: undefined }, + { + link: '/submit-application/pick-topic', + label: 'Submit Application', + icon: PaperPlaneTilt, + roles: undefined, + }, + { + link: '/management/thesis-applications', + label: 'Review Applications v1', + icon: Scroll, + roles: ['admin', 'advisor'], + }, + { + link: '/applications', + label: 'Review Applications v2', + icon: Scroll, + roles: ['admin', 'advisor'], + }, + { + link: '/topics/create', + label: 'Create Topic', + icon: FolderSimplePlus, + roles: ['admin', 'advisor'], + }, + { link: '/theses', label: 'Thesis Overview', icon: Kanban, roles: ['admin'] }, +] + +const SpinningLoader = () => ( +
+ +
+) + +const AuthenticatedArea = (props: PropsWithChildren) => { + const { + children, + requireAuthentication = true, + collapseNavigation = false, + requiredRoles, + } = props + + const [opened, { toggle }] = useDisclosure() + const location = useLocation() + const showHeader = useIsSmallerBreakpoint('md') || collapseNavigation + const auth = useAuthenticationContext() + + useEffect(() => { + if (requireAuthentication && !auth.isAuthenticated) { + auth.login() + } + }, [requireAuthentication, auth.isAuthenticated]) + + if (!requireAuthentication && !auth.isAuthenticated) { + return <>{children} + } + + return ( + + + + + + + + + + {links + .filter( + (item) => !item.roles || item.roles.some((role) => auth.user?.roles.includes(role)), + ) + .map((item) => ( + + + {item.label} + + ))} + + + + + My Information + + + + + Logout + + + + + + {auth.user ? ( + }> + {!requiredRoles || requiredRoles.some((role) => auth.user?.roles.includes(role)) ? ( + children + ) : ( +
+

403 - Unauthorized

+
+ )} +
+ ) : ( + + )} +
+
+ ) +} + +export default AuthenticatedArea diff --git a/client/src/app/layout/ContentContainer/ContentContainer.module.scss b/client/src/app/layout/ContentContainer/ContentContainer.module.scss new file mode 100644 index 00000000..1d61ecbf --- /dev/null +++ b/client/src/app/layout/ContentContainer/ContentContainer.module.scss @@ -0,0 +1,4 @@ +.contentContainer { + background-color: var(--mantine-color-body); + border-radius: 5px; +} \ No newline at end of file diff --git a/client/src/app/layout/ContentContainer/ContentContainer.tsx b/client/src/app/layout/ContentContainer/ContentContainer.tsx new file mode 100644 index 00000000..1ba0cc50 --- /dev/null +++ b/client/src/app/layout/ContentContainer/ContentContainer.tsx @@ -0,0 +1,14 @@ +import { PropsWithChildren } from 'react' +import { Container } from '@mantine/core' + +import * as styles from './ContentContainer.module.scss' + +interface IContentContainerProps {} + +const ContentContainer = (props: PropsWithChildren) => { + const { children } = props + + return {children} +} + +export default ContentContainer diff --git a/client/src/app/styles.scss b/client/src/app/styles.scss new file mode 100644 index 00000000..e69de29b diff --git a/client/src/components/AssignRolesModal/AssignRolesModal.tsx b/client/src/components/AssignRolesModal/AssignRolesModal.tsx new file mode 100644 index 00000000..c00f16b1 --- /dev/null +++ b/client/src/components/AssignRolesModal/AssignRolesModal.tsx @@ -0,0 +1,6 @@ +const AssignRolesModal = () => { + // TODO: implement component + return <> +} + +export default AssignRolesModal diff --git a/client/src/components/AuthenticatedIframe/AuthenticatedIframe.tsx b/client/src/components/AuthenticatedIframe/AuthenticatedIframe.tsx new file mode 100644 index 00000000..cb4dae43 --- /dev/null +++ b/client/src/components/AuthenticatedIframe/AuthenticatedIframe.tsx @@ -0,0 +1,6 @@ +const AuthenticatedIframe = () => { + // TODO: implement component + return <> +} + +export default AuthenticatedIframe diff --git a/client/src/student/form/DeclarationOfDataConsent.tsx b/client/src/components/DeclarationOfDataConsent/DeclarationOfDataConsent.tsx similarity index 96% rename from client/src/student/form/DeclarationOfDataConsent.tsx rename to client/src/components/DeclarationOfDataConsent/DeclarationOfDataConsent.tsx index 8dfdfaea..b2570486 100644 --- a/client/src/student/form/DeclarationOfDataConsent.tsx +++ b/client/src/components/DeclarationOfDataConsent/DeclarationOfDataConsent.tsx @@ -1,6 +1,6 @@ import { Paper, Text } from '@mantine/core' -export const DeclarationOfDataConsent = (): JSX.Element => { +export const DeclarationOfDataConsent = () => { return ( diff --git a/client/src/components/ThesisPreviewModal/ThesisPreviewModal.tsx b/client/src/components/ThesisPreviewModal/ThesisPreviewModal.tsx new file mode 100644 index 00000000..de0d7c1e --- /dev/null +++ b/client/src/components/ThesisPreviewModal/ThesisPreviewModal.tsx @@ -0,0 +1,6 @@ +const ThesisPreviewModal = () => { + // TODO: implement component + return <> +} + +export default ThesisPreviewModal diff --git a/client/src/components/UploadFileModal/UploadFileModal.tsx b/client/src/components/UploadFileModal/UploadFileModal.tsx new file mode 100644 index 00000000..ec0160cd --- /dev/null +++ b/client/src/components/UploadFileModal/UploadFileModal.tsx @@ -0,0 +1,6 @@ +const UploadFileModal = () => { + // TODO: implement component + return <> +} + +export default UploadFileModal diff --git a/client/src/components/UserMultiSelect/UserMultiSelect.tsx b/client/src/components/UserMultiSelect/UserMultiSelect.tsx new file mode 100644 index 00000000..7b7083a3 --- /dev/null +++ b/client/src/components/UserMultiSelect/UserMultiSelect.tsx @@ -0,0 +1,6 @@ +const UserMultiSelect = () => { + // TODO: implement component + return <> +} + +export default UserMultiSelect diff --git a/client/src/config/global.ts b/client/src/config/global.ts new file mode 100644 index 00000000..dcade7af --- /dev/null +++ b/client/src/config/global.ts @@ -0,0 +1,93 @@ +import { IGlobalConfig } from './types' + +const getEnvironmentVariable = (key: string, useJson = false): T | undefined => { + const value = process.env[key] || window.RUNTIME_ENVIRONMENT_VARIABLES?.[key]; + + if (!value) { + return undefined + } + + try { + return useJson ? JSON.parse(value) as T : value as T + } catch { + return undefined + } +} + +export const GLOBAL_CONFIG: IGlobalConfig = { + title: getEnvironmentVariable('APPLICATION_TITLE') || 'Thesis Track', + + focus_topics: getEnvironmentVariable>('FOCUS_TOPICS', true) || { + COMPETENCIES: 'Competencies', + TEAM_BASED_LEARNING: 'Team-based Learning', + AUTOMATIC_ASSESSMENT: 'Automatic Assessment', + LEARNING_PLATFORMS: 'Learning Platforms', + MACHINE_LEARNING: 'Machine Learning', + DEI: 'Diversity, Equity & Inclusion', + LEARNING_ANALYTICS: 'Learning Analytics', + ADAPTIVE_LEARNING: 'Adaptive Learning', + K12_SCHOOLS: 'K12 / Schools', + SECURITY: 'Security', + INFRASTRUCTURE: 'Infrastructure', + AGILE_DEVELOPMENT: 'Agile Development', + MOBILE_DEVELOPMENT: 'Mobile Development', + CONTINUOUS: 'Continuous *', + MODELING: 'Modeling', + INNOVATION: 'Innovation', + PROJECT_COURSES: 'Project Courses', + DISTRIBUTED_SYSTEMS: 'Distributed Systems', + DEPLOYMENT: 'Deployment', + DEV_OPS: 'DevOps', + INTERACTION_DESIGN: 'Interaction Design', + USER_INVOLVEMENT: 'User Involvement', + USER_EXPERIENCE: 'User Experience', + CREATIVITY: 'Creativity', + USER_MODEL: 'User Model', + INTERACTIVE_TECHNOLOGY: 'Interactive Technology', + MOCK_UPS: 'Mock-ups', + PROTOTYPING: 'Prototyping', + EMBEDDED_SYSTEMS: 'Embedded Systems', + DUCKIETOWN: 'Duckietown', + AUTONOMOUS_DRIVING: 'Autonomous Driving', + COMMUNICATION: 'Communication', + DISTRIBUTED_CONTROL: 'Distributed Control', + LEARNING_AUTONOMY: 'Learning Autonomy', + HW_SW_CO_DESIGN: 'HW/SW Co-Design', + }, + + research_areas: getEnvironmentVariable>('RESEARCH_AREAS', true) || { + EDUCATION_TECHNOLOGIES: 'Education Technologies', + HUMAN_COMPUTER_INTERACTION: 'Human Computer Interaction', + ROBOTIC: 'Robotic', + SOFTWARE_ENGINEERING: 'Software Engineering', + }, + + genders: getEnvironmentVariable>('GENDERS', true) || { + MALE: 'Male', + FEMALE: 'Female', + OTHER: 'Other', + PREFER_NOT_TO_SAY: 'Prefer not to say', + }, + + study_degrees: getEnvironmentVariable>('STUDY_DEGREES', true) || { + BACHELOR: 'Bachelor', + MASTER: 'Master', + }, + + study_programs: getEnvironmentVariable>('STUDY_PROGRAMS', true) || { + COMPUTER_SCIENCE: 'Computer Science', + INFORMATION_SYSTEMS: 'Information Systems', + GAMES_ENGINEERING: 'Games Engineering', + MANAGEMENT_AND_TECHNOLOGY: 'Management and Technology', + OTHER: 'Other', + }, + + api_server: getEnvironmentVariable('API_SERVER_HOST') || 'http://localhost:8080', + + keycloak: { + host: getEnvironmentVariable('KEYCLOAK_HOST') || 'http://localhost:8081', + realm: getEnvironmentVariable('KEYCLOAK_REALM_NAME') || 'thesis-track', + client_id: getEnvironmentVariable('KEYCLOAK_CLIENT_ID') || 'thesis-track-app', + university_id_jwt_field: getEnvironmentVariable('UNIVERSITY_ID_JWT_FIELD') || 'preferred_username', + }, +} diff --git a/client/src/config/types.ts b/client/src/config/types.ts new file mode 100644 index 00000000..8a4547f4 --- /dev/null +++ b/client/src/config/types.ts @@ -0,0 +1,20 @@ +import { IDecodedAccessToken } from '../contexts/AuthenticationContext/context' + +export interface IGlobalConfig { + title: string + + api_server: string + + focus_topics: Record + research_areas: Record + genders: Record + study_programs: Record + study_degrees: Record + + keycloak: { + client_id: string + realm: string + host: string + university_id_jwt_field: string + } +} diff --git a/client/src/contexts/AuthenticationContext/AuthenticationProvider.tsx b/client/src/contexts/AuthenticationContext/AuthenticationProvider.tsx new file mode 100644 index 00000000..c5cf0976 --- /dev/null +++ b/client/src/contexts/AuthenticationContext/AuthenticationProvider.tsx @@ -0,0 +1,180 @@ +import React, { PropsWithChildren, useEffect, useMemo, useState } from 'react' +import { + AuthenticationContext, + IAuthenticationContext, + IDecodedAccessToken, + IDecodedRefreshToken, +} from './context' +import Keycloak from 'keycloak-js' +import { GLOBAL_CONFIG } from '../../config/global' +import { jwtDecode } from 'jwt-decode' +import { IUserInfo } from '../../requests/types/user' +import { getAuthenticationTokens, useAuthenticationTokens } from '../../hooks/authentication' +import { useSignal } from '../../hooks/utility' + +interface IAuthenticationProviderProps {} + +const keycloak = new Keycloak({ + realm: GLOBAL_CONFIG.keycloak.realm, + url: GLOBAL_CONFIG.keycloak.host, + clientId: GLOBAL_CONFIG.keycloak.client_id, +}) + +const AuthenticationProvider = (props: PropsWithChildren) => { + const { children } = props + + const [user, setUser] = useState() + const [authenticationTokens, setAuthenticationTokens] = useAuthenticationTokens() + const { + signal: readySignal, + triggerSignal: triggerReadySignal, + ref: { isTriggerred: isReady }, + } = useSignal() + + useEffect(() => { + setUser(undefined) + + const refreshAccessToken = () => { + keycloak + .updateToken(60 * 5) + .then((isSuccess) => { + if (!isSuccess) { + setAuthenticationTokens(undefined) + } + }) + } + + const storeTokens = () => { + const refreshToken = keycloak.refreshToken + const accessToken = keycloak.token + + const decodedAccessToken = accessToken + ? jwtDecode(accessToken) + : undefined + const decodedRefreshToken = refreshToken + ? jwtDecode(refreshToken) + : undefined + + console.log('decoded keycloak refresh token', decodedRefreshToken) + console.log('decoded keycloak access token', decodedAccessToken) + + if (decodedRefreshToken?.exp) { + console.log(`refresh token expires in ${Math.floor(decodedRefreshToken.exp - Date.now() / 1000)} seconds`) + } + + // refresh if already expired + if (decodedRefreshToken?.exp && decodedRefreshToken.exp <= Date.now() / 1000) { + return setAuthenticationTokens(undefined) + } else if (decodedAccessToken?.exp && decodedAccessToken.exp <= Date.now() / 1000) { + return refreshAccessToken() + } + + if (accessToken && refreshToken) { + setAuthenticationTokens({ + access_token: accessToken, + refresh_token: refreshToken, + }) + } else { + setAuthenticationTokens(undefined) + } + } + + const storedTokens = getAuthenticationTokens() + + keycloak.onTokenExpired = () => refreshAccessToken() + keycloak.onAuthRefreshSuccess = () => storeTokens() + + console.log('Initializing keycloak...') + + void keycloak + .init({ + refreshToken: storedTokens?.refresh_token, + token: storedTokens?.access_token, + }) + .then(() => { + console.log('Keycloak initialized') + + storeTokens() + triggerReadySignal() + }) + .catch((error) => { + console.log('Keycloak init error', error) + }) + + const refreshTokenFrequency = 60 * 1000; + const refreshTokenInterval = setInterval(() => { + const refreshToken = keycloak.refreshToken + const accessToken = keycloak.token + + const decodedAccessToken = accessToken + ? jwtDecode(accessToken) + : undefined + const decodedRefreshToken = refreshToken + ? jwtDecode(refreshToken) + : undefined + + if (decodedRefreshToken?.exp && decodedRefreshToken.exp <= Date.now() / 1000) { + keycloak.clearToken() + + return setAuthenticationTokens(undefined) + } else if (decodedAccessToken?.exp && decodedAccessToken.exp <= Date.now() / 1000 + refreshTokenFrequency) { + return refreshAccessToken() + } + }, refreshTokenFrequency) + + return () => { + clearInterval(refreshTokenInterval) + + keycloak.onAuthRefreshSuccess = undefined + keycloak.onTokenExpired = undefined + } + }, []) + + useEffect(() => { + if (!isReady) { + return + } + + if (authenticationTokens?.access_token) { + const decodedAccessToken = jwtDecode(authenticationTokens.access_token) + + setUser({ + first_name: decodedAccessToken.given_name, + last_name: decodedAccessToken.family_name, + email: decodedAccessToken.email, + university_id: decodedAccessToken[GLOBAL_CONFIG.keycloak.university_id_jwt_field] || '', + user_id: decodedAccessToken[GLOBAL_CONFIG.keycloak.university_id_jwt_field] || '', + roles: decodedAccessToken.resource_access[GLOBAL_CONFIG.keycloak.client_id]?.roles ?? [], + }) + } else { + setUser(undefined) + } + }, [authenticationTokens?.access_token, isReady]) + + const contextValue = useMemo(() => { + return { + isAuthenticated: !!authenticationTokens?.access_token, + user: authenticationTokens?.access_token ? user : undefined, + groups: [], + login: () => + readySignal.then(() => { + !keycloak.authenticated && keycloak.login() + }), + logout: (redirectUri: string) => + readySignal.then(() => { + setAuthenticationTokens(undefined) + + keycloak.authenticated && + keycloak.logout({ + redirectUri: `${location.origin}${redirectUri}`, + }) + }), + } + }, [user, !!authenticationTokens?.access_token, location.origin]) + + return ( + {children} + ) +} + +export default AuthenticationProvider diff --git a/client/src/contexts/AuthenticationContext/context.ts b/client/src/contexts/AuthenticationContext/context.ts new file mode 100644 index 00000000..c31cd054 --- /dev/null +++ b/client/src/contexts/AuthenticationContext/context.ts @@ -0,0 +1,24 @@ +import { createContext } from 'react' +import { IUserInfo } from '../../requests/types/user' +import { JwtPayload } from 'jwt-decode' + +export interface IAuthenticationContext { + isAuthenticated: boolean + user: IUserInfo | undefined + groups: string[] + login: () => unknown + logout: (redirectUrl: string) => unknown +} + +export const AuthenticationContext = createContext(undefined) + +export interface IDecodedAccessToken extends JwtPayload { + given_name: string + family_name: string + email: string + preferred_username: string + resource_access: Partial> + [key: string]: any +} + +export interface IDecodedRefreshToken extends JwtPayload {} diff --git a/client/src/global.d.ts b/client/src/global.d.ts new file mode 100644 index 00000000..d9686a06 --- /dev/null +++ b/client/src/global.d.ts @@ -0,0 +1,7 @@ +interface Window { + RUNTIME_ENVIRONMENT_VARIABLES: Record | undefined; +} + +interface WindowEventMap { + 'local-storage': StorageEvent +} diff --git a/client/src/hooks/authentication.ts b/client/src/hooks/authentication.ts new file mode 100644 index 00000000..987884e9 --- /dev/null +++ b/client/src/hooks/authentication.ts @@ -0,0 +1,55 @@ +import { useContext } from 'react' +import { AuthenticationContext } from '../contexts/AuthenticationContext/context' +import { useLocalStorage } from './local-storage' + +export function useAuthenticationContext() { + const context = useContext(AuthenticationContext) + + if (!context) { + throw new Error('Authentication context not initialized') + } + + return context +} + +export function useUser() { + const context = useAuthenticationContext() + + return context.user +} + +export function useLoggedInUser() { + const user = useUser() + const auth = useAuthenticationContext() + + if (!user) { + auth.login() + + throw new Error('Authentication required') + } + + return user +} + +export interface IAuthenticationTokens { + access_token: string + refresh_token: string +} + +export function useAuthenticationTokens() { + return useLocalStorage('authentication_tokens', { usingJson: true }) +} + +export function getAuthenticationTokens(): IAuthenticationTokens | undefined { + try { + const data = localStorage.getItem('authentication_tokens') + + if (data) { + return JSON.parse(data) + } + + return undefined + } catch { + return undefined + } +} diff --git a/client/src/hooks/local-storage.ts b/client/src/hooks/local-storage.ts new file mode 100644 index 00000000..11b77582 --- /dev/null +++ b/client/src/hooks/local-storage.ts @@ -0,0 +1,74 @@ +import { Dispatch, useCallback, useEffect, useMemo, useState } from 'react' + +interface ILocalStorageOptions { + usingJson: boolean + usingSession: boolean +} + +export type LocalStorageStateAction = T | ((prevState: T) => T) + +export function useLocalStorage( + key: string, + options: Partial = {}, +): [T | undefined, Dispatch>] { + const { usingJson, usingSession }: ILocalStorageOptions = { + usingJson: false, + usingSession: false, + ...options, + } + + const [version, setVersion] = useState(0) + + const storage = usingSession ? sessionStorage : localStorage + + useEffect(() => { + const changeListener = (event: StorageEvent) => { + if (event.key === key) { + setVersion((prev) => prev + 1) + } + } + + window.addEventListener('storage', changeListener) + window.addEventListener('local-storage', changeListener) + + return () => { + window.removeEventListener('storage', changeListener) + window.removeEventListener('local-storage', changeListener) + } + }, [key]) + + const storedValue = useMemo(() => { + const data = storage.getItem(key) + + if (data !== null) { + if (usingJson) { + try { + return JSON.parse(data) + } catch { + return undefined + } + } + + return data + } + + return undefined + }, [key, version, usingJson, storage]) + + const setStoredValue = useCallback( + (val: LocalStorageStateAction) => { + const newValue = val instanceof Function ? val(storedValue) : val + + if (typeof newValue === 'undefined') { + storage.removeItem(key) + } else { + storage.setItem(key, usingJson ? JSON.stringify(newValue) : String(newValue)) + } + + window.dispatchEvent(new StorageEvent('local-storage', { key })) + }, + [key, storedValue, usingJson, storage], + ) + + return [storedValue, setStoredValue] +} diff --git a/client/src/hooks/theme.ts b/client/src/hooks/theme.ts new file mode 100644 index 00000000..654e943c --- /dev/null +++ b/client/src/hooks/theme.ts @@ -0,0 +1,19 @@ +import { useDocumentTitle, useMediaQuery } from '@mantine/hooks' +import { useMantineTheme } from '@mantine/core' +import { GLOBAL_CONFIG } from '../config/global' + +export function useIsSmallerBreakpoint(breakpoint: string) { + const theme = useMantineTheme() + + return useMediaQuery(`(max-width: ${theme.breakpoints[breakpoint]})`) || false +} + +export function useIsBiggerThanBreakpoint(breakpoint: string) { + const theme = useMantineTheme() + + return useMediaQuery(`(min-width: ${theme.breakpoints[breakpoint]})`) +} + +export function usePageTitle(title: string) { + useDocumentTitle(`${title} - ${GLOBAL_CONFIG.title}`) +} diff --git a/client/src/hooks/utility.ts b/client/src/hooks/utility.ts new file mode 100644 index 00000000..8a2756d1 --- /dev/null +++ b/client/src/hooks/utility.ts @@ -0,0 +1,51 @@ +import { useMemo, useState } from 'react' + +interface IUseSignalReturnType { + signal: Promise + ref: { isTriggerred: boolean } + triggerSignal: () => unknown +} + +export function useSignal(): IUseSignalReturnType { + const [, setVersion] = useState(0) + + return useMemo(() => { + let externalResolve: (x: boolean) => unknown + const ref: { isTriggerred: boolean } = { isTriggerred: false } + + const signal = new Promise((resolve) => { + externalResolve = resolve + + return true + }) + + return { + signal, + ref, + triggerSignal: () => { + externalResolve(true) + ref.isTriggerred = true + + setVersion((prev) => prev + 1) + }, + } + }, []) +} + +export function usePromiseLoader( + fn: (...args: T) => Promise, +): { + execute: (...args: T) => unknown + isLoading: boolean +} { + const [loading, setLoading] = useState(false) + + return { + isLoading: loading, + execute: (...args: T) => { + setLoading(true) + + void fn(...args).finally(() => setLoading(false)) + }, + } +} diff --git a/client/public/template.html b/client/src/index.html similarity index 88% rename from client/public/template.html rename to client/src/index.html index 8c222d8c..1ab38cd0 100644 --- a/client/public/template.html +++ b/client/src/index.html @@ -6,9 +6,9 @@ ThesisTrack +
- diff --git a/client/src/index.tsx b/client/src/index.tsx index 35d20d50..e9cf01f9 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -1,5 +1,5 @@ import { createRoot } from 'react-dom/client' -import { App } from './App' +import App from './app/App' const rootElement = document.getElementById('root') diff --git a/client/src/interface/application.ts b/client/src/interface/application.ts deleted file mode 100644 index 55c15920..00000000 --- a/client/src/interface/application.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum ApplicationStatus { - NOT_ASSESSED = 'Not assessed', - ACCEPTED = 'Accepted', - REJECTED = 'Rejected', -} diff --git a/client/src/interface/authentication.ts b/client/src/interface/authentication.ts deleted file mode 100644 index 099b48a2..00000000 --- a/client/src/interface/authentication.ts +++ /dev/null @@ -1,11 +0,0 @@ -export enum Permission { - CHAIR_MEMBER = 'chair-member', -} - -export interface User { - firstName: string - lastName: string - email: string - username: string - mgmtAccess: boolean -} diff --git a/client/src/interface/student.ts b/client/src/interface/student.ts deleted file mode 100644 index 416ede8b..00000000 --- a/client/src/interface/student.ts +++ /dev/null @@ -1,53 +0,0 @@ -export enum LanguageProficiency { - A1A2 = 'A1/A2', - B1B2 = 'B1/B2', - C1C2 = 'C1/C2', - NATIVE = 'Native', -} - -export enum StudyDegree { - BACHELOR = 'Bachelor', - MASTER = 'Master', -} - -export enum StudyProgram { - COMPUTER_SCIENCE = 'Computer Science', - INFORMATION_SYSTEMS = 'Information Systems', - GAMES_ENGINEERING = 'Games Engineering', - MANAGEMENT_AND_TECHNOLOGY = 'Management and Technology', - OTHER = 'Other', -} - -export enum Gender { - MALE = 'Male', - FEMALE = 'Female', - OTHER = 'Other', - PREFER_NOT_TO_SAY = 'Prefer not to say', -} - -export interface DevelopmentProfile { - id: string - gitlabUsername: string - appleId: string - macBookDeviceId?: string - iPhoneDeviceId?: string - iPadDeviceId?: string - appleWatchDeviceId?: string -} - -export interface Student { - id: string - tumId?: string - matriculationNumber?: string - isExchangeStudent: boolean - firstName?: string - lastName?: string - gender?: keyof typeof Gender - nationality?: string - email?: string - suggestedAsCoach: boolean - suggestedAsTutor: boolean - blockedByPm: boolean - reasonForBlockedByPm: string - developmentProfile?: DevelopmentProfile -} diff --git a/client/src/interface/thesisApplication.ts b/client/src/interface/thesisApplication.ts deleted file mode 100644 index bf91c16e..00000000 --- a/client/src/interface/thesisApplication.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Student, StudyDegree, StudyProgram } from '../interface/student' -import { ApplicationStatus } from './application' - -export enum ResearchArea { - EDUCATION_TECHNOLOGIES = 'Education Technologies', - HUMAN_COMPUTER_INTERACTION = 'Human Computer Interaction', - ROBOTIC = 'Robotic', - SOFTWARE_ENGINEERING = 'Software Engineering', -} - -export enum FocusTopic { - COMPETENCIES = 'Competencies', - TEAM_BASED_LEARNING = 'Team-based Learning', - AUTOMATIC_ASSESSMENT = 'Automatic Assessment', - LEARNING_PLATFORMS = 'Learning Platforms', - MACHINE_LEARNING = 'Machine Learning', - DEI = 'Diversity, Equity & Inclusion', - LEARNING_ANALYTICS = 'Learning Analytics', - ADAPTIVE_LEARNING = 'Adaptive Learning', - K12_SCHOOLS = 'K12 / Schools', - SECURITY = 'Security', - INFRASTRUCTURE = 'Infrastructure', - AGILE_DEVELOPMENT = 'Agile Development', - MOBILE_DEVELOPMENT = 'Mobile Development', - CONTINUOUS = 'Continuous *', - MODELING = 'Modeling', - INNOVATION = 'Innovation', - PROJECT_COURSES = 'Project Courses', - DISTRIBUTED_SYSTEMS = 'Distributed Systems', - DEPLOYMENT = 'Deployment', - DEV_OPS = 'DevOps', - INTERACTION_DESIGN = 'Interaction Design', - USER_INVOLVEMENT = 'User Involvement', - USER_EXPERIENCE = 'User Experience', - CREATIVITY = 'Creativity', - USER_MODEL = 'User Model', - INTERACTIVE_TECHNOLOGY = 'Interactive Technology', - MOCK_UPS = 'Mock-ups', - PROTOTYPING = 'Prototyping', - EMBEDDED_SYSTEMS = 'Embedded Systems', - DUCKIETOWN = 'Duckietown', - AUTONOMOUS_DRIVING = 'Autonomous Driving', - COMMUNICATION = 'Communication', - DISTRIBUTED_CONTROL = 'Distributed Control', - LEARNING_AUTONOMY = 'Learning Autonomy', - HW_SW_CO_DESIGN = 'HW/SW Co-Design', -} - -export interface ThesisAdvisor { - id?: string - firstName: string - lastName: string - email: string - tumId: string -} - -export interface ThesisApplication { - id: string - student: Student - studyProgram?: StudyProgram - studyDegree?: StudyDegree - currentSemester?: string - start: string - specialSkills: string - researchAreas: ResearchArea[] - focusTopics: FocusTopic[] - motivation: string - interests: string - projects: string - thesisTitle: string - desiredThesisStart: Date - examinationReportFilename?: string - cvFilename?: string - bachelorReportFilename?: string - applicationStatus: keyof typeof ApplicationStatus - assessmentComment?: string - createdAt?: Date - thesisAdvisor?: ThesisAdvisor -} diff --git a/client/src/legacy/interfaces/application.ts b/client/src/legacy/interfaces/application.ts new file mode 100644 index 00000000..4800c1b5 --- /dev/null +++ b/client/src/legacy/interfaces/application.ts @@ -0,0 +1,10 @@ +export enum LegacyApplicationStatus { + NOT_ASSESSED = 'Not assessed', + ACCEPTED = 'Accepted', + REJECTED = 'Rejected', +} + +export enum LegacyApplicationFormAccessMode { + INSTRUCTOR, + STUDENT, +} diff --git a/client/src/legacy/interfaces/student.ts b/client/src/legacy/interfaces/student.ts new file mode 100644 index 00000000..806cef58 --- /dev/null +++ b/client/src/legacy/interfaces/student.ts @@ -0,0 +1,15 @@ +export interface LegacyStudent { + id: string + tumId?: string + matriculationNumber?: string + isExchangeStudent: boolean + firstName?: string + lastName?: string + gender?: string + nationality?: string + email?: string + suggestedAsCoach: boolean + suggestedAsTutor: boolean + blockedByPm: boolean + reasonForBlockedByPm: string +} diff --git a/client/src/legacy/interfaces/thesisApplication.ts b/client/src/legacy/interfaces/thesisApplication.ts new file mode 100644 index 00000000..70890991 --- /dev/null +++ b/client/src/legacy/interfaces/thesisApplication.ts @@ -0,0 +1,34 @@ +import { LegacyStudent } from './student' +import { LegacyApplicationStatus } from './application' + +export interface LegacyThesisAdvisor { + id?: string + firstName: string + lastName: string + email: string + tumId: string +} + +export interface LegacyThesisApplication { + id: string + student: LegacyStudent + studyProgram?: string + studyDegree?: string + currentSemester?: string + start: string + specialSkills: string + researchAreas: string[] + focusTopics: string[] + motivation: string + interests: string + projects: string + thesisTitle: string + desiredThesisStart: Date + examinationReportFilename?: string + cvFilename?: string + bachelorReportFilename?: string + applicationStatus: keyof typeof LegacyApplicationStatus + assessmentComment?: string + createdAt?: Date + thesisAdvisor?: LegacyThesisAdvisor +} diff --git a/client/src/legacy/network/thesisApplication.ts b/client/src/legacy/network/thesisApplication.ts new file mode 100644 index 00000000..966b6249 --- /dev/null +++ b/client/src/legacy/network/thesisApplication.ts @@ -0,0 +1,240 @@ +import { notifications } from '@mantine/notifications' +import { LegacyThesisApplication } from '../interfaces/thesisApplication' +import { LegacyApplicationStatus } from '../interfaces/application' +import { doRequest } from '../../requests/request' + +export const postThesisApplicationAssessment = async ( + thesisApplicationId: string, + assessment: { status: keyof typeof LegacyApplicationStatus; assessmentComment: string }, +): Promise => { + try { + const response = await doRequest( + `/api/thesis-applications/${thesisApplicationId}/assessment`, + { + method: 'POST', + requiresAuth: true, + data: { ...assessment }, + }, + ) + + if (response.ok) { + return response.data + } + } catch (err) { + console.error(err) + } + + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not assess thesis application.`, + }) + + return undefined +} + +export const postThesisApplicatioAcceptance = async ( + thesisApplicationId: string, + notifyStudent: boolean, +): Promise => { + try { + const response = await doRequest( + `/api/thesis-applications/${thesisApplicationId}/accept`, + { + method: 'POST', + requiresAuth: true, + params: { + notifyStudent, + }, + }, + ) + + if (response.ok) { + notifications.show({ + color: 'green', + autoClose: 5000, + title: 'Success', + message: notifyStudent + ? `Sent an acceptance mail successfully.` + : 'Application status updated successfully', + }) + + return response.data + } + } catch (err) { + console.error(err) + } + + notifications.show({ + color: 'red', + autoClose: 5000, + title: 'Error', + message: notifyStudent + ? `Failed to send an acceptance mail.` + : 'Failed to update application status', + }) + + return undefined +} + +export const postThesisApplicationRejection = async ( + thesisApplicationId: string, + notifyStudent: boolean, +): Promise => { + try { + const response = await doRequest( + `/api/thesis-applications/${thesisApplicationId}/reject`, + { + method: 'POST', + requiresAuth: true, + params: { + notifyStudent, + }, + }, + ) + + if (response.ok) { + notifications.show({ + color: 'green', + autoClose: 5000, + title: 'Success', + message: notifyStudent + ? `Sent a rejection mail successfully.` + : 'Application status updated successfully', + }) + + return response.data + } + } catch (err) { + console.error(err) + } + + notifications.show({ + color: 'red', + autoClose: 5000, + title: 'Error', + message: notifyStudent + ? `Failed to send a rejection mail.` + : 'Failed to update application status', + }) + + return undefined +} + +export const postThesisApplicationThesisAdvisorAssignment = async ( + thesisApplicationId: string, + thesisAdvisorId: string, +): Promise => { + try { + const response = await doRequest( + `/api/thesis-applications/${thesisApplicationId}/thesis-advisor/${thesisAdvisorId}`, + { + method: 'POST', + requiresAuth: true, + }, + ) + + if (response.ok) { + return response.data + } + } catch (err) { + console.warn(err) + } + + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not assign thesis advisor to thesis application.`, + }) + + return undefined +} + +export const getThesisApplicationExaminationFile = async ( + thesisApplicationId: string, +): Promise => { + try { + const response = await doRequest( + `/api/thesis-applications/${thesisApplicationId}/examination-report`, + { + method: 'GET', + requiresAuth: true, + responseType: 'blob', + }, + ) + + if (response.ok) { + return new Blob([response.data], { type: 'application/pdf' }) + } + } catch (err) { + console.log(err) + } + + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not load examination file.`, + }) + + return undefined +} + +export const getThesisApplicationCvFile = async ( + thesisApplicationId: string, +): Promise => { + try { + const response = await doRequest(`/api/thesis-applications/${thesisApplicationId}/cv`, { + method: 'GET', + requiresAuth: true, + responseType: 'blob', + }) + + if (response.ok) { + return new Blob([response.data], { type: 'application/pdf' }) + } + } catch (err) { + console.error(err) + } + + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not load cv file.`, + }) + + return undefined +} + +export const getThesisApplicationBachelorReportFile = async ( + thesisApplicationId: string, +): Promise => { + try { + const response = await doRequest( + `/api/thesis-applications/${thesisApplicationId}/bachelor-report`, + { + method: 'GET', + requiresAuth: true, + responseType: 'blob', + }, + ) + + if (response.ok) { + return new Blob([response.data], { type: 'application/pdf' }) + } + } catch (err) { + console.error(err) + } + + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not load bachelor report file.`, + }) + + return undefined +} diff --git a/client/src/management/ManagementConsole.tsx b/client/src/management/ManagementConsole.tsx deleted file mode 100644 index 1e0f4005..00000000 --- a/client/src/management/ManagementConsole.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import Keycloak from 'keycloak-js' -import { axiosInstance, keycloakRealmName, keycloakUrl } from '../network/configService' -import { useEffect, useState } from 'react' -import { jwtDecode } from 'jwt-decode' -import { ThesisApplicationsDatatable } from './components/ThesisApplicationsDatatable' -import { Affix, Button, Center, Transition, rem } from '@mantine/core' -import { IconArrowUp } from '@tabler/icons-react' -import { useWindowScroll } from '@mantine/hooks' -import { useMutation, useQueryClient } from '@tanstack/react-query' -import { putThesisAdvisor } from '../network/thesisApplication' -import { ThesisAdvisor } from '../interface/thesisApplication' -import { Query } from '../state/query' -import { useAuthenticationStore } from '../state/zustand/useAuthenticationStore' - -export const ManagementConsole = (): JSX.Element => { - const queryClient = useQueryClient() - const [scroll, scrollTo] = useWindowScroll() - const [authenticated, setAuthenticated] = useState(false) - const { user, setUser } = useAuthenticationStore() - - const addThesisAdvisor = useMutation({ - mutationFn: (thesisAdvisor: ThesisAdvisor) => putThesisAdvisor(thesisAdvisor), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: [Query.THESIS_APPLICATION] }) - }, - }) - - // eslint-disable-next-line react-hooks/exhaustive-deps - const keycloak = new Keycloak({ - realm: keycloakRealmName, - url: keycloakUrl, - clientId: 'thesis-track-client', - }) - const [keycloakValue, setKeycloakValue] = useState(keycloak) - - useEffect(() => { - if (keycloakValue) { - axiosInstance.interceptors.request.use( - async (config) => { - if (keycloakValue.isTokenExpired(43200)) { - await keycloakValue?.updateToken(60) - } - return config - }, - (error) => { - Promise.reject(error) - }, - ) - } - }, [keycloakValue]) - - useEffect(() => { - void keycloak - .init({ onLoad: 'login-required' }) - .then((isAuthenticated) => { - if (isAuthenticated) { - setAuthenticated(true) - } else { - setAuthenticated(false) - void keycloak.login() - } - localStorage.setItem('jwt_token', keycloak.token ?? '') - localStorage.setItem('refreshToken', keycloak.refreshToken ?? '') - try { - if (keycloak.token) { - const decodedJwt = jwtDecode<{ - given_name: string - family_name: string - email: string - preferred_username: string - }>(keycloak.token) - setUser({ - firstName: decodedJwt.given_name, - lastName: decodedJwt.family_name, - email: decodedJwt.email, - username: decodedJwt.preferred_username, - mgmtAccess: - keycloak.hasResourceRole('chair-member', 'thesis-track-server') || - keycloak.hasResourceRole('thesis-track-admin', 'thesis-track-server'), - }) - - if (keycloak.hasResourceRole('chair-member', 'thesis-track-server')) { - addThesisAdvisor.mutate({ - firstName: decodedJwt.given_name, - lastName: decodedJwt.family_name, - email: decodedJwt.email, - tumId: decodedJwt.preferred_username, - }) - } - } - } catch (error) { - setUser({ - firstName: '', - lastName: '', - email: '', - username: '', - mgmtAccess: false, - }) - } - setKeycloakValue(keycloak) - }) - .catch((err) => { - alert(err) - }) - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) - - return ( -
- {authenticated && user && user.mgmtAccess && ( -
- - - 0}> - {(transitionStyles) => ( - - )} - - -
- )} -
- ) -} diff --git a/client/src/network/configService.ts b/client/src/network/configService.ts deleted file mode 100644 index b1cd05e6..00000000 --- a/client/src/network/configService.ts +++ /dev/null @@ -1,32 +0,0 @@ -import axios from 'axios' - -export const serverBaseUrl = `${process.env.REACT_APP_SERVER_HOST ?? 'http://localhost:8080'}` -export const keycloakUrl = `${process.env.REACT_APP_KEYCLOAK_HOST ?? 'http://localhost:8081'}` -export const keycloakRealmName = `${process.env.REACT_APP_KEYCLOAK_REALM_NAME ?? 'thesis-track'}` - -export interface Patch { - op: 'replace' | 'add' | 'remove' | 'copy' - path: string - value: string -} - -const authenticatedAxiosInstance = axios.create({ - baseURL: serverBaseUrl, -}) - -authenticatedAxiosInstance.interceptors.request.use((config) => { - if (!!localStorage.getItem('jwt_token') && localStorage.getItem('jwt_token') !== '') { - config.headers['Authorization'] = `Bearer ${localStorage.getItem('jwt_token') ?? ''}` - } - return config -}) - -const notAuthenticatedAxiosInstance = axios.create({ - baseURL: serverBaseUrl, -}) - -notAuthenticatedAxiosInstance.interceptors.request.use((config) => { - return config -}) - -export { authenticatedAxiosInstance as axiosInstance, notAuthenticatedAxiosInstance } diff --git a/client/src/network/thesisApplication.ts b/client/src/network/thesisApplication.ts deleted file mode 100644 index 53061bc0..00000000 --- a/client/src/network/thesisApplication.ts +++ /dev/null @@ -1,334 +0,0 @@ -import { notifications } from '@mantine/notifications' -import { axiosInstance, notAuthenticatedAxiosInstance } from './configService' -import { ThesisAdvisor, ThesisApplication } from '../interface/thesisApplication' -import { AxiosError } from 'axios' -import { ApplicationStatus } from '../interface/application' -import { Pageable } from '../interface/pageable' - -export const getThesisApplications = async ( - page: number, - limit: number, - states?: string[], - searchQuery?: string, - sortBy?: string, - sortOrder?: 'asc' | 'desc', -): Promise> => { - try { - return ( - await axiosInstance.get(`/api/thesis-applications`, { - params: { - page, - limit, - states: states?.join(',') ?? Object.keys(ApplicationStatus).join(','), - searchQuery, - sortBy, - sortOrder, - }, - }) - ).data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not fetch thesis applications.`, - }) - return { - content: [], - totalPages: 0, - totalElements: 0, - number: 0, - size: 0, - empty: true, - first: true, - last: true, - numberOfElements: 0, - } - } -} - -export const postThesisApplication = async ({ - application, - examinationReport, - cv, - bachelorReport, -}: { - application: ThesisApplication - examinationReport: File - cv: File - bachelorReport?: File -}): Promise => { - try { - const formData = new FormData() - formData.append( - 'thesisApplication', - new Blob([JSON.stringify(application)], { type: 'application/json' }), - ) - formData.append('examinationReport', examinationReport) - formData.append('cv', cv) - if (bachelorReport) { - formData.append('bachelorReport', bachelorReport) - } - const response = await notAuthenticatedAxiosInstance.post( - `/api/thesis-applications`, - formData, - { - headers: { - 'Content-Type': 'multipart/form-data', - }, - }, - ) - if (response.status >= 200 && response.status < 300) { - notifications.show({ - color: 'green', - autoClose: 5000, - title: 'Success', - message: `Your application was successfully submitted!`, - }) - } - return response.data - } catch (err) { - if ((err as AxiosError)?.response?.status === 400) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `${((err as AxiosError)?.response?.data as string) ?? ''}`, - }) - } else { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Failed to submit the application. Server responded with ${err as string}`, - }) - } - - return undefined - } -} - -export const postThesisApplicationAssessment = async ( - thesisApplicationId: string, - assessment: { status: keyof typeof ApplicationStatus; assessmentComment: string }, -): Promise => { - try { - return ( - await axiosInstance.post(`/api/thesis-applications/${thesisApplicationId}/assessment`, { - ...assessment, - }) - ).data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not assess thesis application.`, - }) - return undefined - } -} - -export const postThesisApplicatioAcceptance = async ( - thesisApplicationId: string, - notifyStudent: boolean, -): Promise => { - try { - const response = await axiosInstance.post( - `/api/thesis-applications/${thesisApplicationId}/accept`, - {}, - { - params: { - notifyStudent, - }, - }, - ) - - if (response) { - notifications.show({ - color: 'green', - autoClose: 5000, - title: 'Success', - message: notifyStudent - ? `Sent an acceptance mail successfully.` - : 'Application status updated successfully', - }) - } - - return response.data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 5000, - title: 'Error', - message: notifyStudent - ? `Failed to send an acceptance mail.` - : 'Failed to update application status', - }) - return undefined - } -} - -export const postThesisApplicationRejection = async ( - thesisApplicationId: string, - notifyStudent: boolean, -): Promise => { - try { - const response = await axiosInstance.post( - `/api/thesis-applications/${thesisApplicationId}/reject`, - {}, - { - params: { - notifyStudent, - }, - }, - ) - - if (response) { - notifications.show({ - color: 'green', - autoClose: 5000, - title: 'Success', - message: notifyStudent - ? `Sent a rejection mail successfully.` - : 'Application status updated successfully', - }) - } - - return response.data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 5000, - title: 'Error', - message: notifyStudent - ? `Failed to send a rejection mail.` - : 'Failed to update application status', - }) - return undefined - } -} - -export const getThesisAdvisors = async (): Promise => { - try { - return (await axiosInstance.get(`/api/thesis-applications/thesis-advisors`)).data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not fetch thesis advisors.`, - }) - return [] - } -} - -export const putThesisAdvisor = async ( - thesisAdvisor: ThesisAdvisor, -): Promise => { - try { - return (await axiosInstance.put(`/api/thesis-applications/thesis-advisors`, thesisAdvisor)).data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not add thesis advisor.`, - }) - return undefined - } -} - -export const postThesisApplicationThesisAdvisorAssignment = async ( - thesisApplicationId: string, - thesisAdvisorId: string, -): Promise => { - try { - return ( - await axiosInstance.post( - `/api/thesis-applications/${thesisApplicationId}/thesis-advisor/${thesisAdvisorId}`, - {}, - ) - ).data - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not assign thesis advisor to thesis application.`, - }) - return undefined - } -} - -export const getThesisApplicationExaminationFile = async ( - thesisApplicationId: string, -): Promise => { - try { - const response = await axiosInstance.get( - `/api/thesis-applications/${thesisApplicationId}/examination-report`, - { - responseType: 'blob', - }, - ) - if (response) { - return new Blob([response.data], { type: 'application/pdf' }) - } - return undefined - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not load examination file.`, - }) - return undefined - } -} - -export const getThesisApplicationCvFile = async ( - thesisApplicationId: string, -): Promise => { - try { - const response = await axiosInstance.get(`/api/thesis-applications/${thesisApplicationId}/cv`, { - responseType: 'blob', - }) - if (response) { - return new Blob([response.data], { type: 'application/pdf' }) - } - return undefined - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not load cv file.`, - }) - return undefined - } -} - -export const getThesisApplicationBachelorReportFile = async ( - thesisApplicationId: string, -): Promise => { - try { - const response = await axiosInstance.get( - `/api/thesis-applications/${thesisApplicationId}/bachelor-report`, - { - responseType: 'blob', - }, - ) - if (response) { - return new Blob([response.data], { type: 'application/pdf' }) - } - return undefined - } catch (err) { - notifications.show({ - color: 'red', - autoClose: 10000, - title: 'Error', - message: `Could not load bachelor report file.`, - }) - return undefined - } -} diff --git a/client/src/pages/CreateTopicPage/CreateTopicPage.tsx b/client/src/pages/CreateTopicPage/CreateTopicPage.tsx new file mode 100644 index 00000000..0debd72a --- /dev/null +++ b/client/src/pages/CreateTopicPage/CreateTopicPage.tsx @@ -0,0 +1,16 @@ +import ContentContainer from '../../app/layout/ContentContainer/ContentContainer' +import React from 'react' +import { usePageTitle } from '../../hooks/theme' + +const CreateTopicPage = () => { + // TODO: implement component + usePageTitle('Create Topic') + + return ( + +

Create Topic

+
+ ) +} + +export default CreateTopicPage diff --git a/client/src/pages/DashboardPage/DashboardPage.tsx b/client/src/pages/DashboardPage/DashboardPage.tsx new file mode 100644 index 00000000..516eb18e --- /dev/null +++ b/client/src/pages/DashboardPage/DashboardPage.tsx @@ -0,0 +1,16 @@ +import ContentContainer from '../../app/layout/ContentContainer/ContentContainer' +import React from 'react' +import { usePageTitle } from '../../hooks/theme' + +const DashboardPage = () => { + // TODO: implement component + usePageTitle('Dashboard') + + return ( + +

Dashboard

+
+ ) +} + +export default DashboardPage diff --git a/client/src/pages/LandingPage/LandingPage.tsx b/client/src/pages/LandingPage/LandingPage.tsx new file mode 100644 index 00000000..2130bf1e --- /dev/null +++ b/client/src/pages/LandingPage/LandingPage.tsx @@ -0,0 +1,15 @@ +import { useNavigate } from 'react-router-dom' +import { useEffect } from 'react' + +const LandingPage = () => { + // TODO: implement component + const navigate = useNavigate() + + useEffect(() => { + navigate('/applications/thesis', { replace: true }) + }, []) + + return <> +} + +export default LandingPage diff --git a/client/src/pages/LegacyApplicationReviewPage/LegacyApplicationReviewPage.tsx b/client/src/pages/LegacyApplicationReviewPage/LegacyApplicationReviewPage.tsx new file mode 100644 index 00000000..4bbd6aa1 --- /dev/null +++ b/client/src/pages/LegacyApplicationReviewPage/LegacyApplicationReviewPage.tsx @@ -0,0 +1,53 @@ +import { useEffect } from 'react' +import { Affix, Button, Center, Transition, rem, Container } from '@mantine/core' +import { useWindowScroll } from '@mantine/hooks' +import { LegacyThesisApplicationsDatatable } from './components/LegacyThesisApplicationsDatatable/LegacyThesisApplicationsDatatable' +import { ArrowUp } from 'phosphor-react' +import { useLoggedInUser } from '../../hooks/authentication' +import { doRequest } from '../../requests/request' + +const LegacyApplicationReviewPage = () => { + const [scroll, scrollTo] = useWindowScroll() + + const user = useLoggedInUser() + + useEffect(() => { + return doRequest( + '/api/thesis-applications/thesis-advisors', + { + method: 'PUT', + requiresAuth: true, + data: { + firstName: user.first_name, + lastName: user.last_name, + email: user.email, + tumId: user.university_id, + }, + }, + () => {}, + ) + }, [user.user_id]) + + return ( + +
+ + + 0}> + {(transitionStyles) => ( + + )} + + +
+
+ ) +} + +export default LegacyApplicationReviewPage diff --git a/client/src/management/components/ThesisApplicationsDatatable.tsx b/client/src/pages/LegacyApplicationReviewPage/components/LegacyThesisApplicationsDatatable/LegacyThesisApplicationsDatatable.tsx similarity index 61% rename from client/src/management/components/ThesisApplicationsDatatable.tsx rename to client/src/pages/LegacyApplicationReviewPage/components/LegacyThesisApplicationsDatatable/LegacyThesisApplicationsDatatable.tsx index 8437d840..8478ae1d 100644 --- a/client/src/management/components/ThesisApplicationsDatatable.tsx +++ b/client/src/pages/LegacyApplicationReviewPage/components/LegacyThesisApplicationsDatatable/LegacyThesisApplicationsDatatable.tsx @@ -1,57 +1,94 @@ -import { useState } from 'react' +import { useEffect, useState } from 'react' import { ActionIcon, Badge, Group, Modal, MultiSelect, Stack, TextInput } from '@mantine/core' import { DataTable, type DataTableSortStatus } from 'mantine-datatable' import { useAutoAnimate } from '@formkit/auto-animate/react' -import { IconExternalLink, IconEyeEdit, IconSearch } from '@tabler/icons-react' -import moment from 'moment' import { Link } from 'react-router-dom' -import { useQuery } from '@tanstack/react-query' -import { Query } from '../../state/query' -import { getThesisApplications } from '../../network/thesisApplication' -import { ThesisApplication } from '../../interface/thesisApplication' -import { ApplicationStatus } from '../../interface/application' +import LegacyThesisApplicationForm from '../../../LegacySubmitApplicationPage/LegacyThesisApplicationForm' +import { Pageable } from '../../../../requests/types/pageable' +import { LegacyThesisApplication } from '../../../../legacy/interfaces/thesisApplication' import { - ApplicationFormAccessMode, - ThesisApplicationForm, -} from '../../student/form/ThesisApplicationForm' -import { Pageable } from '../../interface/pageable' + LegacyApplicationFormAccessMode, + LegacyApplicationStatus, +} from '../../../../legacy/interfaces/application' +import { ArrowSquareOut, Eye, MagnifyingGlass } from 'phosphor-react' +import { notifications } from '@mantine/notifications' +import { doRequest } from '../../../../requests/request' +import { useLoggedInUser } from '../../../../hooks/authentication' +import { formatDate } from '../../../../utils/format' -export const ThesisApplicationsDatatable = (): JSX.Element => { +export const LegacyThesisApplicationsDatatable = () => { const [bodyRef] = useAutoAnimate() const [page, setPage] = useState(1) const [limit, setLimit] = useState(20) + const [version, setVersion] = useState(0) - const [selectedApplications, setSelectedApplications] = useState([]) - const [openedApplication, setOpenedApplication] = useState() + const [selectedApplications, setSelectedApplications] = useState([]) + const [openedApplication, setOpenedApplication] = useState() const [searchQuery, setSearchQuery] = useState('') - const [sort, setSort] = useState>({ + const [sort, setSort] = useState>({ columnAccessor: 'createdAt', direction: 'desc', }) const [filteredStates, setFilteredStates] = useState(['NOT_ASSESSED']) - const { data: applications, isLoading } = useQuery>({ - queryKey: [ - Query.THESIS_APPLICATION, - page, - limit, - searchQuery, - filteredStates?.join(','), - sort.columnAccessor, - sort.direction, - ], - queryFn: () => - getThesisApplications( - page - 1, - limit, - filteredStates, - searchQuery, - sort.columnAccessor, - sort.direction, - ), - }) + const [applications, setApplications] = useState>() + + const user = useLoggedInUser() + + useEffect(() => { + setApplications(undefined) + + return doRequest>( + `/api/thesis-applications`, + { + method: 'GET', + params: { + page: page - 1, + limit, + states: filteredStates?.join(',') ?? Object.keys(LegacyApplicationStatus).join(','), + searchQuery, + sortBy: sort.columnAccessor, + sortOrder: sort.direction, + }, + requiresAuth: true, + }, + (error, res) => { + if (!res?.ok) { + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not fetch thesis applications. ${error || ''}`, + }) + + return setApplications({ + content: [], + totalPages: 0, + totalElements: 0, + number: 0, + size: 0, + empty: true, + first: true, + last: true, + numberOfElements: 0, + }) + } + + setApplications(res.data) + }, + ) + }, [ + version, + user.user_id, + page, + limit, + searchQuery, + filteredStates?.join(','), + sort.columnAccessor, + sort.direction, + ]) return ( @@ -64,23 +101,27 @@ export const ThesisApplicationsDatatable = (): JSX.Element => { setOpenedApplication(undefined) }} > - { + setVersion((prev) => prev + 1) + setOpenedApplication(undefined) + }} /> )} } + leftSection={} value={searchQuery} onChange={(e) => { setSearchQuery(e.currentTarget.value) }} /> { hidePickedOptions label='Status' description='Show all applications having status in' - data={Object.keys(ApplicationStatus).map((key) => { + data={Object.keys(LegacyApplicationStatus).map((key) => { return { - label: ApplicationStatus[key as keyof typeof ApplicationStatus], + label: LegacyApplicationStatus[key as keyof typeof LegacyApplicationStatus], value: key, } })} @@ -128,7 +169,7 @@ export const ThesisApplicationsDatatable = (): JSX.Element => { onChange={(value) => { setFilteredStates(value.length > 0 ? value : undefined) }} - leftSection={} + leftSection={} clearable searchable /> @@ -146,7 +187,11 @@ export const ThesisApplicationsDatatable = (): JSX.Element => { default: break } - return {ApplicationStatus[application.applicationStatus]} + return ( + + {LegacyApplicationStatus[application.applicationStatus]} + + ) }, }, { @@ -175,8 +220,7 @@ export const ThesisApplicationsDatatable = (): JSX.Element => { accessor: 'createdAt', title: 'Created At', sortable: true, - render: (application) => - `${moment(application.createdAt).format('DD. MMMM YYYY HH:mm')}`, + render: (application) => `${formatDate(application.createdAt, {})}`, }, { accessor: 'actions', @@ -193,7 +237,7 @@ export const ThesisApplicationsDatatable = (): JSX.Element => { setOpenedApplication(application) }} > - + { color='blue' onClick={(e) => e.stopPropagation()} > - + diff --git a/client/src/pages/LegacySubmitApplicationPage/LegacyThesisApplicationForm.tsx b/client/src/pages/LegacySubmitApplicationPage/LegacyThesisApplicationForm.tsx new file mode 100644 index 00000000..f0b45da7 --- /dev/null +++ b/client/src/pages/LegacySubmitApplicationPage/LegacyThesisApplicationForm.tsx @@ -0,0 +1,1017 @@ +import { isEmail, isNotEmpty, useForm } from '@mantine/form' +import { Dropzone, PDF_MIME_TYPE } from '@mantine/dropzone' +import countries from 'i18n-iso-countries' +import enLocale from 'i18n-iso-countries/langs/en.json' +import { + ActionIcon, + Box, + Button, + Card, + Center, + Checkbox, + Divider, + Group, + Image, + Loader, + LoadingOverlay, + Select, + Spoiler, + Stack, + Text, + Textarea, + Title, + rem, + useMantineTheme, +} from '@mantine/core' +import { DeclarationOfDataConsent } from '../../components/DeclarationOfDataConsent/DeclarationOfDataConsent' +import LS1Logo from '../../static/ls1logo.png' +import { DatePickerInput } from '@mantine/dates' +import { notifications } from '@mantine/notifications' +import { useDisclosure } from '@mantine/hooks' +import { LegacyApplicationSuccessfulSubmission } from './components/LegacyApplicationSubmission/LegacyApplicationSuccessfulSubmission' +import { useEffect, useState } from 'react' +import LegacyFormTextField from './form/LegacyFormTextField' +import LegacyFormSelectField from './form/LegacyFormSelectField' +import { + getThesisApplicationBachelorReportFile, + getThesisApplicationCvFile, + getThesisApplicationExaminationFile, + postThesisApplicatioAcceptance, + postThesisApplicationAssessment, + postThesisApplicationRejection, + postThesisApplicationThesisAdvisorAssignment, +} from '../../legacy/network/thesisApplication' +import { + LegacyThesisAdvisor, + LegacyThesisApplication, +} from '../../legacy/interfaces/thesisApplication' +import { Calendar, ImageSquare, UploadSimple, X } from 'phosphor-react' +import { GLOBAL_CONFIG } from '../../config/global' +import { doRequest } from '../../requests/request' +import { formatDate } from '../../utils/format' +import { usePromiseLoader } from '../../hooks/utility' +import { downloadPdf } from '../../utils/blob' +import { LegacyApplicationFormAccessMode } from '../../legacy/interfaces/application' + +countries.registerLocale(enLocale) +const countriesArr = Object.entries(countries.getNames('en', { select: 'alias' })).map( + ([key, value]) => { + return { + label: value, + value: key, + } + }, +) + +interface ThesisApplicationFormProps { + accessMode: LegacyApplicationFormAccessMode + application?: LegacyThesisApplication + onUpdate?: () => unknown +} + +const LegacyThesisApplicationForm = ({ + application, + accessMode, + onUpdate, +}: ThesisApplicationFormProps) => { + const theme = useMantineTheme() + + const [loadingOverlayVisible, loadingOverlayHandlers] = useDisclosure(false) + const [applicationSuccessfullySubmitted, setApplicationSuccessfullySubmitted] = useState(false) + const [notifyStudent, setNotifyStudent] = useState(true) + const uploads = useForm<{ + examinationReport: File | undefined + cv: File | undefined + bachelorReport: File | undefined + }>({ + initialValues: { + examinationReport: undefined, + cv: undefined, + bachelorReport: undefined, + }, + validate: { + examinationReport: (value) => { + if (!value) { + return 'Please upload your examination report.' + } else if (value && value.size > 1 * 1024 ** 2) { + return 'The file should not exceed 3mb' + } + }, + cv: (value) => { + if (!value) { + return 'Please upload your CV.' + } else if (value && value.size > 1 * 1024 ** 2) { + return 'The file should not exceed 3mb' + } + }, + }, + }) + const form = useForm({ + initialValues: application + ? { + ...application, + desiredThesisStart: new Date(application.desiredThesisStart), + assessmentComment: application.assessmentComment ?? '', + } + : { + id: '', + student: { + id: '', + tumId: '', + matriculationNumber: '', + isExchangeStudent: false, + email: '', + firstName: '', + lastName: '', + nationality: '', + gender: undefined, + suggestedAsCoach: false, + suggestedAsTutor: false, + blockedByPm: false, + reasonForBlockedByPm: '', + }, + studyDegree: undefined, + studyProgram: undefined, + currentSemester: '', + start: '', + specialSkills: '', + researchAreas: [], + focusTopics: [], + motivation: '', + projects: '', + interests: '', + thesisTitle: '', + desiredThesisStart: new Date(), + applicationStatus: 'NOT_ASSESSED', + assessmentComment: '', + }, + validateInputOnChange: ['student.tumId'], + validateInputOnBlur: true, + validate: { + student: { + tumId: (value, values) => + /^[A-Za-z]{2}[0-9]{2}[A-Za-z]{3}$/.test(value ?? '') || values.student?.isExchangeStudent + ? null + : 'This is not a valid TUM ID', + matriculationNumber: (value, values) => + /^\d{8}$/.test(value ?? '') || values.student?.isExchangeStudent + ? null + : 'This is not a valid matriculation number.', + firstName: isNotEmpty('Please state your first name.'), + lastName: isNotEmpty('Please state your last name'), + email: isEmail('Invalid email'), + gender: isNotEmpty('Please state your gender.'), + nationality: isNotEmpty('Please state your nationality.'), + }, + motivation: (value) => { + if (!value || !isNotEmpty(value)) { + return 'Please state your motivation for the thesis.' + } else if (value.length > 500) { + return 'The maximum allowed number of characters is 500.' + } + }, + specialSkills: (value) => { + if (!value || !isNotEmpty(value)) { + return 'Please state your special skills.' + } else if (value.length > 500) { + return 'The maximum allowed number of characters is 500.' + } + }, + interests: (value) => { + if (!value || !isNotEmpty(value)) { + return 'Please state your interests.' + } else if (value.length > 500) { + return 'The maximum allowed number of characters is 500.' + } + }, + projects: (value) => { + if (!value || !isNotEmpty(value)) { + return 'Please state your projects.' + } else if (value.length > 500) { + return 'The maximum allowed number of characters is 500.' + } + }, + thesisTitle: (value) => { + if (!value || !isNotEmpty(value)) { + return 'Please state your thesis title suggestion.' + } else if (value.length > 200) { + return 'The maximum allowed number of characters is 200.' + } + }, + studyDegree: isNotEmpty('Please state your study degree.'), + studyProgram: isNotEmpty('Please state your study program.'), + currentSemester: (value) => { + return !value || value.length === 0 || !/\b([1-9]|[1-9][0-9])\b/.test(value) + ? 'Please state your current semester.' + : null + }, + }, + }) + const consentForm = useForm({ + initialValues: { + declarationOfConsentAccepted: false, + }, + validateInputOnChange: true, + validate: { + declarationOfConsentAccepted: (value) => !value, + }, + }) + + const [fetchedThesisAdvisors, setFetchedThesisAdvisors] = useState() + + useEffect(() => { + if (accessMode === LegacyApplicationFormAccessMode.INSTRUCTOR) { + return doRequest( + `/api/thesis-applications/thesis-advisors`, + { + method: 'GET', + requiresAuth: true, + }, + (err, res) => { + if (!res?.ok) { + notifications.show({ + color: 'red', + autoClose: 10000, + title: 'Error', + message: `Could not fetch thesis advisors.`, + }) + + setFetchedThesisAdvisors([]) + } else { + setFetchedThesisAdvisors(res.data) + } + }, + ) + } + }, [accessMode]) + + const assessThesisApplication = usePromiseLoader(async () => { + await postThesisApplicationAssessment(application?.id ?? '', { + status: form.values.applicationStatus, + assessmentComment: form.values.assessmentComment ?? '', + }) + }) + + const assignThesisApplicationToThesisAdvisor = usePromiseLoader((advisorId: string) => + postThesisApplicationThesisAdvisorAssignment(application?.id ?? '', advisorId), + ) + + const acceptThesisApplication = usePromiseLoader(async () => { + await postThesisApplicatioAcceptance(application?.id ?? '', notifyStudent) + + onUpdate?.() + }) + + const rejectThesisApplication = usePromiseLoader(async () => { + await postThesisApplicationRejection(application?.id ?? '', notifyStudent) + + onUpdate?.() + }) + + const [thesisAdvisorId, setThesisAdvisorId] = useState( + application?.thesisAdvisor?.id ?? null, + ) + + useEffect(() => { + setThesisAdvisorId(application?.thesisAdvisor?.id ?? null) + }, [application]) + + return ( +
+ + + {applicationSuccessfullySubmitted ? ( + + ) : ( + + {accessMode === LegacyApplicationFormAccessMode.STUDENT && ( + +
+ LS1 Logo +
+
+ Thesis Application at LS1 Chair +
+
+ )} +
+ + + + + + + + + + { + return { + label: GLOBAL_CONFIG.genders[key], + value: key, + } + })} + selectProps={form.getInputProps('student.gender')} + /> + c.value == form.values.student.nationality)?.label ?? + '' + } + data={countriesArr} + selectProps={form.getInputProps('student.nationality')} + /> + + + + { + return { + label: GLOBAL_CONFIG.study_degrees[key], + value: key, + } + })} + selectProps={form.getInputProps('studyDegree')} + /> + { + return { + label: GLOBAL_CONFIG.study_programs[key], + value: key, + } + })} + selectProps={form.getInputProps('studyProgram')} + /> + + + +
+ + {!form.errors.specialSkills && + accessMode !== LegacyApplicationFormAccessMode.INSTRUCTOR && ( + {`${ + form.values.specialSkills?.length ?? 0 + } / 500`} + )} +
+
+ + {!form.errors.motivation && + accessMode !== LegacyApplicationFormAccessMode.INSTRUCTOR && ( + {`${form.values.motivation?.length ?? 0} / 500`} + )} +
+
+ +
+ + {!form.errors.interests && + accessMode !== LegacyApplicationFormAccessMode.INSTRUCTOR && ( + {`${form.values.interests?.length ?? 0} / 500`} + )} +
+
+ + {!form.errors.projects && + accessMode !== LegacyApplicationFormAccessMode.INSTRUCTOR && ( + {`${form.values.projects?.length ?? 0} / 500`} + )} +
+
+
+ + {!form.errors.thesisTitle && + accessMode !== LegacyApplicationFormAccessMode.INSTRUCTOR && ( + {`${form.values.thesisTitle?.length ?? 0} / 200`} + )} +
+ {accessMode === LegacyApplicationFormAccessMode.INSTRUCTOR ? ( + + + Desired Thesis Start Date + + + {formatDate(form.values.desiredThesisStart, { includeHours: false })} + + + ) : ( + } + label='Desired Thesis Start Date' + {...form.getInputProps('desiredThesisStart')} + /> + )} + + { + return { + label: GLOBAL_CONFIG.research_areas[key] ?? key, + value: key, + } + })} + label='Research Areas' + placeholder='Research areas' + readValue={form.values.researchAreas + .map((ra) => GLOBAL_CONFIG.research_areas[ra] ?? ra) + .join(', ')} + multiselectProps={form.getInputProps('researchAreas')} + /> + { + return { + label: GLOBAL_CONFIG.focus_topics[key] ?? key, + value: key, + } + })} + label='Focus Topics' + placeholder='Focus topics' + readValue={form.values.focusTopics + .map((ft) => GLOBAL_CONFIG.focus_topics[ft] ?? ft) + .join(', ')} + multiselectProps={form.getInputProps('focusTopics')} + /> + + {accessMode === LegacyApplicationFormAccessMode.STUDENT && ( + + + + Examination Report + + * + + {uploads.values.examinationReport && ( + + + + {uploads.values.examinationReport.name} + + { + uploads.setValues({ examinationReport: undefined }) + }} + > + + + + + )} + {!uploads.values.examinationReport && ( + { + if (files[0]) { + uploads.setValues({ + examinationReport: files[0], + }) + } + }} + onReject={() => { + notifications.show({ + color: 'red', + autoClose: 5000, + title: 'Error', + message: `Failed upload file. Please make sure the file is a PDF and does not exceed 1mb.`, + }) + }} + maxSize={1 * 1024 ** 2} + accept={PDF_MIME_TYPE} + > + + + + + + + + + + + +
+ + Drag the file here or click to select file + + + The file should not exceed 1mb + +
+
+
+ )} + + + CV + + * + + {uploads.values.cv && ( + + + + {uploads.values.cv.name} + + { + uploads.setValues({ cv: undefined }) + }} + > + + + + + )} + {!uploads.values.cv && ( + { + if (files[0]) { + uploads.setValues({ + cv: files[0], + }) + } + }} + onReject={() => { + notifications.show({ + color: 'red', + autoClose: 5000, + title: 'Error', + message: `Failed upload file. Please make sure the file is a PDF and does not exceed 1mb.`, + }) + }} + maxSize={1 * 1024 ** 2} + accept={PDF_MIME_TYPE} + > + + + + + + + + + + + +
+ + Drag the file here or click to select file + + + The file should not exceed 1mb + +
+
+
+ )} + + Bachelor Report + + {uploads.values.bachelorReport && ( + + + + {uploads.values.bachelorReport.name} + + { + uploads.setValues({ bachelorReport: undefined }) + }} + > + + + + + )} + {!uploads.values.bachelorReport && ( + { + if (files[0]) { + uploads.setValues({ + bachelorReport: files[0], + }) + } + }} + onReject={() => { + notifications.show({ + color: 'red', + autoClose: 5000, + title: 'Error', + message: `Failed upload file. Please make sure the file is a PDF and does not exceed 1mb.`, + }) + }} + maxSize={1 * 1024 ** 2} + accept={PDF_MIME_TYPE} + > + + + + + + + + + + + +
+ + Drag the file here or click to select file + + + The file should not exceed 1mb + +
+
+
+ )} +
+ )} + + {accessMode === LegacyApplicationFormAccessMode.INSTRUCTOR && ( + <> + + Uploaded Files + + } + labelPosition='center' + /> + + {application?.examinationReportFilename && ( + + )} + {application?.cvFilename && ( + + )} + {application?.bachelorReportFilename && ( + + )} + + + + )} + {accessMode === LegacyApplicationFormAccessMode.INSTRUCTOR && ( + <> +