diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 38f85d2..a4ed7b5 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,24 +14,22 @@ "@fullcalendar/timegrid": "^6.1.11", "@fullcalendar/vue3": "^6.1.11", "@tanstack/vue-query": "^5.28.9", - "@tanstack/vue-query-devtools": "^5.28.10", "@unhead/ssr": "^1.9.14", - "@unhead/vue": "^1.9.10", "@vueuse/core": "^10.9.0", "pinia": "^2.1.7", "primeflex": "^3.3.1", "primeicons": "^6.0.1", "primevue": "^3.50.0", "source-sans": "^3.46.0", - "vite-ssg": "^0.23.7", "vue": "^3.4.11", - "vue-i18n": "^9.10.2", - "vue-router": "^4.3.0" + "vue-i18n": "^9.10.2" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", + "@tanstack/vue-query-devtools": "^5.28.10", "@types/node": "^20.12.2", + "@unhead/vue": "^1.9.15", "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-typescript": "^12.0.0", "eslint": "^8.57.0", @@ -43,8 +41,11 @@ "terser": "^5.31.0", "typescript": "^5.4.3", "vite": "^5.2.7", + "vite-plugin-vue-devtools": "^7.3.1", + "vite-ssg": "^0.23.7", "vite-ssg-sitemap": "^0.7.1", "vitest": "^1.4.0", + "vue-router": "^4.4.0", "vue-tsc": "^1.8.27" } }, @@ -57,10 +58,522 @@ "node": ">=0.10.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "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, + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz", + "integrity": "sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7", + "@babel/helper-replace-supers": "^7.24.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz", + "integrity": "sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", + "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz", + "integrity": "sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-member-expression-to-functions": "^7.24.7", + "@babel/helper-optimise-call-expression": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", + "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -68,6 +581,182 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.7.tgz", + "integrity": "sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-decorators": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.7.tgz", + "integrity": "sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz", + "integrity": "sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.24.7", + "@babel/helper-create-class-features-plugin": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/plugin-syntax-typescript": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -75,6 +764,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "aix" @@ -90,6 +780,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -105,6 +796,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -120,6 +812,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -135,6 +828,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -150,6 +844,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -165,6 +860,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -180,6 +876,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -195,6 +892,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -210,6 +908,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -225,6 +924,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -240,6 +940,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -255,6 +956,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -270,6 +972,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -285,6 +988,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -300,6 +1004,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -315,6 +1020,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -330,6 +1036,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -345,6 +1052,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -360,6 +1068,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -375,6 +1084,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -390,6 +1100,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -405,6 +1116,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -600,14 +1312,15 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "devOptional": true, + "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, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -617,16 +1330,17 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "devOptional": true, + "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, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -635,7 +1349,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -647,10 +1361,11 @@ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", - "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", - "devOptional": true, + "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, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -691,6 +1406,13 @@ "node": ">= 8" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.25", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.25.tgz", + "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/plugin-node-resolve": { "version": "15.2.3", "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz", @@ -773,6 +1495,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -785,6 +1508,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -797,6 +1521,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -809,6 +1534,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -821,6 +1547,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -833,6 +1560,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -845,6 +1573,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -857,6 +1586,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -869,6 +1599,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -881,6 +1612,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -893,6 +1625,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -905,6 +1638,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -917,6 +1651,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -929,6 +1664,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -941,6 +1677,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -953,6 +1690,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -992,6 +1730,7 @@ "version": "5.28.10", "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.28.10.tgz", "integrity": "sha512-5UN629fKa5/1K/2Pd26gaU7epxRrYiT1gy+V+pW5K6hnf1DeUKK3pANSb2eHKlecjIKIhTwyF7k9XdyE2gREvQ==", + "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1025,6 +1764,7 @@ "version": "5.28.10", "resolved": "https://registry.npmjs.org/@tanstack/vue-query-devtools/-/vue-query-devtools-5.28.10.tgz", "integrity": "sha512-KfJssD1dMVw/gAxAFCzUoYXCXm+xszEa83SxMQdLtEbXO0O8PuIN5zIJZBxDTcUHfq89k2OJUKzU9rPiMMoT0w==", + "dev": true, "dependencies": { "@tanstack/query-devtools": "5.28.10" }, @@ -1087,7 +1827,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/json-schema": { "version": "7.0.12", @@ -1099,7 +1840,7 @@ "version": "20.12.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.4.tgz", "integrity": "sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==", - "devOptional": true, + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -1317,21 +2058,25 @@ "dev": true }, "node_modules/@unhead/dom": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.9.10.tgz", - "integrity": "sha512-F4sBrmd8kG8MEqcVTGL0Y6tXbJMdWK724pznUzefpZTs1GaVypFikLluaLt4EnICcVhOBSe4TkGrc8N21IJJzQ==", + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.9.15.tgz", + "integrity": "sha512-4sdP/2Unt4zFRO8pBZVXvebidGmrLEvnDU6ZpasZfInjiiuuaQOVTJaiKnEnug3cmW2YjglPG2d1c2xAsHr3NQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@unhead/schema": "1.9.10", - "@unhead/shared": "1.9.10" + "@unhead/schema": "1.9.15", + "@unhead/shared": "1.9.15" }, "funding": { "url": "https://github.com/sponsors/harlan-zw" } }, "node_modules/@unhead/schema": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.9.10.tgz", - "integrity": "sha512-3ROh0doKfA7cIcU0zmjYVvNOiJuxSOcjInL+7iOFIxQovEWr1PcDnrnbEWGJsXrLA8eqjrjmhuDqAr3JbMGsLg==", + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.9.15.tgz", + "integrity": "sha512-9ADZuXOH+tOKHIjXsgg+SPINnh/YJEBMCjpg+8VLGgE2r5med3jAnOU8g7ALfuVEBRBrbFgs1qVKoKm1NkTXJQ==", + "dev": true, + "license": "MIT", "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" @@ -1341,11 +2086,13 @@ } }, "node_modules/@unhead/shared": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.9.10.tgz", - "integrity": "sha512-LBXxm/8ahY4FZ0FbWVaM1ANFO5QpPzvaYwjAQhgHANsrqFP2EqoGcOv1CfhdQbxg8vpGXkjI7m0r/8E9d3JoDA==", + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.9.15.tgz", + "integrity": "sha512-+U5r04eRtCNcniWjzNPRtwVuF9rW/6EXxhGvuohJBDaIE57J6BHWo5cEp7Pqts7DlTFs7LiDtH8ONNDv4QqRaw==", + "dev": true, + "license": "MIT", "dependencies": { - "@unhead/schema": "1.9.10" + "@unhead/schema": "1.9.15" }, "funding": { "url": "https://github.com/sponsors/harlan-zw" @@ -1387,14 +2134,16 @@ } }, "node_modules/@unhead/vue": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.9.10.tgz", - "integrity": "sha512-Zi65eTU5IIaqqXAVOVJ4fnwJRR751FZIFlzYOjIekf1eNkISy+A4xyz3NIEQWSlXCrOiDNgDhT0YgKUcx5FfHQ==", + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.9.15.tgz", + "integrity": "sha512-h866wYOs6Q6+lc0av4EU0CPTtTvaz9UWwwsiNoulzJa95QyUN/gDPI/NiDuKweHswY+a0SSzEqe9Nhg+LlmHew==", + "dev": true, + "license": "MIT", "dependencies": { - "@unhead/schema": "1.9.10", - "@unhead/shared": "1.9.10", + "@unhead/schema": "1.9.15", + "@unhead/shared": "1.9.15", "hookable": "^5.5.3", - "unhead": "1.9.10" + "unhead": "1.9.15" }, "funding": { "url": "https://github.com/sponsors/harlan-zw" @@ -1540,6 +2289,84 @@ "path-browserify": "^1.0.1" } }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.2.tgz", + "integrity": "sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.2.tgz", + "integrity": "sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "~7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.23.3", + "@babel/template": "^7.23.9", + "@babel/traverse": "^7.23.9", + "@babel/types": "^7.23.9", + "@vue/babel-helper-vue-transform-on": "1.2.2", + "@vue/babel-plugin-resolve-type": "1.2.2", + "camelcase": "^6.3.0", + "html-tags": "^3.3.1", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-jsx/node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.2.tgz", + "integrity": "sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/helper-module-imports": "~7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/parser": "^7.23.9", + "@vue/compiler-sfc": "^3.4.15" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/babel-plugin-resolve-type/node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@vue/compiler-core": { "version": "3.4.15", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz", @@ -1601,6 +2428,50 @@ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.1.tgz", "integrity": "sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==" }, + "node_modules/@vue/devtools-core": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-core/-/devtools-core-7.3.5.tgz", + "integrity": "sha512-uSC3IkIp6MtyJYSh5xzY99sgqlAXLq+peE2KKXTi6JeRHOtMngFWFWENXi70IJ1EVGYztiFQoHhI9WZcgKBz8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.3.5", + "@vue/devtools-shared": "^7.3.5", + "mitt": "^3.0.1", + "nanoid": "^3.3.4", + "pathe": "^1.1.2", + "vite-hot-client": "^0.2.3" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.3.5.tgz", + "integrity": "sha512-wwfi10gJ1HMtjzcd8aIOnzBHlIRqsYDgcDyrKvkeyc0Gbcoe7UrkXRVHZUOtcxxoplHA0PwpT6wFg0uUCmi8Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.3.5", + "birpc": "^0.2.17", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.3.5.tgz", + "integrity": "sha512-Rqii3VazmWTi67a86rYopi61n5Ved05EybJCwyrfoO9Ok3MaS/4yRFl706ouoISMlyrASJFEzM0/AiDA6w4f9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, "node_modules/@vue/eslint-config-typescript": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz", @@ -1980,7 +2851,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "devOptional": true, + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -2020,6 +2891,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, "dependencies": { "debug": "^4.3.4" }, @@ -2057,6 +2929,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { "node": ">=8" } @@ -2065,6 +2938,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -2079,7 +2953,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2115,7 +2989,8 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/balanced-match": { "version": "1.0.2", @@ -2127,11 +3002,21 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } }, + "node_modules/birpc": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.17.tgz", + "integrity": "sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -2149,21 +3034,22 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "funding": [ { @@ -2179,12 +3065,12 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001541", - "electron-to-chromium": "^1.4.535", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" }, "bin": { "browserslist": "cli.js" @@ -2197,7 +3083,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "devOptional": true + "dev": true }, "node_modules/builtin-modules": { "version": "3.3.0", @@ -2211,6 +3097,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -2233,15 +3135,30 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dev": true, + "license": "MIT", "dependencies": { "no-case": "^2.2.0", "upper-case": "^1.1.1" } }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/caniuse-lite": { - "version": "1.0.30001555", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001555.tgz", - "integrity": "sha512-NzbUFKUnJ3DTcq6YyZB6+qqhfD112uR3uoEnkmfzm2wVzUNsFkU7AwBjKQ654Sp5cau0JxhFyRSn/tQZ+XfygA==", + "version": "1.0.30001640", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001640.tgz", + "integrity": "sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==", "dev": true, "funding": [ { @@ -2257,7 +3174,7 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true + "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "4.4.1", @@ -2309,7 +3226,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "devOptional": true, + "dev": true, "funding": [ { "type": "individual", @@ -2336,7 +3253,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -2358,6 +3275,8 @@ "version": "4.2.4", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dev": true, + "license": "MIT", "dependencies": { "source-map": "~0.6.0" }, @@ -2369,6 +3288,8 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2382,6 +3303,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -2392,12 +3314,14 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "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==", + "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2408,7 +3332,8 @@ "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/computeds": { "version": "0.0.1", @@ -2422,6 +3347,29 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2452,6 +3400,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "dev": true, "dependencies": { "rrweb-cssom": "^0.6.0" }, @@ -2462,7 +3411,8 @@ "node_modules/cssstyle/node_modules/rrweb-cssom": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", - "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true }, "node_modules/csstype": { "version": "3.1.3", @@ -2473,6 +3423,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, "dependencies": { "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0" @@ -2491,6 +3442,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2506,7 +3458,8 @@ "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true }, "node_modules/deep-eql": { "version": "4.1.3", @@ -2535,10 +3488,54 @@ "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", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -2577,16 +3574,18 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.569", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.569.tgz", - "integrity": "sha512-LsrJjZ0IbVy12ApW3gpYpcmHS3iRxH4bkKOW98y1/D+3cvDUWGcbzbsFinfUS8knpcZk/PG/2p/RnkMCYN7PVg==", + "version": "1.4.818", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.818.tgz", + "integrity": "sha512-eGvIk2V0dGImV9gWLq8fDfTTsCAeMDwZqEPMr+jMInxZdnp9Us8UpovYpRCf9NQ7VOFgrN2doNSgvISbsbNpxA==", "dev": true, - "peer": true + "license": "ISC" }, "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==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" }, "node_modules/enhanced-resolve": { "version": "5.15.0", @@ -2613,6 +3612,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/error-stack-parser-es": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-0.1.4.tgz", + "integrity": "sha512-l0uy0kAoo6toCgVOYaAayqtPa2a1L15efxUMEnQebKwLQX2X0OpS6wMMQdc4juJXmxd9i40DuaUHq+mjIya9TQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/es-module-lexer": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.1.tgz", @@ -2624,6 +3633,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -2658,9 +3668,11 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2963,10 +3975,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3014,6 +4027,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3023,19 +4037,6 @@ "node": ">= 6" } }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3046,6 +4047,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -3064,10 +4066,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -3170,7 +4184,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", @@ -3203,6 +4218,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, "bin": { "he": "bin/he" } @@ -3216,6 +4232,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, "dependencies": { "whatwg-encoding": "^3.1.1" }, @@ -3227,6 +4244,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "dev": true, + "license": "MIT", "dependencies": { "camel-case": "^3.0.0", "clean-css": "^4.2.1", @@ -3243,10 +4262,25 @@ "node": ">=6" } }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/html5parser": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html5parser/-/html5parser-2.0.2.tgz", "integrity": "sha512-L0y+IdTVxHsovmye8MBtFgBvWZnq1C9WnI/SmJszxoQjmUH1psX2uzDk21O5k5et6udxdGjwxkbmT9eVRoG05w==", + "dev": true, + "license": "MIT", "dependencies": { "tslib": "^2.2.0" } @@ -3255,6 +4289,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -3267,6 +4302,7 @@ "version": "7.0.5", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -3297,7 +4333,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "integrity": "sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==", - "devOptional": true + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -3344,7 +4380,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -3379,11 +4415,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3392,6 +4444,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3400,7 +4454,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -3408,6 +4462,25 @@ "node": ">=0.10.0" } }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", @@ -3418,7 +4491,8 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, + "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -3435,7 +4509,8 @@ "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true }, "node_modules/is-stream": { "version": "3.0.0", @@ -3449,6 +4524,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3508,6 +4612,7 @@ "version": "24.1.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "dev": true, "dependencies": { "cssstyle": "^4.0.1", "data-urls": "^5.0.0", @@ -3547,10 +4652,24 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, "engines": { "node": ">=18" } }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -3576,23 +4695,25 @@ "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==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonc-parser": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/keyv": { "version": "4.5.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", @@ -3605,7 +4726,9 @@ "node_modules/kolorist": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" }, "node_modules/levn": { "version": "0.4.1", @@ -3685,7 +4808,9 @@ "node_modules/lower-case": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==" + "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { "version": "6.0.0", @@ -3742,6 +4867,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" } @@ -3750,6 +4876,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" }, @@ -3781,6 +4908,13 @@ "node": "*" } }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, "node_modules/mlly": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.5.0.tgz", @@ -3793,10 +4927,21 @@ "ufo": "^1.3.2" } }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/muggle-string": { "version": "0.3.1", @@ -3837,22 +4982,38 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "license": "MIT", "dependencies": { "lower-case": "^1.1.1" } }, - "node_modules/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==", + "node_modules/node-gyp-build": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", "dev": true, - "peer": true + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "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==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3899,7 +5060,8 @@ "node_modules/nwsapi": { "version": "2.2.10", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", - "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==" + "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", + "dev": true }, "node_modules/once": { "version": "1.4.0", @@ -3925,6 +5087,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -3976,6 +5157,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", + "dev": true, + "license": "MIT", "dependencies": { "no-case": "^2.2.0" } @@ -3996,6 +5179,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, "dependencies": { "entities": "^4.4.0" }, @@ -4066,16 +5250,24 @@ "node": "*" } }, - "node_modules/picocolors": { + "node_modules/perfect-debounce": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8.6" }, @@ -4264,12 +5456,14 @@ "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true }, "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" } @@ -4277,7 +5471,8 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -4318,7 +5513,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -4330,6 +5525,8 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.10" } @@ -4343,6 +5540,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4350,7 +5549,8 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true }, "node_modules/resolve": { "version": "1.22.8", @@ -4388,6 +5588,13 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -4407,6 +5614,7 @@ "version": "4.17.2", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -4440,7 +5648,21 @@ "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==" + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", + "dev": true + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/run-parallel": { "version": "1.2.0", @@ -4488,13 +5710,14 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "node_modules/sass": { "version": "1.74.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.74.1.tgz", "integrity": "sha512-w0Z9p/rWZWelb88ISOLyvqTWGmtmu2QJICqDBGyNnfG4OUnPX9BBjjYIXUpXCMOOg5MQWNpqzt876la1fsTvUA==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -4548,6 +5771,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -4637,6 +5861,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -4656,6 +5895,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" } @@ -4672,7 +5912,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==", - "devOptional": true, + "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -4683,6 +5923,16 @@ "resolved": "https://registry.npmjs.org/source-sans/-/source-sans-3.46.0.tgz", "integrity": "sha512-bVC2YX4VNiv5vMcy77dL0XKsNp794ThfynNsr+FqSAwk8TGG0pZsg7eUQi6yHwaRBMVmZ3Aaf4FY46dxIIGgsg==" }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -4699,6 +5949,8 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4712,6 +5964,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4755,6 +6008,19 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/superjson": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.1.tgz", + "integrity": "sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4779,10 +6045,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true }, "node_modules/tapable": { "version": "2.2.1", @@ -4798,7 +6071,7 @@ "version": "5.31.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.0.tgz", "integrity": "sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg==", - "devOptional": true, + "dev": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -4877,11 +6150,22 @@ "node": ">=14.0.0" } }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4889,10 +6173,21 @@ "node": ">=8.0" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dev": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -4907,6 +6202,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, "engines": { "node": ">= 4.0.0" } @@ -4915,6 +6211,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, "dependencies": { "punycode": "^2.3.1" }, @@ -4937,7 +6234,9 @@ "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", @@ -4986,15 +6285,18 @@ } }, "node_modules/ufo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", - "integrity": "sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz", + "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==", + "dev": true, + "license": "MIT" }, "node_modules/uglify-js": { "version": "3.18.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "dev": true, + "license": "BSD-2-Clause", "bin": { "uglifyjs": "bin/uglifyjs" }, @@ -5006,34 +6308,28 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true + "dev": true }, "node_modules/unhead": { - "version": "1.9.10", - "resolved": "https://registry.npmjs.org/unhead/-/unhead-1.9.10.tgz", - "integrity": "sha512-Y3w+j1x1YFig2YuE+W2sER+SciRR7MQktYRHNqvZJ0iUNCCJTS8Z/SdSMUEeuFV28daXeASlR3fy7Ry3O2indg==", + "version": "1.9.15", + "resolved": "https://registry.npmjs.org/unhead/-/unhead-1.9.15.tgz", + "integrity": "sha512-/99Wft1CT0fxsWzmBeOwuH/k4HdMeyfDGyB4wFNVZVNTffRHDOqaqQ6RS+LHPsIiCKmm9FP7Vq7Rz09Zs/fQJQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@unhead/dom": "1.9.10", - "@unhead/schema": "1.9.10", - "@unhead/shared": "1.9.10", + "@unhead/dom": "1.9.15", + "@unhead/schema": "1.9.15", + "@unhead/shared": "1.9.15", "hookable": "^5.5.3" }, "funding": { "url": "https://github.com/sponsors/harlan-zw" } }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "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": [ { @@ -5049,10 +6345,10 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -5064,7 +6360,9 @@ "node_modules/upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==" + "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==", + "dev": true, + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", @@ -5079,11 +6377,28 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" } }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz", + "integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5094,6 +6409,7 @@ "version": "5.2.8", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", + "dev": true, "dependencies": { "esbuild": "^0.20.1", "postcss": "^8.4.38", @@ -5144,6 +6460,19 @@ } } }, + "node_modules/vite-hot-client": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vite-hot-client/-/vite-hot-client-0.2.3.tgz", + "integrity": "sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0" + } + }, "node_modules/vite-node": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.4.0.tgz", @@ -5166,10 +6495,125 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-plugin-inspect": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/vite-plugin-inspect/-/vite-plugin-inspect-0.8.4.tgz", + "integrity": "sha512-G0N3rjfw+AiiwnGw50KlObIHYWfulVwaCBUBLh2xTW9G1eM9ocE5olXkEYUbwyTmX+azM8duubi+9w5awdCz+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.7", + "@rollup/pluginutils": "^5.1.0", + "debug": "^4.3.4", + "error-stack-parser-es": "^0.1.1", + "fs-extra": "^11.2.0", + "open": "^10.1.0", + "perfect-debounce": "^1.0.0", + "picocolors": "^1.0.0", + "sirv": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-inspect/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/vite-plugin-inspect/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, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/vite-plugin-inspect/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, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/vite-plugin-vue-devtools": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.3.5.tgz", + "integrity": "sha512-6omLXTfYu0bmSmncPSbj4mdMPB3t5dAZkUyriJikahGEnvv5gynHlydDsJShHT6l/5dCkvmSesSji/2a6FfutQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-core": "^7.3.5", + "@vue/devtools-kit": "^7.3.5", + "@vue/devtools-shared": "^7.3.5", + "execa": "^8.0.1", + "sirv": "^2.0.4", + "vite-plugin-inspect": "^0.8.4", + "vite-plugin-vue-inspector": "^5.1.2" + }, + "engines": { + "node": ">=v14.21.3" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0-0 || ^5.0.0-0" + } + }, + "node_modules/vite-plugin-vue-inspector": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.1.2.tgz", + "integrity": "sha512-M+yH2LlQtVNzJAljQM+61CqDXBvHim8dU5ImGaQuwlo13tMDHue5D7IC20YwDJuWDODiYc/cZBUYspVlyPf2vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/plugin-proposal-decorators": "^7.23.0", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.22.15", + "@vue/babel-plugin-jsx": "^1.1.5", + "@vue/compiler-dom": "^3.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.4" + }, + "peerDependencies": { + "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0" + } + }, "node_modules/vite-ssg": { "version": "0.23.7", "resolved": "https://registry.npmjs.org/vite-ssg/-/vite-ssg-0.23.7.tgz", "integrity": "sha512-ufkQa45DzXPpo/jPiOkuMvxWn0B1hD1Lw4CnG/9CAgM804/dZYQi9PQvr4a1W0nMjySgsGFwV/zR1JZNzrGEvw==", + "dev": true, + "license": "MIT", "dependencies": { "@unhead/dom": "^1.9.7", "@unhead/vue": "^1.9.7", @@ -5211,10 +6655,40 @@ "integrity": "sha512-5yzGZi9NRREbhObUBCHkzAtth3vaWs7JxQFXugTUjD11IREYN9jATrdp7rGqFcDXVZoZuTAyfT57OYNskEvWFQ==", "dev": true }, + "node_modules/vite-ssg/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/vite-ssg/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, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/vite-ssg/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==", + "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -5225,6 +6699,16 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/vite-ssg/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, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/vitest": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.4.0.tgz", @@ -5354,9 +6838,11 @@ } }, "node_modules/vue-router": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz", - "integrity": "sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.0.tgz", + "integrity": "sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==", + "dev": true, + "license": "MIT", "dependencies": { "@vue/devtools-api": "^6.5.1" }, @@ -5398,6 +6884,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, "dependencies": { "xml-name-validator": "^5.0.0" }, @@ -5409,6 +6896,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, "engines": { "node": ">=18" } @@ -5431,6 +6919,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, "engines": { "node": ">=12" } @@ -5521,6 +7010,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, "dependencies": { "iconv-lite": "0.6.3" }, @@ -5532,6 +7022,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -5543,6 +7034,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, "engines": { "node": ">=18" } @@ -5551,6 +7043,7 @@ "version": "14.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dev": true, "dependencies": { "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" @@ -5594,6 +7087,8 @@ "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, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5616,6 +7111,7 @@ "version": "8.17.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, "engines": { "node": ">=10.0.0" }, @@ -5644,12 +7140,15 @@ "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -5664,6 +7163,8 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -5681,6 +7182,8 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", "engines": { "node": ">=12" } diff --git a/frontend/package.json b/frontend/package.json index fe70d2a..5d64262 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -19,26 +19,24 @@ "@fullcalendar/timegrid": "^6.1.11", "@fullcalendar/vue3": "^6.1.11", "@tanstack/vue-query": "^5.28.9", - "@tanstack/vue-query-devtools": "^5.28.10", "@unhead/ssr": "^1.9.14", - "@unhead/vue": "^1.9.10", "@vueuse/core": "^10.9.0", "pinia": "^2.1.7", "primeflex": "^3.3.1", "primeicons": "^6.0.1", "primevue": "^3.50.0", "source-sans": "^3.46.0", - "vite-ssg": "^0.23.7", "vue": "^3.4.11", - "vue-i18n": "^9.10.2", - "vue-router": "^4.3.0" + "vue-i18n": "^9.10.2" }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "@types/node": "^20.12.2", + "@unhead/vue": "^1.9.15", "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-typescript": "^12.0.0", + "@tanstack/vue-query-devtools": "^5.28.10", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-vue": "^9.24.0", @@ -48,8 +46,11 @@ "terser": "^5.31.0", "typescript": "^5.4.3", "vite": "^5.2.7", + "vite-plugin-vue-devtools": "^7.3.1", + "vite-ssg": "^0.23.7", "vite-ssg-sitemap": "^0.7.1", "vitest": "^1.4.0", + "vue-router": "^4.4.0", "vue-tsc": "^1.8.27" } } diff --git a/frontend/src/view/FaqView.vue b/frontend/src/view/FaqView.vue index 8e56c57..20f4ef4 100644 --- a/frontend/src/view/FaqView.vue +++ b/frontend/src/view/FaqView.vue @@ -234,7 +234,7 @@ along with this program. If not, see .
{{ $t("faqView.ninthQuestion") }}
{{ $t("faqView.ninthAnswer") }} - Gitlab.
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index f89e430..7675e00 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -22,6 +22,7 @@ import {resolve as pathResolver} from "path"; import terser from "@rollup/plugin-terser"; import ViteSSGOptions from "vite-ssg"; import generateSitemap from 'vite-ssg-sitemap' +import vueDevTools from 'vite-plugin-vue-devtools' const hostname = "https://cal.htwk-leipzig.de"; @@ -31,6 +32,7 @@ export default defineConfig({ vue(), resolve(), terser(), + vueDevTools(), ], resolve: { alias: diff --git a/reverseproxy.local.conf b/reverseproxy.local.conf index 05f99c2..60b3822 100644 --- a/reverseproxy.local.conf +++ b/reverseproxy.local.conf @@ -51,5 +51,9 @@ http { location / { proxy_pass http://htwkalender-frontend:8000; } + + location /__devtools__ { + proxy_pass http://htwkalender-frontend:8000; + } } } diff --git a/services/data-manager/main.go b/services/data-manager/main.go index 1e50b50..a5fbcf6 100644 --- a/services/data-manager/main.go +++ b/services/data-manager/main.go @@ -20,7 +20,9 @@ import ( "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/plugins/migratecmd" _ "htwkalender/data-manager/migrations" + "htwkalender/data-manager/model/serviceModel" "htwkalender/data-manager/service" + "htwkalender/data-manager/service/events" "htwkalender/data-manager/service/grpc" "log/slog" "os" @@ -29,6 +31,14 @@ import ( func setupApp() *pocketbase.PocketBase { app := pocketbase.New() + courseService := events.NewPocketBaseCourseService(app) + eventService := events.NewPocketBaseEventService(app) + + services := serviceModel.Service{ + CourseService: courseService, + EventService: eventService, + App: app, + } // loosely check if it was executed using "go run" isGoRun := strings.HasPrefix(os.Args[0], os.TempDir()) @@ -41,8 +51,8 @@ func setupApp() *pocketbase.PocketBase { // (the isGoRun check is to enable it only during development) Automigrate: isGoRun, }) - service.AddRoutes(app) - service.AddSchedules(app) + service.AddRoutes(services) + service.AddSchedules(services) return app } diff --git a/services/data-manager/model/eventModel_test.go b/services/data-manager/model/eventModel_test.go index 2749143..d67cd00 100644 --- a/services/data-manager/model/eventModel_test.go +++ b/services/data-manager/model/eventModel_test.go @@ -37,25 +37,25 @@ func TestEventsContains(t *testing.T) { want bool }{ { - name: "empty events", + name: "event contains empty events", m: Events{}, args: args{event: Event{}}, want: false, }, { - name: "one event", + name: "event contains one event", m: Events{{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}}, args: args{event: Event{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}}, want: true, }, { - name: "two events", + name: "event contains two events", m: Events{{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}, {Day: "test2", Week: "test2", Start: specificTime, End: specificTime, Name: "test2", Course: "test2", Prof: "test2", Rooms: "test2", EventType: "test2"}}, args: args{event: Event{Day: "test2", Week: "test2", Start: specificTime, End: specificTime, Name: "test2", Course: "test2", Prof: "test2", Rooms: "test2", EventType: "test2"}}, want: true, }, { - name: "two events with different values", + name: "event contains two events with different values", m: Events{{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test", UUID: "439ßu56rf8u9ijn4f4-2345345"}, {Day: "test2", Week: "test2", Start: specificTime, End: specificTime, Name: "test2", Course: "test2", Prof: "test2", Rooms: "test2", EventType: "test2", UUID: "432a39ßu545349ijn4f4-23dsa45"}}, args: args{event: Event{Day: "test3", Week: "test3", Start: specificTime, End: specificTime, Name: "test3", Course: "test3", Prof: "test3", Rooms: "test3", EventType: "test3", UUID: "934mf43r34f-g68h7655tg3"}}, want: false, @@ -99,25 +99,25 @@ func TestEventEquals(t *testing.T) { want bool }{ { - name: "empty events", + name: "event equals empty events", fields: fields{}, args: args{event: Event{}}, want: true, }, { - name: "one empty one not", + name: "event equals one empty one not", fields: fields{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}, args: args{event: Event{}}, want: false, }, { - name: "one event", + name: "event equals one event", fields: fields{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}, args: args{event: Event{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}}, want: true, }, { - name: "two events", + name: "event equals two events", fields: fields{Day: "test", Week: "test", Start: specificTime, End: specificTime, Name: "test", Course: "test", Prof: "test", Rooms: "test", EventType: "test"}, args: args{event: Event{Day: "test2", Week: "test2", Start: specificTime, End: specificTime, Name: "test2", Course: "test2", Prof: "test2", Rooms: "test2", EventType: "test2"}}, want: false, @@ -172,22 +172,22 @@ func TestEventAnonymizeEvent(t *testing.T) { want AnonymizedEventDTO }{ { - name: "empty event", + name: "event anonymize empty event", fields: fields{}, want: AnonymizedEventDTO{Day: "", Week: "", Start: types.DateTime{}, End: types.DateTime{}, Rooms: "", Free: false}, }, { - name: "one event", + name: "event anonymize one event", fields: fields{Name: "Event", Day: "test", Week: "test", Rooms: "test"}, want: AnonymizedEventDTO{Day: "test", Week: "test", Start: types.DateTime{}, End: types.DateTime{}, Rooms: "test", Free: false}, }, { - name: "one event with free", + name: "event anonymize one event with free", fields: fields{Name: "Räume zur freien Verfügung", Day: "test", Week: "test", Rooms: "test", Course: "test"}, want: AnonymizedEventDTO{Day: "test", Week: "test", Start: types.DateTime{}, End: types.DateTime{}, Rooms: "test", Free: true}, }, { - name: "another free event", + name: "event anonymize another free event", fields: fields{Name: "Zur freien Verfügung", Day: "Montag", Week: "5", Start: types.DateTime{}, End: types.DateTime{}, Rooms: "TR_A1.28-S", Course: "42INM-3"}, want: AnonymizedEventDTO{Day: "Montag", Week: "5", Start: types.DateTime{}, End: types.DateTime{}, Rooms: "TR_A1.28-S", Free: true}, }, @@ -242,12 +242,12 @@ func TestEventGetName(t *testing.T) { want string }{ { - name: "empty event", + name: "event get name - empty event", fields: fields{}, want: "", }, { - name: "one event", + name: "event get name - one event", fields: fields{Name: "Event"}, want: "Event", }, @@ -464,7 +464,7 @@ func TestEventsContains1(t *testing.T) { want bool }{ { - name: "empty events", + name: "event contains - empty events", m: Events{}, args: args{event: Event{}}, want: false, diff --git a/services/data-manager/model/feedModel_test.go b/services/data-manager/model/feedModel_test.go index 111d8d1..f2de61b 100644 --- a/services/data-manager/model/feedModel_test.go +++ b/services/data-manager/model/feedModel_test.go @@ -6,7 +6,7 @@ import ( "testing" ) -func TestFeed_SetModules(t *testing.T) { +func TestFeedSetModules(t *testing.T) { type fields struct { Modules string Retrieved types.DateTime diff --git a/services/data-manager/model/moduleModel_test.go b/services/data-manager/model/moduleModel_test.go index b2ebe5d..b0dc7a8 100644 --- a/services/data-manager/model/moduleModel_test.go +++ b/services/data-manager/model/moduleModel_test.go @@ -2,7 +2,7 @@ package model import "testing" -func TestModuleDTO_GetName(t *testing.T) { +func TestModuleDTOGetName(t *testing.T) { type fields struct { UUID string Name string @@ -41,7 +41,7 @@ func TestModuleDTO_GetName(t *testing.T) { } } -func TestModuleDTO_SetName(t *testing.T) { +func TestModuleDTOSetName(t *testing.T) { type fields struct { UUID string Name string @@ -83,7 +83,7 @@ func TestModuleDTO_SetName(t *testing.T) { } } -func TestModule_SetName(t *testing.T) { +func TestModuleSetName(t *testing.T) { type fields struct { UUID string Name string diff --git a/services/data-manager/model/serviceModel/serviceModel.go b/services/data-manager/model/serviceModel/serviceModel.go new file mode 100644 index 0000000..8e2fe69 --- /dev/null +++ b/services/data-manager/model/serviceModel/serviceModel.go @@ -0,0 +1,12 @@ +package serviceModel + +import ( + "github.com/pocketbase/pocketbase" + "htwkalender/data-manager/service/events" +) + +type Service struct { + App *pocketbase.PocketBase + EventService events.EventService + CourseService events.CourseService +} diff --git a/services/data-manager/service/addRoute.go b/services/data-manager/service/addRoute.go index 8dadd40..333b287 100644 --- a/services/data-manager/service/addRoute.go +++ b/services/data-manager/service/addRoute.go @@ -17,8 +17,8 @@ package service import ( + "htwkalender/data-manager/model/serviceModel" "htwkalender/data-manager/service/course" - "htwkalender/data-manager/service/events" "htwkalender/data-manager/service/fetch/sport" v1 "htwkalender/data-manager/service/fetch/v1" v2 "htwkalender/data-manager/service/fetch/v2" @@ -28,19 +28,18 @@ import ( "net/http" "github.com/labstack/echo/v5" - "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/apis" "github.com/pocketbase/pocketbase/core" ) -func AddRoutes(app *pocketbase.PocketBase) { +func AddRoutes(services serviceModel.Service) { - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/fetch/events", Handler: func(c echo.Context) error { - savedEvents, err := v2.ParseEventsFromRemote(app) + savedEvents, err := v2.ParseEventsFromRemote(services.App) if err != nil { slog.Error("Failed to parse events from remote: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to parse events from remote") @@ -49,7 +48,7 @@ func AddRoutes(app *pocketbase.PocketBase) { } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), apis.RequireAdminAuth(), }, }) @@ -59,16 +58,16 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/fetch/daily/events", Handler: func(c echo.Context) error { - course.UpdateCourse(app) + course.UpdateCourse(services) return c.JSON(http.StatusOK, "Daily events fetched") }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), apis.RequireAdminAuth(), }, }) @@ -78,19 +77,19 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/fetch/groups", Handler: func(c echo.Context) error { - groups, err := v1.FetchSeminarGroups(app) + groups, err := v1.FetchSeminarGroups(services.App) if err != nil { return c.JSON(http.StatusBadRequest, "Failed to fetch seminar groups") } return c.JSON(http.StatusOK, groups) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), apis.RequireAdminAuth(), }, }) @@ -100,20 +99,20 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/fetch/sports", Handler: func(c echo.Context) error { - sportEvents, err := sport.FetchAndUpdateSportEvents(app) + sportEvents, err := sport.FetchAndUpdateSportEvents(services.App) if err != nil { return c.JSON(http.StatusBadRequest, "Failed to fetch sport events") } return c.JSON(http.StatusOK, sportEvents) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), apis.RequireAdminAuth(), }, }) @@ -123,19 +122,19 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodDelete, Path: "/api/modules", Handler: func(c echo.Context) error { - err := events.DeleteAllEvents(app) + err := services.EventService.DeleteAllEvents() if err != nil { return c.JSON(http.StatusBadRequest, "Failed to delete events") } return c.JSON(http.StatusOK, "Events deleted") }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), apis.RequireAdminAuth(), }, }) @@ -145,19 +144,19 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/rooms", Handler: func(c echo.Context) error { - rooms, err := room.GetRooms(app) + rooms, err := room.GetRooms(services.App) if err != nil { return c.JSON(http.StatusBadRequest, "Failed to get rooms") } return c.JSON(http.StatusOK, rooms) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -167,14 +166,14 @@ func AddRoutes(app *pocketbase.PocketBase) { }) // API Endpoint to get all events for a specific room on a specific day - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/schedule/day", Handler: func(c echo.Context) error { roomParam := c.QueryParam("room") date := c.QueryParam("date") - roomSchedule, err := room.GetRoomScheduleForDay(app, roomParam, date) + roomSchedule, err := room.GetRoomScheduleForDay(services.App, roomParam, date) if err != nil { slog.Error("Failed to get room schedule for day: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get room schedule for day") @@ -182,7 +181,7 @@ func AddRoutes(app *pocketbase.PocketBase) { return c.JSON(http.StatusOK, roomSchedule) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -192,7 +191,7 @@ func AddRoutes(app *pocketbase.PocketBase) { }) // API Endpoint to create a new iCal feed - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/schedule", @@ -200,7 +199,7 @@ func AddRoutes(app *pocketbase.PocketBase) { roomParam := c.QueryParam("room") to := c.QueryParam("to") from := c.QueryParam("from") - roomSchedule, err := room.GetRoomSchedule(app, roomParam, from, to) + roomSchedule, err := room.GetRoomSchedule(services.App, roomParam, from, to) if err != nil { slog.Error("Failed to get room schedule:", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get room schedule") @@ -208,7 +207,7 @@ func AddRoutes(app *pocketbase.PocketBase) { return c.JSON(http.StatusOK, roomSchedule) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -218,7 +217,7 @@ func AddRoutes(app *pocketbase.PocketBase) { }) // API Endpoint to get all rooms that have no events in a specific time frame - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/rooms/free", @@ -233,7 +232,7 @@ func AddRoutes(app *pocketbase.PocketBase) { slog.Error("Failed to parse time: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to parse time") } - rooms, err := room.GetFreeRooms(app, from, to) + rooms, err := room.GetFreeRooms(services.App, from, to) if err != nil { slog.Error("Failed to get free rooms: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get free rooms") @@ -241,7 +240,7 @@ func AddRoutes(app *pocketbase.PocketBase) { return c.JSON(http.StatusOK, rooms) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -250,15 +249,14 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - addFeedRoutes(app) + addFeedRoutes(services.App) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/course/modules", Handler: func(c echo.Context) error { - modules, err := events.GetModulesForCourseDistinct( - app, + modules, err := services.EventService.GetModulesForCourseDistinct( c.QueryParam("course"), c.QueryParam("semester"), ) @@ -271,7 +269,7 @@ func AddRoutes(app *pocketbase.PocketBase) { } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -280,12 +278,12 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/modules", Handler: func(c echo.Context) error { - modules, err := events.GetAllModulesDistinct(app) + modules, err := services.EventService.GetAllModulesDistinct() if err != nil { slog.Error("Failed to get modules: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get modules") @@ -293,7 +291,7 @@ func AddRoutes(app *pocketbase.PocketBase) { return c.JSON(http.StatusOK, modules) }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -302,13 +300,13 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/module", Handler: func(c echo.Context) error { requestModule := c.QueryParam("uuid") - module, err := events.GetModuleByUUID(app, requestModule) + module, err := services.EventService.GetModuleByUUID(requestModule) if err != nil { slog.Error("Failed to get module: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get module") @@ -317,7 +315,7 @@ func AddRoutes(app *pocketbase.PocketBase) { } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -326,22 +324,26 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/courses", Handler: func(c echo.Context) error { semester := c.QueryParam("semester") if semester == "" { - courses := events.GetAllCourses(app) + courses := services.CourseService.GetAllCourses() return c.JSON(200, courses) } else { - courses := events.GetAllCoursesForSemester(app, semester) - return c.JSON(200, courses) + seminarGroups := services.CourseService.GetAllCoursesForSemester(semester) + courseStringList := make([]string, 0) + for _, seminarGroup := range seminarGroups { + courseStringList = append(courseStringList, seminarGroup.Course) + } + return c.JSON(200, courseStringList) } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -351,14 +353,13 @@ func AddRoutes(app *pocketbase.PocketBase) { }) // api end point to get all courses for a specific semester with courses that have events - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/courses/events", Handler: func(c echo.Context) error { semester := c.QueryParam("semester") - courses, err := events.GetAllCoursesForSemesterWithEvents(app, semester) - + courses, err := services.CourseService.GetAllCoursesForSemesterWithEvents(semester) if err != nil { slog.Error("Failed to get courses for semester with events: ", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get courses for semester with events") @@ -367,7 +368,7 @@ func AddRoutes(app *pocketbase.PocketBase) { } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -377,12 +378,12 @@ func AddRoutes(app *pocketbase.PocketBase) { }) // API Endpoint to get all eventTypes from the database distinct - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodGet, Path: "/api/events/types", Handler: func(c echo.Context) error { - eventTypes, err := events.GetEventTypes(app) + eventTypes, err := services.EventService.GetEventTypes() if err != nil { slog.Error("Failed to get event types", "error", err) return c.JSON(http.StatusBadRequest, "Failed to get event types") @@ -391,7 +392,7 @@ func AddRoutes(app *pocketbase.PocketBase) { } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), }, }) if err != nil { @@ -400,13 +401,12 @@ func AddRoutes(app *pocketbase.PocketBase) { return nil }) - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { _, err := e.Router.AddRoute(echo.Route{ Method: http.MethodDelete, Path: "/api/events", Handler: func(c echo.Context) error { - err := events.DeleteAllEventsByCourseAndSemester( - app, + err := services.EventService.DeleteAllEventsByCourseAndSemester( c.QueryParam("course"), c.QueryParam("semester"), ) @@ -418,7 +418,7 @@ func AddRoutes(app *pocketbase.PocketBase) { } }, Middlewares: []echo.MiddlewareFunc{ - apis.ActivityLogger(app), + apis.ActivityLogger(services.App), apis.RequireAdminAuth(), }, }) diff --git a/services/data-manager/service/addSchedule.go b/services/data-manager/service/addSchedule.go index c24f2e1..da0bac4 100644 --- a/services/data-manager/service/addSchedule.go +++ b/services/data-manager/service/addSchedule.go @@ -17,9 +17,9 @@ package service import ( - "github.com/pocketbase/pocketbase" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/cron" + "htwkalender/data-manager/model/serviceModel" "htwkalender/data-manager/service/course" "htwkalender/data-manager/service/feed" "htwkalender/data-manager/service/fetch/sport" @@ -30,9 +30,9 @@ import ( "strconv" ) -func AddSchedules(app *pocketbase.PocketBase) { +func AddSchedules(services serviceModel.Service) { - app.OnBeforeServe().Add(func(e *core.ServeEvent) error { + services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error { scheduler := cron.New() // !! IMPORTANT !! CRON is based on UTC time zone so in Germany it is UTC+2 in summer and UTC+1 in winter @@ -40,7 +40,7 @@ func AddSchedules(app *pocketbase.PocketBase) { // Every sunday at 10pm update all courses (5 segments - minute, hour, day, month, weekday) "0 22 * * 0" scheduler.MustAdd("updateCourses", "0 22 * * 0", func() { slog.Info("Started updating courses schedule") - groups, err := v1.FetchSeminarGroups(app) + groups, err := v1.FetchSeminarGroups(services.App) if err != nil { slog.Warn("Failed to fetch seminar groups: ", "error", err) } @@ -51,20 +51,20 @@ func AddSchedules(app *pocketbase.PocketBase) { // In Germany it is 7am and 7pm, syllabus gets updated twice a day at German 5:00 Uhr and 17:00 Uhr scheduler.MustAdd("updateEventsByCourse", "0 5,17 * * *", func() { slog.Info("Started updating courses schedule") - course.UpdateCourse(app) + course.UpdateCourse(services) }) // Every sunday at 1am clean all courses (5 segments - minute, hour, day, month, weekday) "0 3 * * 0" scheduler.MustAdd("cleanFeeds", "0 1 * * 0", func() { // clean feeds older than 6 months slog.Info("Started cleaning feeds schedule") - feed.ClearFeeds(app.Dao(), 6, time.RealClock{}) + feed.ClearFeeds(services.App.Dao(), 6, time.RealClock{}) }) // Every sunday at 3am fetch all sport events (5 segments - minute, hour, day, month, weekday) "0 2 * * 0" scheduler.MustAdd("fetchSportEvents", "0 3 * * 0", func() { slog.Info("Started fetching sport events schedule") - sportEvents, err := sport.FetchAndUpdateSportEvents(app) + sportEvents, err := sport.FetchAndUpdateSportEvents(services.App) if err != nil { slog.Error("Failed to fetch and save sport events:", "error", err) } @@ -73,7 +73,7 @@ func AddSchedules(app *pocketbase.PocketBase) { //fetch all events for semester and delete from remote this should be done every sunday at 2am scheduler.MustAdd("fetchEvents", "0 22 * * 6", func() { - savedEvents, err := v2.FetchAllEventsAndSave(app, time.RealClock{}) + savedEvents, err := v2.FetchAllEventsAndSave(services.App, time.RealClock{}) if err != nil { slog.Error("Failed to fetch and save events: ", "error", err) } else { diff --git a/services/data-manager/service/course/courseFunctions.go b/services/data-manager/service/course/courseFunctions.go index 0612d97..9e761b3 100644 --- a/services/data-manager/service/course/courseFunctions.go +++ b/services/data-manager/service/course/courseFunctions.go @@ -17,17 +17,26 @@ package course import ( - "github.com/pocketbase/pocketbase" - "htwkalender/data-manager/service/events" + "htwkalender/data-manager/model" + "htwkalender/data-manager/model/serviceModel" + "htwkalender/data-manager/service/functions" + "htwkalender/data-manager/service/functions/time" "log/slog" ) -func UpdateCourse(app *pocketbase.PocketBase) { - courses := events.GetAllCourses(app) - for _, course := range courses { - _, err := events.UpdateModulesForCourse(app, course) +func UpdateCourse(service serviceModel.Service) { + currentSemesters := functions.CalculateSemesterList(time.RealClock{}) + + var seminarGroups []model.SeminarGroup + + for _, semester := range currentSemesters { + seminarGroups = append(seminarGroups, service.CourseService.GetAllCoursesForSemester(semester)...) + } + + for _, seminarGroup := range seminarGroups { + _, err := service.EventService.UpdateModulesForCourse(seminarGroup) if err != nil { - slog.Warn("Update Course: "+course+" failed:", "error", err) + slog.Warn("Update Course: "+seminarGroup.Course+" failed:", "error", err) } } } diff --git a/services/data-manager/service/course/courseFunctions_test.go b/services/data-manager/service/course/courseFunctions_test.go new file mode 100644 index 0000000..fb0fa9f --- /dev/null +++ b/services/data-manager/service/course/courseFunctions_test.go @@ -0,0 +1,97 @@ +package course + +import ( + "bytes" + "fmt" + "github.com/stretchr/testify/require" + "htwkalender/data-manager/model" + "htwkalender/data-manager/model/serviceModel" + "htwkalender/data-manager/service/events/mock" + "log/slog" + "regexp" + "testing" +) + +// CustomWriter is a custom writer to capture log output +type CustomWriter struct { + Buffer bytes.Buffer +} + +func (w *CustomWriter) Write(p []byte) (n int, err error) { + return w.Buffer.Write(p) +} + +func TestUpdateCourse(t *testing.T) { + // Create mock services + mockCourseService := new(mock.MockCourseService) + mockEventService := new(mock.MockEventService) + + events := model.Events{} + + // Set up expectations + mockCourseService.On("GetAllCoursesForSemester", "ss").Return([]model.SeminarGroup{{Course: "Course1", Semester: ""}, {Course: "Course2", Semester: ""}}) + mockEventService.On("UpdateModulesForCourse", model.SeminarGroup{Course: "Course1", Semester: ""}).Return(events, nil) + mockEventService.On("UpdateModulesForCourse", model.SeminarGroup{Course: "Course2", Semester: ""}).Return(events, nil) + + // Inject mocks into the UpdateCourse function + service := serviceModel.Service{ + CourseService: mockCourseService, + EventService: mockEventService, + App: nil, + } + UpdateCourse(service) + + // Assert that the expectations were met + mockCourseService.AssertExpectations(t) + mockEventService.AssertExpectations(t) + + // Assert that the UpdateCourse function was called twice + mockCourseService.AssertNumberOfCalls(t, "GetAllCoursesForSemester", 1) + mockEventService.AssertNumberOfCalls(t, "UpdateModulesForCourse", 2) + + // Assert that the UpdateCourse function was called with the correct arguments + mockEventService.AssertCalled(t, "UpdateModulesForCourse", model.SeminarGroup{Course: "Course1", Semester: ""}) + mockEventService.AssertCalled(t, "UpdateModulesForCourse", model.SeminarGroup{Course: "Course2", Semester: ""}) +} + +func TestUpdateCourseErr(t *testing.T) { + // Create mock services + mockCourseService := new(mock.MockCourseService) + mockEventService := new(mock.MockEventService) + + events := model.Events{} + + // Set up expectations + mockCourseService.On("GetAllCoursesForSemester", "ss").Return([]model.SeminarGroup{{Course: "Course1", Semester: ""}, {Course: "Course2", Semester: ""}}) + mockEventService.On("UpdateModulesForCourse", model.SeminarGroup{Course: "Course1", Semester: ""}).Return(events, fmt.Errorf("error")) + mockEventService.On("UpdateModulesForCourse", model.SeminarGroup{Course: "Course2", Semester: ""}).Return(events, fmt.Errorf("error")) + + // Create a custom writer to capture log output + customWriter := &CustomWriter{} + originalLogger := slog.Default() + defer slog.SetDefault(originalLogger) + + // Replace the default logger with a custom logger + slog.SetDefault(slog.New(slog.NewTextHandler(customWriter, nil))) + + // Inject mocks into the UpdateCourse function + service := serviceModel.Service{ + CourseService: mockCourseService, + EventService: mockEventService, + App: nil, + } + UpdateCourse(service) + + // Assert that the expectations were met + mockCourseService.AssertExpectations(t) + mockEventService.AssertExpectations(t) + + // Assert that the UpdateCourse function was called twice + mockCourseService.AssertNumberOfCalls(t, "GetAllCoursesForSemester", 1) + mockEventService.AssertNumberOfCalls(t, "UpdateModulesForCourse", 2) + + // Check the captured log output for the expected messages + logOutput := customWriter.Buffer.String() + require.Regexp(t, regexp.MustCompile(`Update Course: Course1 failed:.*error`), logOutput) + require.Regexp(t, regexp.MustCompile(`Update Course: Course2 failed:.*error`), logOutput) +} diff --git a/services/data-manager/service/db/dbGroups.go b/services/data-manager/service/db/dbGroups.go index f4776c3..5e70e21 100644 --- a/services/data-manager/service/db/dbGroups.go +++ b/services/data-manager/service/db/dbGroups.go @@ -24,56 +24,68 @@ import ( "log/slog" ) -func SaveGroups(seminarGroup []model.SeminarGroup, collection *models.Collection, app *pocketbase.PocketBase) ([]*models.Record, error) { - var savedRecords []*models.Record - var tobeSavedGroups []model.SeminarGroup - var insertRecords []*models.Record - - for _, group := range seminarGroup { - dbGroup, err := FindGroupByCourseAndSemester(group.Course, group.Semester, app) - - if dbGroup == nil && err.Error() == "sql: no rows in result set" { - tobeSavedGroups = append(tobeSavedGroups, group) - } else if err != nil { - return nil, err - } - } - - // create record for each group that's not already in the database - for _, group := range tobeSavedGroups { - record := models.NewRecord(collection) - record.Set("university", group.University) - record.Set("shortcut", group.GroupShortcut) - record.Set("groupId", group.GroupId) - record.Set("course", group.Course) - record.Set("faculty", group.Faculty) - record.Set("facultyId", group.FacultyId) - record.Set("semester", group.Semester) - insertRecords = append(insertRecords, record) - } - - // save all records - for _, record := range insertRecords { - if record != nil { - err := app.Dao().SaveRecord(record) - if err == nil { - savedRecords = append(savedRecords, record) - } else { - return nil, err - } - } - } - - return savedRecords, nil +type SeminarGroup struct { + University string `db:"university" json:"university"` + GroupShortcut string `db:"shortcut" json:"shortcut"` + GroupId string `db:"groupId" json:"groupId"` + Course string `db:"course" json:"course"` + Faculty string `db:"faculty" json:"faculty"` + FacultyId string `db:"facultyId" json:"facultyId"` + Semester string `db:"semester" json:"semester"` + models.BaseModel } -func FindGroupByCourseAndSemester(course string, semester string, app *pocketbase.PocketBase) (*model.SeminarGroup, error) { - var group model.SeminarGroup - err := app.Dao().DB().Select("*").From("groups").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).One(&group) +func (s *SeminarGroup) TableName() string { + return "groups" +} + +// UniqueKey Should be same as unique constraint in the database +func (s *SeminarGroup) UniqueKey() string { + return s.Course + s.Semester +} + +func (s *SeminarGroup) toSeminarGroupModel() model.SeminarGroup { + return model.SeminarGroup{ + University: s.University, + GroupShortcut: s.GroupShortcut, + GroupId: s.GroupId, + Course: s.Course, + Faculty: s.Faculty, + FacultyId: s.FacultyId, + Semester: s.Semester, + } +} + +func (s *SeminarGroups) toSeminarGroupModels() []model.SeminarGroup { + var seminarGroups []model.SeminarGroup + for _, group := range *s { + seminarGroups = append(seminarGroups, group.toSeminarGroupModel()) + } + return seminarGroups +} + +type SeminarGroups []*SeminarGroup + +func SaveGroups(seminarGroups SeminarGroups, app *pocketbase.PocketBase) (SeminarGroups, error) { + + // delete all groups from the database + execute, err := app.Dao().DB().Delete("groups", dbx.NewExp("1 = 1")).Execute() if err != nil { return nil, err } - return &group, nil + rowCount, _ := execute.RowsAffected() + + savedGroups := SeminarGroups{} + for _, group := range seminarGroups { + saveErr := app.Dao().Save(group) + if saveErr != nil { + return nil, saveErr + } + savedGroups = append(savedGroups, group) + } + slog.Info("Saved all groups to the database", "insert", len(savedGroups), "deleted", rowCount) + + return savedGroups, nil } func GetAllCourses(app *pocketbase.PocketBase) []string { @@ -98,26 +110,18 @@ func GetAllCourses(app *pocketbase.PocketBase) []string { return courseArray } -func GetAllCoursesForSemester(app *pocketbase.PocketBase, semester string) []string { +func GetAllCoursesForSemester(app *pocketbase.PocketBase, semester string) []model.SeminarGroup { - var courses []struct { - CourseShortcut string `db:"course" json:"course"` - } + var courses SeminarGroups // get all courses for a specific semester - err := app.Dao().DB().Select("course").From("groups").Where(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).All(&courses) + err := app.Dao().DB().Select("*").From("groups").Where(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).All(&courses) if err != nil { slog.Error("Error while getting groups from database: ", "error", err) - return []string{} + return nil } - var courseArray []string - - for _, course := range courses { - courseArray = append(courseArray, course.CourseShortcut) - } - - return courseArray + return courses.toSeminarGroupModels() } diff --git a/services/data-manager/service/events/courseService.go b/services/data-manager/service/events/courseService.go index 389a428..65cc1a8 100644 --- a/services/data-manager/service/events/courseService.go +++ b/services/data-manager/service/events/courseService.go @@ -18,36 +18,56 @@ package events import ( "github.com/pocketbase/pocketbase" + "htwkalender/data-manager/model" "htwkalender/data-manager/service/db" "htwkalender/data-manager/service/functions" ) -func GetAllCourses(app *pocketbase.PocketBase) []string { - return db.GetAllCourses(app) +// CourseService defines the methods to be implemented +type CourseService interface { + GetAllCourses() []string + GetAllCoursesForSemester(semester string) []model.SeminarGroup + GetAllCoursesForSemesterWithEvents(semester string) ([]string, error) } -func GetAllCoursesForSemester(app *pocketbase.PocketBase, semester string) []string { - return db.GetAllCoursesForSemester(app, semester) +// PocketBaseCourseService is a struct that implements the CourseService interface +type PocketBaseCourseService struct { + app *pocketbase.PocketBase } -func GetAllCoursesForSemesterWithEvents(app *pocketbase.PocketBase, semester string) ([]string, error) { - courses, err := db.GetAllCoursesForSemesterWithEvents(app, semester) +// NewPocketBaseCourseService creates a new PocketBaseCourseService +func NewPocketBaseCourseService(app *pocketbase.PocketBase) *PocketBaseCourseService { + return &PocketBaseCourseService{app: app} +} + +// GetAllCourses returns all courses +func (s *PocketBaseCourseService) GetAllCourses() []string { + return db.GetAllCourses(s.app) +} + +// GetAllCoursesForSemester returns all courses for a specific semester +func (s *PocketBaseCourseService) GetAllCoursesForSemester(semester string) []model.SeminarGroup { + return db.GetAllCoursesForSemester(s.app, semester) +} + +// GetAllCoursesForSemesterWithEvents returns all courses for a specific semester with events +func (s *PocketBaseCourseService) GetAllCoursesForSemesterWithEvents(semester string) ([]string, error) { + courses, err := db.GetAllCoursesForSemesterWithEvents(s.app, semester) if err != nil { return nil, err - } else { - // remove empty courses like " " or "" - courses = removeEmptyCourses(courses) - return courses, nil } + // remove empty courses like " " or "" + courses = removeEmptyCourses(courses) + return courses, nil } // removeEmptyCourses removes empty courses from the list of courses func removeEmptyCourses(courses []string) []string { var filteredCourses []string - for index, course := range courses { + for _, course := range courses { if !functions.OnlyWhitespace(course) || len(course) != 0 { - filteredCourses = append(filteredCourses, courses[index]) + filteredCourses = append(filteredCourses, course) } } return filteredCourses diff --git a/services/data-manager/service/events/eventService.go b/services/data-manager/service/events/eventService.go index afa318a..f0a3534 100644 --- a/services/data-manager/service/events/eventService.go +++ b/services/data-manager/service/events/eventService.go @@ -26,9 +26,31 @@ import ( "strconv" ) -func GetModulesForCourseDistinct(app *pocketbase.PocketBase, course string, semester string) (model.Events, error) { +type EventService interface { + GetModulesForCourseDistinct(course string, semester string) (model.Events, error) + GetAllModulesDistinct() ([]model.ModuleDTO, error) + GetModuleByUUID(uuid string) (model.Module, error) + DeleteAllEventsByCourseAndSemester(course string, semester string) error + DeleteAllEvents() error + UpdateModulesForCourse(seminarGroup model.SeminarGroup) (model.Events, error) + GetEventTypes() ([]string, error) +} - modules, err := db.GetAllModulesForCourse(app, course, semester) +type Named interface { + GetName() string + SetName(name string) +} + +type PocketBaseEventService struct { + app *pocketbase.PocketBase +} + +func NewPocketBaseEventService(app *pocketbase.PocketBase) *PocketBaseEventService { + return &PocketBaseEventService{app: app} +} + +func (s *PocketBaseEventService) GetModulesForCourseDistinct(course string, semester string) (model.Events, error) { + modules, err := db.GetAllModulesForCourse(s.app, course, semester) // Convert the []model.Module to []Named var namedEvents []Named @@ -40,11 +62,6 @@ func GetModulesForCourseDistinct(app *pocketbase.PocketBase, course string, seme return modules, err } -type Named interface { - GetName() string - SetName(name string) -} - // replaceEmptyEntry replaces an empty entry in a module with a replacement string // If the module is not empty, nothing happens func replaceEmptyEntry(namedList []Named, replacement string) { @@ -57,8 +74,8 @@ func replaceEmptyEntry(namedList []Named, replacement string) { // GetAllModulesDistinct returns all modules distinct by name and course from the database // That means you get all modules with duplicates if they have different courses -func GetAllModulesDistinct(app *pocketbase.PocketBase) ([]model.ModuleDTO, error) { - modules, err := db.GetAllModulesDistinctByNameAndCourse(app) +func (s *PocketBaseEventService) GetAllModulesDistinct() ([]model.ModuleDTO, error) { + modules, err := db.GetAllModulesDistinctByNameAndCourse(s.app) if err != nil { return nil, err } @@ -70,13 +87,13 @@ func GetAllModulesDistinct(app *pocketbase.PocketBase) ([]model.ModuleDTO, error return modules, nil } -func GetModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, error) { - module, findModuleErr := db.FindModuleByUUID(app, uuid) +func (s *PocketBaseEventService) GetModuleByUUID(uuid string) (model.Module, error) { + module, findModuleErr := db.FindModuleByUUID(s.app, uuid) if findModuleErr != nil { return model.Module{}, findModuleErr } - events, findEventsError := db.FindAllEventsByModule(app, module) + events, findEventsError := db.FindAllEventsByModule(s.app, module) if findEventsError != nil || len(events) == 0 { return model.Module{}, findEventsError } else { @@ -94,8 +111,8 @@ func GetModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, err // DeleteAllEventsByCourseAndSemester deletes all events for a course and a semester // If the deletion was successful, nil is returned // If the deletion was not successful, an error is returned -func DeleteAllEventsByCourseAndSemester(app *pocketbase.PocketBase, course string, semester string) error { - err := db.DeleteAllEventsByCourse(app.Dao(), course, semester) +func (s *PocketBaseEventService) DeleteAllEventsByCourseAndSemester(course string, semester string) error { + err := db.DeleteAllEventsByCourse(s.app.Dao(), course, semester) if err != nil { return err } else { @@ -103,8 +120,8 @@ func DeleteAllEventsByCourseAndSemester(app *pocketbase.PocketBase, course strin } } -func DeleteAllEvents(app *pocketbase.PocketBase) error { - err := db.DeleteAllEvents(app) +func (s *PocketBaseEventService) DeleteAllEvents() error { + err := db.DeleteAllEvents(s.app) if err != nil { return err } else { @@ -120,14 +137,12 @@ func DeleteAllEvents(app *pocketbase.PocketBase) error { // 3. Save all events for the course and the semester // If the update was successful, nil is returned // If the update was not successful, an error is returned -func UpdateModulesForCourse(app *pocketbase.PocketBase, course string) (model.Events, error) { +func (s *PocketBaseEventService) UpdateModulesForCourse(seminarGroup model.SeminarGroup) (model.Events, error) { - seminarGroup, err := v1.GetSeminarGroupEventsFromHTML(course) + seminarGroup, err := v1.FetchAndParse(seminarGroup.Semester, seminarGroup.Course) if err != nil { return nil, err } - - seminarGroup = v1.ClearEmptySeminarGroups(seminarGroup) seminarGroup = v1.ReplaceEmptyEventNames(seminarGroup) //check if events in the seminarGroups Events are already in the database @@ -136,14 +151,14 @@ func UpdateModulesForCourse(app *pocketbase.PocketBase, course string) (model.Ev //if there are no events in the database, save the new events //get all events for the course and the semester - dbEvents, err := db.GetAllEventsForCourse(app, course) + dbEvents, err := db.GetAllEventsForCourse(s.app, seminarGroup.Course) if err != nil { return nil, err } //if there are no events in the database, save the new events if len(dbEvents) == 0 { - events, dbError := db.SaveSeminarGroupEvents(seminarGroup, app) + events, dbError := db.SaveSeminarGroupEvents(seminarGroup, s.app) if dbError != nil { return nil, dbError } @@ -156,37 +171,37 @@ func UpdateModulesForCourse(app *pocketbase.PocketBase, course string) (model.Ev // check which events are not already in the database and need to be inserted/saved for _, event := range seminarGroup.Events { - if !ContainsEvent(dbEvents, event) { + if !containsEvent(dbEvents, event) { insertList = append(insertList, event) } } // check which events are in the database but not in the seminarGroup and need to be deleted for _, dbEvent := range dbEvents { - if !ContainsEvent(seminarGroup.Events, dbEvent) { + if !containsEvent(seminarGroup.Events, dbEvent) { deleteList = append(deleteList, dbEvent) } } // delete all events that are in the deleteList - err = db.DeleteEvents(deleteList, app) + err = db.DeleteEvents(deleteList, s.app) if err != nil { slog.Error("Failed to delete events:", "error", err) return nil, err } // save all events that are in the insertList - savedEvents, err := db.SaveEvents(insertList, app.Dao()) + savedEvents, err := db.SaveEvents(insertList, s.app.Dao()) if err != nil { slog.Error("Failed to save events: ", "error", err) return nil, err } - slog.Info("Course: " + course + " - Event changes: " + strconv.FormatInt(int64(len(insertList)), 10) + " new events, " + strconv.FormatInt(int64(len(deleteList)), 10) + " deleted events") + slog.Info("Course: " + seminarGroup.Course + " - Event changes: " + strconv.FormatInt(int64(len(insertList)), 10) + " new events, " + strconv.FormatInt(int64(len(deleteList)), 10) + " deleted events") return savedEvents, nil } -func ContainsEvent(events model.Events, event model.Event) bool { +func containsEvent(events model.Events, event model.Event) bool { for _, e := range events { if e.Name == event.Name && e.Prof == event.Prof && @@ -201,8 +216,8 @@ func ContainsEvent(events model.Events, event model.Event) bool { return false } -func GetEventTypes(app *pocketbase.PocketBase) ([]string, error) { - dbEventTypes, err := db.GetAllEventTypes(app) +func (s *PocketBaseEventService) GetEventTypes() ([]string, error) { + dbEventTypes, err := db.GetAllEventTypes(s.app) if err != nil { return nil, err } diff --git a/services/data-manager/service/events/eventService_test.go b/services/data-manager/service/events/eventService_test.go index e4f7b68..d64d58c 100644 --- a/services/data-manager/service/events/eventService_test.go +++ b/services/data-manager/service/events/eventService_test.go @@ -50,8 +50,8 @@ func TestContainsEvent(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := ContainsEvent(tt.args.events, tt.args.event); got != tt.want { - t.Errorf("ContainsEvent() = %v, want %v", got, tt.want) + if got := containsEvent(tt.args.events, tt.args.event); got != tt.want { + t.Errorf("containsEvent() = %v, want %v", got, tt.want) } }) } diff --git a/services/data-manager/service/events/mock/courseMock.go b/services/data-manager/service/events/mock/courseMock.go new file mode 100644 index 0000000..80aabce --- /dev/null +++ b/services/data-manager/service/events/mock/courseMock.go @@ -0,0 +1,66 @@ +package mock + +import ( + "github.com/stretchr/testify/mock" + "htwkalender/data-manager/model" +) + +// MockCourseService is a mock implementation of the CourseService interface +type MockCourseService struct { + mock.Mock +} + +func (m *MockCourseService) GetAllCourses() []string { + args := m.Called() + return args.Get(0).([]string) +} + +func (m *MockCourseService) GetAllCoursesForSemester(semester string) []model.SeminarGroup { + args := m.Called(semester) + return args.Get(0).([]model.SeminarGroup) +} + +func (m *MockCourseService) GetAllCoursesForSemesterWithEvents(semester string) ([]string, error) { + args := m.Called(semester) + return args.Get(0).([]string), args.Error(1) +} + +// MockEventService is a mock implementation of the EventService interface +type MockEventService struct { + mock.Mock +} + +func (m *MockEventService) GetModulesForCourseDistinct(course string, semester string) (model.Events, error) { + args := m.Called(course, semester) + return args.Get(0).(model.Events), args.Error(1) +} + +func (m *MockEventService) GetAllModulesDistinct() ([]model.ModuleDTO, error) { + args := m.Called() + return args.Get(0).([]model.ModuleDTO), args.Error(1) +} + +func (m *MockEventService) GetModuleByUUID(uuid string) (model.Module, error) { + args := m.Called(uuid) + return args.Get(0).(model.Module), args.Error(1) +} + +func (m *MockEventService) DeleteAllEventsByCourseAndSemester(course string, semester string) error { + args := m.Called(course, semester) + return args.Error(0) +} + +func (m *MockEventService) DeleteAllEvents() error { + args := m.Called() + return args.Error(0) +} + +func (m *MockEventService) UpdateModulesForCourse(seminarGroup model.SeminarGroup) (model.Events, error) { + args := m.Called(seminarGroup) + return args.Get(0).(model.Events), args.Error(1) +} + +func (m *MockEventService) GetEventTypes() ([]string, error) { + args := m.Called() + return args.Get(0).([]string), args.Error(1) +} diff --git a/services/data-manager/service/fetch/v1/fetchSeminarEventService.go b/services/data-manager/service/fetch/v1/fetchSeminarEventService.go index e2a8780..4a02776 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarEventService.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarEventService.go @@ -41,16 +41,12 @@ func ReplaceEmptyEventNames(group model.SeminarGroup) model.SeminarGroup { return group } -func ClearEmptySeminarGroups(seminarGroup model.SeminarGroup) model.SeminarGroup { - var newSeminarGroup = model.SeminarGroup{} - - if len(seminarGroup.Events) > 0 && seminarGroup.Course != "" { - newSeminarGroup = seminarGroup - } - return newSeminarGroup -} - func fetchHTMLFromURL(semester, seminarGroupLabel string) (string, error) { + // check that semester and seminarGroupLabel are not empty + if semester == "" || seminarGroupLabel == "" { + return "", fmt.Errorf("semester or seminarGroupLabel is empty") + } + url := "https://stundenplan.htwk-leipzig.de/" + semester + "/Berichte/Text-Listen;Studenten-Sets;name;" + seminarGroupLabel + "?template=sws_semgrp&weeks=1-65" result, err := fetch.GetHTML(url) if err != nil { @@ -60,22 +56,6 @@ func fetchHTMLFromURL(semester, seminarGroupLabel string) (string, error) { return result, nil } -func GetSeminarGroupEventsFromHTML(seminarGroupLabel string) (model.SeminarGroup, error) { - var seminarGroup [2]model.SeminarGroup - var errSS, errWS error - - currentMonth := time.Now().Month() - - if isSummerSemester(currentMonth) { - seminarGroup[0], errSS = fetchAndParse("ss", seminarGroupLabel) - } - if isWinterSemester(currentMonth) { - seminarGroup[1], errWS = fetchAndParse("ws", seminarGroupLabel) - } - - return checkForSuccessfulFetch(errSS, errWS, seminarGroup) -} - func isSummerSemester(month time.Month) bool { return month >= 3 && month <= 10 } @@ -84,7 +64,7 @@ func isWinterSemester(month time.Month) bool { return month >= 9 || month <= 4 } -func fetchAndParse(season, label string) (model.SeminarGroup, error) { +func FetchAndParse(season, label string) (model.SeminarGroup, error) { result, err := fetchHTMLFromURL(season, label) if err != nil { return model.SeminarGroup{}, err @@ -92,20 +72,6 @@ func fetchAndParse(season, label string) (model.SeminarGroup, error) { return parseSeminarGroup(result), nil } -func checkForSuccessfulFetch(errSS error, errWS error, seminarGroup [2]model.SeminarGroup) (model.SeminarGroup, error) { - switch { - case errSS != nil && errWS != nil: - return model.SeminarGroup{}, errWS - case errSS != nil: - return seminarGroup[1], nil - case errWS != nil: - return seminarGroup[0], nil - default: - seminarGroup[0].Events = append(seminarGroup[0].Events, seminarGroup[1].Events...) - return seminarGroup[0], nil - } -} - func SplitEventType(events []model.Event) ([]model.Event, error) { re, err := regexp.Compile("^([VPS])([wp])$") if err != nil { @@ -135,15 +101,21 @@ func parseSeminarGroup(result string) model.SeminarGroup { eventTables := getEventTables(doc) allDayLabels := getAllDayLabels(doc) - if eventTables == nil || allDayLabels == nil { - return model.SeminarGroup{} - } course := findFirstSpanWithClass(table, "header-2-0-1").FirstChild.Data + semesterString := findFirstSpanWithClass(table, "header-0-2-0").FirstChild.Data + semester, year := extractSemesterAndYear(semesterString) + + if eventTables == nil || allDayLabels == nil { + return model.SeminarGroup{ + University: findFirstSpanWithClass(table, "header-1-0-0").FirstChild.Data, + Course: course, + Events: []model.Event{}, + } + } + eventsWithCombinedWeeks := toEvents(eventTables, allDayLabels, course) splitEventsByWeekVal := splitEventsByWeek(eventsWithCombinedWeeks) events := splitEventsBySingleWeek(splitEventsByWeekVal) - semesterString := findFirstSpanWithClass(table, "header-0-2-0").FirstChild.Data - semester, year := extractSemesterAndYear(semesterString) events = convertWeeksToDates(events, semester, year) events = generateUUIDs(events, course) events, err = SplitEventType(events) diff --git a/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go b/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go index 32cfff0..692847c 100644 --- a/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go +++ b/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go @@ -20,7 +20,6 @@ import ( "encoding/xml" "fmt" "github.com/pocketbase/pocketbase" - "github.com/pocketbase/pocketbase/models" "htwkalender/data-manager/model" "htwkalender/data-manager/service/db" "htwkalender/data-manager/service/functions" @@ -58,8 +57,8 @@ func getSeminarHTML(semester string) (string, error) { } -func FetchSeminarGroups(app *pocketbase.PocketBase) ([]*models.Record, error) { - var groups []model.SeminarGroup +func FetchSeminarGroups(app *pocketbase.PocketBase) (db.SeminarGroups, error) { + var groups db.SeminarGroups semesterString := functions.CalculateSemesterList(time.RealClock{}) var results [2]string @@ -77,26 +76,24 @@ func FetchSeminarGroups(app *pocketbase.PocketBase) ([]*models.Record, error) { // filter duplicates groups = removeDuplicates(groups) - collection, dbError := db.FindCollection(app, "groups") + insertedGroups, dbError := db.SaveGroups(groups, app) if dbError != nil { - slog.Error("Error while searching collection groups", "error", dbError) - return nil, err - } - var insertedGroups []*models.Record - - insertedGroups, dbError = db.SaveGroups(groups, collection, app) - if dbError != nil { - slog.Error("Error while saving groups", "error", dbError) + slog.Error("FetchSeminarGroups", "error", dbError) return nil, err } return insertedGroups, nil } -func removeDuplicates(groups []model.SeminarGroup) []model.SeminarGroup { - var uniqueGroups []model.SeminarGroup +func removeDuplicates(groups db.SeminarGroups) db.SeminarGroups { + uniqueGroups := make(db.SeminarGroups, 0, len(groups)) + seen := make(map[string]struct{}) // Use an empty struct to minimize memory usage + + // unique Identifier is the course and semester for _, group := range groups { - if !contains(uniqueGroups, group) { + key := group.UniqueKey() + if _, exists := seen[key]; !exists { + seen[key] = struct{}{} uniqueGroups = append(uniqueGroups, group) } } @@ -112,7 +109,7 @@ func contains(groups []model.SeminarGroup, group model.SeminarGroup) bool { return false } -func parseSeminarGroups(result string, semester string) []model.SeminarGroup { +func parseSeminarGroups(result string, semester string) db.SeminarGroups { var studium model.Studium err := xml.Unmarshal([]byte(result), &studium) @@ -120,11 +117,11 @@ func parseSeminarGroups(result string, semester string) []model.SeminarGroup { return nil } - var seminarGroups []model.SeminarGroup + var seminarGroups db.SeminarGroups for _, faculty := range studium.Faculty { for _, Studiengang := range faculty.Studiengang { for _, Studienrichtung := range Studiengang.Semgrp { - seminarGroup := model.SeminarGroup{ + seminarGroup := db.SeminarGroup{ University: "HTWK-Leipzig", GroupShortcut: Studiengang.Name, GroupId: Studiengang.ID, @@ -133,7 +130,7 @@ func parseSeminarGroups(result string, semester string) []model.SeminarGroup { FacultyId: faculty.ID, Semester: semester, } - seminarGroups = append(seminarGroups, seminarGroup) + seminarGroups = append(seminarGroups, &seminarGroup) } } } diff --git a/services/go.mod b/services/go.mod index 8d8ee37..a8571b7 100644 --- a/services/go.mod +++ b/services/go.mod @@ -12,6 +12,7 @@ require ( github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 github.com/pocketbase/dbx v1.10.1 github.com/pocketbase/pocketbase v0.22.12 + github.com/stretchr/testify v1.9.0 golang.org/x/net v0.26.0 google.golang.org/grpc v1.63.2 google.golang.org/protobuf v1.34.1 @@ -41,6 +42,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.0 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.28.7 // indirect github.com/aws/smithy-go v1.20.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/disintegration/imaging v1.6.2 // indirect github.com/domodwyer/mailyak/v3 v3.6.2 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -62,10 +64,12 @@ require ( github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.52.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect @@ -83,6 +87,7 @@ require ( golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/api v0.180.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240509183442-62759503f434 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/gc/v3 v3.0.0-20240304020402-f0dba7c97c2b // indirect modernc.org/libc v1.50.5 // indirect modernc.org/mathutil v1.6.0 // indirect diff --git a/services/go.sum b/services/go.sum index 50f1700..a97f4be 100644 --- a/services/go.sum +++ b/services/go.sum @@ -218,6 +218,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -366,6 +368,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=