diff --git a/.eslintrc.json b/.eslintrc.json index 26c9f5aaafb0af24447ebd42fb63ec50fc8d8071..6568f6110a7b555c79d0a0aaa608367860c5af84 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -9,7 +9,7 @@ }, "extends": [ "eslint:recommended", - "plugin:vue/essential", + "plugin:vue/vue3-essential", "@vue/eslint-config-typescript" ], "globals": { diff --git a/app/views/oer/mymaterial/edit.php b/app/views/oer/mymaterial/edit.php index d95b17bc4531538dae5f24e5e9e29a9f33ce33b9..71e010175e03206d1554a150ffcacf6a9ab9f37c 100644 --- a/app/views/oer/mymaterial/edit.php +++ b/app/views/oer/mymaterial/edit.php @@ -36,7 +36,9 @@ </h1> </header> <div class="image" - :style="'background-image: url(' + logo_url + ');' + (!customlogo ? ' background-size: 60% auto;': '')"></div> + :style="{ + backgroundImage: logo_url ? `url(${logo_url})` : null, + backgroundSize: customlogo ? null : '60% auto'}"></div> </article> </label> @@ -198,6 +200,7 @@ searchtype="<?= htmlReady($tagsearch) ?>" v-model="tags[index]" :autocomplete="true" + :keep-value="true" ></quicksearch> <a href="#" @click.prevent="removeTag(index)" diff --git a/lib/classes/StudipController.php b/lib/classes/StudipController.php index f749bd0d602f1d37ccac7f7bac72c731c5c7e795..d103621b3e5a2bde805ed8c164a1a51944caeecf 100644 --- a/lib/classes/StudipController.php +++ b/lib/classes/StudipController.php @@ -586,6 +586,9 @@ abstract class StudipController extends Trails\Controller public function render_form(\Studip\Forms\Form $form) { \NotificationCenter::postNotification('FormWillRender', $form); + if (\Request::isDialog()) { + $this->response->add_header('X-No-Buttons', 1); + } $this->render_template($form->getTemplate(), $this->layout); } diff --git a/lib/classes/forms/Form.php b/lib/classes/forms/Form.php index 58fe47a2a3baa0c535960c02526c3c3a60c19898..576ea43702a5214ca7d1014ca3f5451c5dc9dad0 100644 --- a/lib/classes/forms/Form.php +++ b/lib/classes/forms/Form.php @@ -502,6 +502,9 @@ class Form extends Part public function render(string|Template $layout = null) { \NotificationCenter::postNotification('FormWillRender', $this); + if (\Request::isDialog()) { + header('X-No-Buttons: 1'); + } return $this->getTemplate()->render([], $layout); } diff --git a/package-lock.json b/package-lock.json index 3739a8aea10bff0298e7e1b1b3486a080f294b24..f9151062361bdb42eddeddc2a2f7e7ff18823741 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,17 @@ "name": "@studip/core", "version": "6.0.0", "license": "GPL-2.0", + "dependencies": { + "@vojtechlanka/vue-tags-input": "^3.1.1" + }, "devDependencies": { "@axe-core/playwright": "^4.6.1", - "@babel/core": "^7.17.9", - "@babel/eslint-parser": "^7.17.0", + "@babel/core": "^7.26.0", + "@babel/eslint-parser": "^7.25.9", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/register": "^7.12.1", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.26.0", + "@babel/register": "^7.25.9", "@ckeditor/ckeditor5-alignment": "^36.x", "@ckeditor/ckeditor5-autoformat": "^36.x", "@ckeditor/ckeditor5-basic-styles": "^36.x", @@ -45,8 +48,7 @@ "@ckeditor/ckeditor5-theme-lark": "^36.x", "@ckeditor/ckeditor5-typing": "^36.x", "@ckeditor/ckeditor5-upload": "^36.x", - "@ckeditor/ckeditor5-vue2": "^3.0.1", - "@elan-ev/reststate-vuex": "~1.0.5", + "@ckeditor/ckeditor5-vue": "^5.1.0", "@fullcalendar/core": "^4.3.1", "@fullcalendar/daygrid": "^4.3.0", "@fullcalendar/interaction": "^4.3.0", @@ -54,17 +56,17 @@ "@fullcalendar/resource-timegrid": "^4.3.0", "@fullcalendar/resource-timeline": "^4.3.0", "@fullcalendar/timegrid": "^4.3.0", - "@johmun/vue-tags-input": "^2.1.0", "@playwright/test": "^1.33.0", "@popperjs/core": "^2.11.2", "@types/jquery": "^3.5.16", "@types/jqueryui": "^1.12.16", "@types/lodash": "^4.14.191", - "@vue/eslint-config-typescript": "^12.0.0", + "@vue/compiler-sfc": "^3.5.13", + "@vue/eslint-config-typescript": "^13.0.0", "altcha": "^0.3.2", - "autoprefixer": "^10.2.5", + "autoprefixer": "^10.4.20", "axios": "^0.21.0", - "babel-loader": "^8.2.1", + "babel-loader": "^9.2.1", "blueimp-file-upload": "10.31.0", "buffer": "^6.0.3", "chart.js": "^2.9.4", @@ -72,18 +74,19 @@ "ckeditor5-math": "^36.x", "colorpare": "^2.2.0", "cropperjs": "1.5.9", - "css-loader": "^5.0.1", - "css-minimizer-webpack-plugin": "^1.1.5", + "css-loader": "^7.1.2", + "css-minimizer-webpack-plugin": "^7.0.0", "dotenv": "^16.0.3", "easygettext": "^2.17.0", "es6-promise": "4.2.8", - "eslint": "^7.32.0", - "eslint-plugin-vue": "^9.10.0", - "eslint-webpack-plugin": "^3.1.1", - "expose-loader": "1.0.1", + "eslint": "^8.57.1", + "eslint-plugin-vue": "^9.28.0", + "eslint-webpack-plugin": "^4.2.0", + "expose-loader": "^5.0.0", "favico.js": "0.3.10", "file-saver": "^2.0.5", - "focus-trap-vue": "^1.1.1", + "focus-trap": "^7.6.2", + "focus-trap-vue": "^4.0.3", "highlight.js": "10.5.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", @@ -99,47 +102,45 @@ "jszip": "^3.8.0", "lodash": "^4.17.20", "md5": "^2.3.0", - "mini-css-extract-plugin": "1.3.1", - "mitt": "2.1.0", + "mini-css-extract-plugin": "^2.9.2", + "mitt": "^3.0.1", "mp3tag.js": "3.7.1", "multiselect": "0.9.12", "pdfjs-dist": "^2.6.347", - "portal-vue": "^2.1.7", - "postcss": "^8.1.8", - "postcss-loader": "4.1.0", + "pinia": "^2.2.8", + "portal-vue": "^3.0.0", + "postcss": "^8.4.49", + "postcss-loader": "^8.1.1", "postcss-scss": "^4.0.4", "raw-loader": "^4.0.2", "sanitize-html": "^2.7.0", "sass": "^1.29.0", - "sass-loader": "^10.1.0", + "sass-loader": "^16.0.4", "select2": "4.0.13", "sprintf-js": "^1.0.3", "stream-browserify": "^3.0.0", - "style-loader": "^2.0.0", + "style-loader": "^4.0.0", "svgo": "3.3.2", "tablesorter": "2.31.3", - "ts-loader": "^9.4.2", - "typescript": "^5.0.2", - "vrp-vue-resizable": "1.2.7", - "vue": "^2.7.14", - "vue-dragscroll": "^3.0.1", - "vue-gettext": "^2.1.12", - "vue-loader": "^15.9.8", - "vue-router": "^3.5.1", - "vue-select": "^3.11.2", - "vue-template-babel-compiler": "^1.2.0", - "vue-template-compiler": "^2.6.12", - "vue-twentytwenty": "^0.10.1", + "ts-loader": "^9.5.1", + "typescript": "^5.7.2", + "vue": "^3.5.13", + "vue-dragscroll": "^4.0.6", + "vue-loader": "^17.4.2", + "vue-resizable": "^2.1.7", + "vue-router": "^4.5.0", + "vue-select": "^4.0.0-beta.6", "vue-typer": "^1.2.0", - "vuedraggable": "^2.24.3", - "vuex": "^3.6.2", - "webpack": "^5.70.0", - "webpack-cli": "^4.10.0", - "webpack-merge": "5.4.0", + "vue3-gettext": "^3.0.0-beta.5", + "vuedraggable": "^4.1.0", + "vuex": "^4.1.0", + "webpack": "^5.97.0", + "webpack-cli": "^5.1.4", + "webpack-merge": "^6.0.1", "webpack-notifier": "^1.15.0" }, "engines": { - "node": ">=18" + "node": ">=18 <23" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -177,43 +178,47 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.20.tgz", - "integrity": "sha512-BQYjKbpXjoXwFW5jGqiizJQQT/aC7pFm9Ok1OWssonuguICi264lbgMzRp2ZMmRSlfkX6DsWDDcsrctK8Rwfiw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.0.tgz", - "integrity": "sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helpers": "^7.23.0", - "@babel/parser": "^7.23.0", - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -244,10 +249,11 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.22.15.tgz", - "integrity": "sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz", + "integrity": "sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ==", "dev": true, + "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", @@ -258,7 +264,7 @@ }, "peerDependencies": { "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0" + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/@babel/eslint-parser/node_modules/semver": { @@ -271,53 +277,59 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz", - "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz", + "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz", - "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.15", - "browserslist": "^4.21.9", + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -330,28 +342,31 @@ "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-create-class-features-plugin": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz", - "integrity": "sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", "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": { @@ -359,19 +374,21 @@ "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-create-regexp-features-plugin": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz", - "integrity": "sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz", + "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@nicolo-ribaudo/semver-v6": "^6.3.3", - "regexpu-core": "^5.3.1" + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -380,11 +397,22 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.2.tgz", - "integrity": "sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -396,75 +424,44 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.0" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.15" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz", - "integrity": "sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -474,35 +471,38 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-wrap-function": "^7.22.20" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -512,14 +512,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-member-expression-to-functions": "^7.22.15", - "@babel/helper-optimise-call-expression": "^7.22.5" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -529,115 +530,98 @@ } }, "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz", + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true, + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true, + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz", - "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-function-name": "^7.22.5", - "@babel/template": "^7.22.15", - "@babel/types": "^7.22.19" + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.23.1", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.1.tgz", - "integrity": "sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.15", - "@babel/traverse": "^7.23.0", - "@babel/types": "^7.23.0" + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.26.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -645,13 +629,15 @@ "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz", - "integrity": "sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg==", + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -660,73 +646,71 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz", - "integrity": "sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ==", + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-transform-optional-chaining": "^7.22.15" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.13.0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", - "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", - "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.20.7" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-proposal-optional-chaining": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", - "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2", - "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, "node_modules/@babel/plugin-proposal-private-property-in-object": { @@ -777,21 +761,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", @@ -804,25 +773,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz", - "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -832,12 +790,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz", - "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -957,21 +916,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", @@ -1019,12 +963,13 @@ } }, "node_modules/@babel/plugin-transform-arrow-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz", - "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1034,15 +979,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.15.tgz", - "integrity": "sha512-jBm1Es25Y+tVoTi5rfd5t1KLmL8ogLKpXszboWOTTtGFGz2RKnQe2yn7HbZ+kb/B8N0FVSGQo874NSlOU1T4+w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.9", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1052,14 +997,15 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz", - "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.5" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1069,12 +1015,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoped-functions": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz", - "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz", + "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1084,12 +1031,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz", - "integrity": "sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1099,13 +1047,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz", - "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1115,14 +1064,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz", - "integrity": "sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-class-static-block": "^7.14.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1132,19 +1081,17 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz", - "integrity": "sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-optimise-call-expression": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.9", - "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", "globals": "^11.1.0" }, "engines": { @@ -1155,13 +1102,14 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz", - "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/template": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1171,12 +1119,13 @@ } }, "node_modules/@babel/plugin-transform-destructuring": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz", - "integrity": "sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1186,13 +1135,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz", - "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1202,12 +1152,13 @@ } }, "node_modules/@babel/plugin-transform-duplicate-keys": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz", - "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1216,14 +1167,31 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-dynamic-import": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz", - "integrity": "sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1233,13 +1201,14 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz", - "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz", + "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1249,13 +1218,13 @@ } }, "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz", - "integrity": "sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1265,12 +1234,14 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz", - "integrity": "sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1280,14 +1251,15 @@ } }, "node_modules/@babel/plugin-transform-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz", - "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1297,13 +1269,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz", - "integrity": "sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1313,12 +1285,13 @@ } }, "node_modules/@babel/plugin-transform-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz", - "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1328,13 +1301,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz", - "integrity": "sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1344,12 +1317,13 @@ } }, "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz", - "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1359,13 +1333,14 @@ } }, "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz", - "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1375,14 +1350,15 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz", - "integrity": "sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz", + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-simple-access": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1392,15 +1368,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz", - "integrity": "sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-module-transforms": "^7.23.0", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1410,13 +1387,14 @@ } }, "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz", - "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1426,13 +1404,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1442,12 +1421,13 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz", - "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1457,13 +1437,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz", - "integrity": "sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz", + "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1473,13 +1453,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz", - "integrity": "sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1489,16 +1469,15 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz", - "integrity": "sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.22.15" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1508,13 +1487,14 @@ } }, "node_modules/@babel/plugin-transform-object-super": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz", - "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-replace-supers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1524,13 +1504,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz", - "integrity": "sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1540,14 +1520,14 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz", - "integrity": "sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1557,12 +1537,13 @@ } }, "node_modules/@babel/plugin-transform-parameters": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz", - "integrity": "sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1572,13 +1553,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz", - "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1588,15 +1570,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz", - "integrity": "sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-create-class-features-plugin": "^7.22.11", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1606,12 +1588,13 @@ } }, "node_modules/@babel/plugin-transform-property-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz", - "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1621,12 +1604,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz", - "integrity": "sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1636,13 +1620,31 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@babel/plugin-transform-reserved-words": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz", - "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1652,16 +1654,17 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.15.tgz", - "integrity": "sha512-tEVLhk8NRZSmwQ0DJtxxhTrCht1HVo8VaMzYT4w6lwyKBuHsgoioAUA7/6eT2fRfc5/23fuGdlwIxXhRVgWr4g==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "babel-plugin-polyfill-corejs2": "^0.4.5", - "babel-plugin-polyfill-corejs3": "^0.8.3", - "babel-plugin-polyfill-regenerator": "^0.5.2", + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, "engines": { @@ -1681,12 +1684,13 @@ } }, "node_modules/@babel/plugin-transform-shorthand-properties": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz", - "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1696,13 +1700,14 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz", - "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1712,12 +1717,13 @@ } }, "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz", - "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1727,12 +1733,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz", - "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1742,12 +1749,13 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz", - "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1757,12 +1765,13 @@ } }, "node_modules/@babel/plugin-transform-unicode-escapes": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz", - "integrity": "sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1772,13 +1781,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz", - "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1788,13 +1798,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz", - "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1804,13 +1815,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz", - "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1820,90 +1832,80 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.20.tgz", - "integrity": "sha512-11MY04gGC4kSzlPHRfvVkNAZhUxOvm7DCJ37hPDnUENwe06npjIRAfInEMTGSb4LZK5ZgDFkv5hw0lGebHeTyg==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.22.20", - "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-validator-option": "^7.22.15", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.22.5", - "@babel/plugin-syntax-import-attributes": "^7.22.5", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.22.5", - "@babel/plugin-transform-async-generator-functions": "^7.22.15", - "@babel/plugin-transform-async-to-generator": "^7.22.5", - "@babel/plugin-transform-block-scoped-functions": "^7.22.5", - "@babel/plugin-transform-block-scoping": "^7.22.15", - "@babel/plugin-transform-class-properties": "^7.22.5", - "@babel/plugin-transform-class-static-block": "^7.22.11", - "@babel/plugin-transform-classes": "^7.22.15", - "@babel/plugin-transform-computed-properties": "^7.22.5", - "@babel/plugin-transform-destructuring": "^7.22.15", - "@babel/plugin-transform-dotall-regex": "^7.22.5", - "@babel/plugin-transform-duplicate-keys": "^7.22.5", - "@babel/plugin-transform-dynamic-import": "^7.22.11", - "@babel/plugin-transform-exponentiation-operator": "^7.22.5", - "@babel/plugin-transform-export-namespace-from": "^7.22.11", - "@babel/plugin-transform-for-of": "^7.22.15", - "@babel/plugin-transform-function-name": "^7.22.5", - "@babel/plugin-transform-json-strings": "^7.22.11", - "@babel/plugin-transform-literals": "^7.22.5", - "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", - "@babel/plugin-transform-member-expression-literals": "^7.22.5", - "@babel/plugin-transform-modules-amd": "^7.22.5", - "@babel/plugin-transform-modules-commonjs": "^7.22.15", - "@babel/plugin-transform-modules-systemjs": "^7.22.11", - "@babel/plugin-transform-modules-umd": "^7.22.5", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.22.5", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", - "@babel/plugin-transform-numeric-separator": "^7.22.11", - "@babel/plugin-transform-object-rest-spread": "^7.22.15", - "@babel/plugin-transform-object-super": "^7.22.5", - "@babel/plugin-transform-optional-catch-binding": "^7.22.11", - "@babel/plugin-transform-optional-chaining": "^7.22.15", - "@babel/plugin-transform-parameters": "^7.22.15", - "@babel/plugin-transform-private-methods": "^7.22.5", - "@babel/plugin-transform-private-property-in-object": "^7.22.11", - "@babel/plugin-transform-property-literals": "^7.22.5", - "@babel/plugin-transform-regenerator": "^7.22.10", - "@babel/plugin-transform-reserved-words": "^7.22.5", - "@babel/plugin-transform-shorthand-properties": "^7.22.5", - "@babel/plugin-transform-spread": "^7.22.5", - "@babel/plugin-transform-sticky-regex": "^7.22.5", - "@babel/plugin-transform-template-literals": "^7.22.5", - "@babel/plugin-transform-typeof-symbol": "^7.22.5", - "@babel/plugin-transform-unicode-escapes": "^7.22.10", - "@babel/plugin-transform-unicode-property-regex": "^7.22.5", - "@babel/plugin-transform-unicode-regex": "^7.22.5", - "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", - "@babel/types": "^7.22.19", - "babel-plugin-polyfill-corejs2": "^0.4.5", - "babel-plugin-polyfill-corejs3": "^0.8.3", - "babel-plugin-polyfill-regenerator": "^0.5.2", - "core-js-compat": "^3.31.0", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", "semver": "^6.3.1" }, "engines": { @@ -1937,15 +1939,16 @@ } }, "node_modules/@babel/register": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.22.15.tgz", - "integrity": "sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.25.9.tgz", + "integrity": "sha512-8D43jXtGsYmEeDvm4MWHYUpWf8iiXgWYx3fW7E7Wb7Oe6FWqJPl5K6TuFW0dOwNZzEE5rjlaSJYH9JjrUKJszA==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "find-cache-dir": "^2.0.0", "make-dir": "^2.1.0", - "pirates": "^4.0.5", + "pirates": "^4.0.6", "source-map-support": "^0.5.16" }, "engines": { @@ -1955,12 +1958,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==", - "dev": true - }, "node_modules/@babel/runtime": { "version": "7.22.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", @@ -1974,34 +1971,33 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz", - "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -2009,14 +2005,13 @@ } }, "node_modules/@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", - "dev": true, + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -2186,15 +2181,6 @@ "node": ">=7.0.0" } }, - "node_modules/@ckeditor/ckeditor5-dev-translations/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@ckeditor/ckeditor5-dev-translations/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -2279,15 +2265,6 @@ "node": ">=7.0.0" } }, - "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/postcss-loader": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.3.0.tgz", @@ -2330,18 +2307,39 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/style-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", + "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/@ckeditor/ckeditor5-dev-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@ckeditor/ckeditor5-easy-image": { "version": "36.0.1", "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-easy-image/-/ckeditor5-easy-image-36.0.1.tgz", @@ -2731,13 +2729,15 @@ "npm": ">=5.7.1" } }, - "node_modules/@ckeditor/ckeditor5-vue2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-vue2/-/ckeditor5-vue2-3.0.1.tgz", - "integrity": "sha512-vS9ffP3rOFgM8oeG9XVFD+UtcYAhkgFDfBHjswJuCgUM0Iw8uqLlCiDPbs4PeJsend8GcmmtNeFdcQaSPkOtpw==", + "node_modules/@ckeditor/ckeditor5-vue": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ckeditor/ckeditor5-vue/-/ckeditor5-vue-5.1.0.tgz", + "integrity": "sha512-KEx4Tj2Irr4ZbLG8LnaKpb0Dgd8qmLmKFWeiKkQwM3RAAeYRYOCcBVB2Y168I9KA8wRosPxgOO9jbQ92yopYHA==", "dev": true, + "hasInstallScript": true, + "license": "GPL-2.0-or-later", "engines": { - "node": ">=14.0.0", + "node": ">=16.0.0", "npm": ">=5.7.1" } }, @@ -2785,24 +2785,6 @@ "node": ">=10.0.0" } }, - "node_modules/@elan-ev/reststate-client": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@elan-ev/reststate-client/-/reststate-client-1.0.0.tgz", - "integrity": "sha512-mXnQAeGJ+MZ5eKlJOaZnmq27UbUMeztKm5tgRDIgA2s49KcGbMOsug5KuZZFZFOj/AKE/N7O04pVOWRlgHpIBg==", - "dev": true - }, - "node_modules/@elan-ev/reststate-vuex": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@elan-ev/reststate-vuex/-/reststate-vuex-1.0.6.tgz", - "integrity": "sha512-hj1MCzPx9dF2jhQ2rstTBqg4WGNT+cvfIBBpCgsAE9CSrroZlL0Gdb6+3XVnM9cOKQi7NdAnTy6b/FMC5+rlaw==", - "dev": true, - "dependencies": { - "@elan-ev/reststate-client": "^1.0.0" - }, - "peerDependencies": { - "vuex": "^3.0.1" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -2831,39 +2813,52 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -2874,13 +2869,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "engines": { - "node": ">= 4" + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { @@ -2888,6 +2887,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -2895,6 +2895,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@fullcalendar/core": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-4.4.2.tgz", @@ -2996,24 +3006,145 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -3109,15 +3240,6 @@ "node": ">=7.0.0" } }, - "node_modules/@jest/console/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/console/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3220,15 +3342,6 @@ "node": ">=7.0.0" } }, - "node_modules/@jest/core/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/core/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3399,15 +3512,6 @@ "node": ">=7.0.0" } }, - "node_modules/@jest/reporters/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/reporters/node_modules/jest-worker": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", @@ -3581,15 +3685,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/@jest/transform/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/transform/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3662,15 +3757,6 @@ "node": ">=7.0.0" } }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/types/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3683,27 +3769,16 @@ "node": ">=8" } }, - "node_modules/@johmun/vue-tags-input": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@johmun/vue-tags-input/-/vue-tags-input-2.1.0.tgz", - "integrity": "sha512-Fdwfss/TqCqMJbGAkmlzKbcG/ia1MstYjhqPBj+zG7h/166tIcE1TIftUxhT9LZ+RWjRSG0EFA1UyaHQSr3k3Q==", - "dev": true, - "dependencies": { - "vue": "^2.6.10" - }, - "peerDependencies": { - "vue": "2.x" - } - }, "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==", + "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" @@ -3719,10 +3794,11 @@ } }, "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==", + "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" } @@ -3738,27 +3814,22 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "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" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", @@ -3768,15 +3839,6 @@ "eslint-scope": "5.1.1" } }, - "node_modules/@nicolo-ribaudo/semver-v6": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz", - "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3836,6 +3898,17 @@ "node": ">=10" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@playwright/test": { "version": "1.38.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", @@ -3945,30 +4018,33 @@ } }, "node_modules/@types/eslint": { - "version": "8.40.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz", - "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==", + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "dev": true, + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/glob": { "version": "7.2.0", @@ -4072,11 +4148,12 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "dev": true }, - "node_modules/@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", - "dev": true + "node_modules/@types/parse5": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", + "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/raf": { "version": "3.4.0", @@ -4085,12 +4162,6 @@ "dev": true, "optional": true }, - "node_modules/@types/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==", - "dev": true - }, "node_modules/@types/sizzle": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", @@ -4125,33 +4196,32 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", - "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/type-utils": "6.7.5", - "@typescript-eslint/utils": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -4160,26 +4230,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", - "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -4188,16 +4259,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", - "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -4205,25 +4277,26 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", - "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.5", - "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -4232,12 +4305,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", - "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -4245,21 +4319,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", - "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/visitor-keys": "6.7.5", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -4271,42 +4347,67 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", - "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.5", - "@typescript-eslint/types": "6.7.5", - "@typescript-eslint/typescript-estree": "6.7.5", - "semver": "^7.5.4" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", - "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "6.7.5", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -4318,6 +4419,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4325,135 +4427,102 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@vue/compiler-core": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.3.4.tgz", - "integrity": "sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==", + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true, - "optional": true, + "license": "ISC" + }, + "node_modules/@vojtechlanka/vue-tags-input": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@vojtechlanka/vue-tags-input/-/vue-tags-input-3.1.1.tgz", + "integrity": "sha512-GdREECH+k2pQCKdbHHh4/IxRXje3QQ8rXzXd9/6L1kzGYXqHlG1tbRoi1qC7enph67/g2nvGaZfpqLuuW+CX3g==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.21.3", - "@vue/shared": "3.3.4", + "fast-deep-equal": "^3.1.3", + "vue": "3.x", + "vuedraggable": "^4.1.0" + }, + "peerDependencies": { + "vue": "3.x" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz", - "integrity": "sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==", - "dev": true, - "optional": true, + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz", - "integrity": "sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==", - "dev": true, - "optional": true, - "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/compiler-dom": "3.3.4", - "@vue/compiler-ssr": "3.3.4", - "@vue/reactivity-transform": "3.3.4", - "@vue/shared": "3.3.4", + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", "estree-walker": "^2.0.2", - "magic-string": "^0.30.0", - "postcss": "^8.1.10", - "source-map-js": "^1.0.2" + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz", - "integrity": "sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==", - "dev": true, - "optional": true, + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.3.4", - "@vue/shared": "3.3.4" + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" } }, - "node_modules/@vue/component-compiler-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.3.0.tgz", - "integrity": "sha512-97sfH2mYNU+2PzGrmK2haqffDpVASuib9/w2/noxiFi31Z54hW+q3izKQXXQZSNhtiUpAI36uSuYepeBe4wpHQ==", + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", "dev": true, - "dependencies": { - "consolidate": "^0.15.1", - "hash-sum": "^1.0.2", - "lru-cache": "^4.1.2", - "merge-source-map": "^1.1.0", - "postcss": "^7.0.36", - "postcss-selector-parser": "^6.0.2", - "source-map": "~0.6.1", - "vue-template-es2015-compiler": "^1.9.0" - }, - "optionalDependencies": { - "prettier": "^1.18.2 || ^2.0.0" - } + "license": "MIT" }, - "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "node_modules/@vue/eslint-config-typescript": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-13.0.0.tgz", + "integrity": "sha512-MHh9SncG/sfqjVqjcuFLOLD6Ed4dRAis4HNt0dXASeAuLqIAx4YMB1/m2o4pUKK1vCt8fUvYG8KKX2Ot3BVZTg==", "dev": true, + "license": "MIT", "dependencies": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/@vue/component-compiler-utils/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/@vue/component-compiler-utils/node_modules/yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true - }, - "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", - "integrity": "sha512-StxLFet2Qe97T8+7L8pGlhYBBr8Eg05LPuTDVopQV6il+SK6qqom59BA/rcFipUef2jD8P2X44Vd8tMFytfvlg==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^6.7.0", - "@typescript-eslint/parser": "^6.7.0", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.1.1", "vue-eslint-parser": "^9.3.1" }, "engines": { - "node": "^14.17.0 || >=16.0.0" + "node": "^18.18.0 || >=20.0.0" }, "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0", + "eslint": "^8.56.0", "eslint-plugin-vue": "^9.0.0", - "typescript": "*" + "typescript": ">=4.7.4" }, "peerDependenciesMeta": { "typescript": { @@ -4461,202 +4530,257 @@ } } }, - "node_modules/@vue/reactivity-transform": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz", - "integrity": "sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==", - "dev": true, - "optional": true, + "node_modules/@vue/reactivity": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz", + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.20.15", - "@vue/compiler-core": "3.3.4", - "@vue/shared": "3.3.4", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.0" + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz", + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz", + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "vue": "3.5.13" } }, "node_modules/@vue/shared": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz", - "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==", - "dev": true, - "optional": true + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "license": "MIT" }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "dev": true, + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/ast": "1.14.1", "@xtuc/long": "4.2.2" } }, "node_modules/@webpack-cli/configtest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.2.0.tgz", - "integrity": "sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.5.0.tgz", - "integrity": "sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, - "dependencies": { - "envinfo": "^7.7.3" + "license": "MIT", + "engines": { + "node": ">=14.15.0" }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.7.0.tgz", - "integrity": "sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, "peerDependencies": { - "webpack-cli": "4.x.x" + "webpack": "5.x.x", + "webpack-cli": "5.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -4668,13 +4792,15 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/abab": { "version": "2.0.6", @@ -4897,27 +5023,12 @@ "ajv": "^6.9.1" } }, - "node_modules/alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==", - "dev": true - }, "node_modules/altcha": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/altcha/-/altcha-0.3.2.tgz", "integrity": "sha512-5UQP/fwgdlxfhgr4GADoPyMzHWTmDuWq3OloQlZsmUl3C/8+0huWdXW5S8FraA6GWK8iEwbG/2IR4TehLTY9cQ==", "dev": true }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4942,18 +5053,6 @@ "node": ">=8" } }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -4982,17 +5081,14 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "node_modules/array-back": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", + "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "license": "MIT", + "engines": { + "node": ">=6" } }, "node_modules/array-union": { @@ -5004,25 +5100,6 @@ "node": ">=8" } }, - "node_modules/array.prototype.reduce": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", - "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-array-method-boxes-properly": "^1.0.0", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -5037,15 +5114,6 @@ "dev": true, "optional": true }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -5065,9 +5133,9 @@ } }, "node_modules/autoprefixer": { - "version": "10.4.16", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.16.tgz", - "integrity": "sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "dev": true, "funding": [ { @@ -5083,12 +5151,13 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "browserslist": "^4.21.10", - "caniuse-lite": "^1.0.30001538", - "fraction.js": "^4.3.6", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -5101,18 +5170,6 @@ "postcss": "^8.1.0" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/axe-core": { "version": "4.7.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", @@ -5195,15 +5252,6 @@ "node": ">=7.0.0" } }, - "node_modules/babel-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/babel-jest/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5217,75 +5265,142 @@ } }, "node_modules/babel-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.3.0.tgz", - "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", "dev": true, + "license": "MIT", "dependencies": { - "find-cache-dir": "^3.3.1", - "loader-utils": "^2.0.0", - "make-dir": "^3.1.0", - "schema-utils": "^2.6.5" + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 8.9" + "node": ">= 14.15.0" }, "peerDependencies": { - "@babel/core": "^7.0.0", - "webpack": ">=2" + "@babel/core": "^7.12.0", + "webpack": ">=5" } }, "node_modules/babel-loader/node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "dev": true, + "license": "MIT", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-loader/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/babel-loader/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/babel-loader/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/babel-loader/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/babel-loader/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", "dev": true, + "license": "MIT", "dependencies": { - "find-up": "^4.0.0" + "find-up": "^6.3.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/babel-loader/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/babel-loader/node_modules/yocto-queue": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", + "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/babel-plugin-istanbul": { @@ -5345,13 +5460,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz", - "integrity": "sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==", + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.4.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -5363,30 +5479,33 @@ "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-plugin-polyfill-corejs3": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.4.tgz", - "integrity": "sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.2", - "core-js-compat": "^3.32.2" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz", - "integrity": "sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.4.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5498,12 +5617,6 @@ "node": ">=8" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, "node_modules/blueimp-canvas-to-blob": { "version": "3.29.0", "resolved": "https://registry.npmjs.org/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.29.0.tgz", @@ -5571,9 +5684,9 @@ } }, "node_modules/browserslist": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz", - "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "dev": true, "funding": [ { @@ -5589,11 +5702,12 @@ "url": "https://github.com/sponsors/ai" } ], + "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.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -5711,6 +5825,7 @@ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, + "optional": true, "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -5719,39 +5834,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5832,20 +5914,6 @@ "node": ">=10.0.0" } }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -6131,36 +6199,12 @@ "node": ">= 0.12.0" } }, - "node_modules/coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "dependencies": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6182,16 +6226,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "dev": true, - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", @@ -6222,6 +6256,22 @@ "node": ">= 0.8" } }, + "node_modules/command-line-args": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", + "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^3.1.0", + "find-replace": "^3.0.0", + "lodash.camelcase": "^4.3.0", + "typical": "^4.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -6231,6 +6281,13 @@ "node": ">= 10" } }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true, + "license": "ISC" + }, "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -6243,19 +6300,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/consolidate": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", - "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", - "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", - "dev": true, - "dependencies": { - "bluebird": "^3.1.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/constantinople": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", @@ -6280,12 +6324,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.33.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.33.0.tgz", - "integrity": "sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw==", + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz", + "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.22.1" + "browserslist": "^4.24.2" }, "funding": { "type": "opencollective", @@ -6378,15 +6423,6 @@ "node": ">=7.0.0" } }, - "node_modules/create-jest/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/create-jest/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6428,15 +6464,6 @@ "node": "*" } }, - "node_modules/css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha512-zj5D7X1U2h2zsXOAM8EyUREBnnts6H+Jm+d1M2DbiQQcUtnqgQsMrdo8JW9R80YFUmIdBZeMu5wvYM7hcgWP/Q==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/css-declaration-sorter": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz", @@ -6460,971 +6487,670 @@ } }, "node_modules/css-loader": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz", - "integrity": "sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.15", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^3.0.0", - "semver": "^7.3.5" + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.27.0 || ^5.0.0" - } - }, - "node_modules/css-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/css-minimizer-webpack-plugin": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-1.3.0.tgz", - "integrity": "sha512-jFa0Siplmfef4ndKglpVaduY47oHQwioAOEGK0f0vAX0s+vc+SmP6cCMoc+8Adau5600RnOEld5VVdC8CQau7w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-7.0.0.tgz", + "integrity": "sha512-niy66jxsQHqO+EYbhPuIhqRQ1mNcNVUHrMnkzzir9kFOERJUaQDDRhh7dKDz33kBpkWMF9M8Vx0QlDbc5AHOsw==", "dev": true, + "license": "MIT", "dependencies": { - "cacache": "^15.0.5", - "cssnano": "^4.1.10", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.3.0", - "p-limit": "^3.0.2", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "webpack-sources": "^1.4.3" + "@jridgewell/trace-mapping": "^0.3.25", + "cssnano": "^7.0.1", + "jest-worker": "^29.7.0", + "postcss": "^8.4.38", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "webpack": "^5.0.0" }, - "engines": { - "node": ">=4" + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "lightningcss": { + "optional": true + } } }, "node_modules/css-minimizer-webpack-plugin/node_modules/css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - }, - "engines": { - "node": ">4" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz", + "integrity": "sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==", "dev": true, + "license": "ISC", "engines": { - "node": ">= 6" + "node": "^14 || ^16 || >=18" }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "peerDependencies": { + "postcss": "^8.0.9" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", - "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", - "dev": true, - "dependencies": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.8", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/domutils/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.0.6.tgz", + "integrity": "sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==", "dev": true, + "license": "MIT", "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" + "cssnano-preset-default": "^7.0.6", + "lilconfig": "^3.1.2" }, "engines": { - "node": ">=8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "type": "opencollective", + "url": "https://opencollective.com/cssnano" }, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano-preset-default": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.6.tgz", + "integrity": "sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.0", + "postcss-calc": "^10.0.2", + "postcss-colormin": "^7.0.2", + "postcss-convert-values": "^7.0.4", + "postcss-discard-comments": "^7.0.3", + "postcss-discard-duplicates": "^7.0.1", + "postcss-discard-empty": "^7.0.0", + "postcss-discard-overridden": "^7.0.0", + "postcss-merge-longhand": "^7.0.4", + "postcss-merge-rules": "^7.0.4", + "postcss-minify-font-values": "^7.0.0", + "postcss-minify-gradients": "^7.0.0", + "postcss-minify-params": "^7.0.2", + "postcss-minify-selectors": "^7.0.4", + "postcss-normalize-charset": "^7.0.0", + "postcss-normalize-display-values": "^7.0.0", + "postcss-normalize-positions": "^7.0.0", + "postcss-normalize-repeat-style": "^7.0.0", + "postcss-normalize-string": "^7.0.0", + "postcss-normalize-timing-functions": "^7.0.0", + "postcss-normalize-unicode": "^7.0.2", + "postcss-normalize-url": "^7.0.0", + "postcss-normalize-whitespace": "^7.0.0", + "postcss-ordered-values": "^7.0.1", + "postcss-reduce-initial": "^7.0.2", + "postcss-reduce-transforms": "^7.0.0", + "postcss-svgo": "^7.0.1", + "postcss-unique-selectors": "^7.0.3" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano-utils": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.0.tgz", + "integrity": "sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==", "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/css-minimizer-webpack-plugin/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "^1.2.6" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true, "engines": { - "node": ">=6" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "dependencies": { - "boolbase": "~1.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "node_modules/css-minimizer-webpack-plugin/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, + "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" + "node": ">=14" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-calc": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.0.2.tgz", + "integrity": "sha512-DT/Wwm6fCKgpYVI7ZEWuPJ4az8hiEHtCUeYjZXqU7Ou4QqYh1Df2yCQ7Ca6N7xqKPFkxN3fhf+u9KSoOCJNAjg==", "dev": true, + "license": "MIT", "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" + "postcss-selector-parser": "^6.1.2", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.0.0" + "node": "^18.12 || ^20.9 || >=22.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", - "dev": true, - "dependencies": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" + "peerDependencies": { + "postcss": "^8.4.38" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.2.tgz", + "integrity": "sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0", + "colord": "^2.9.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-colormin/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.4.tgz", + "integrity": "sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q==", "dev": true, + "license": "MIT", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "browserslist": "^4.23.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-convert-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.3.tgz", + "integrity": "sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA==", "dev": true, + "license": "MIT", "dependencies": { - "postcss": "^7.0.0" + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.1.tgz", + "integrity": "sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==", "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.0.tgz", + "integrity": "sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==", "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.0.tgz", + "integrity": "sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==", "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.4.tgz", + "integrity": "sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A==", "dev": true, + "license": "MIT", "dependencies": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.4" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.4.tgz", + "integrity": "sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.0.0", + "browserslist": "^4.23.3", "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" + "cssnano-utils": "^5.0.0", + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.0.tgz", + "integrity": "sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==", "dev": true, + "license": "MIT", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.0.tgz", + "integrity": "sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==", "dev": true, + "license": "MIT", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "colord": "^2.9.3", + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.2.tgz", + "integrity": "sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==", "dev": true, + "license": "MIT", "dependencies": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" + "browserslist": "^4.23.3", + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-params/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.0.4.tgz", + "integrity": "sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA==", "dev": true, + "license": "MIT", "dependencies": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" + "cssesc": "^3.0.0", + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "engines": { - "node": ">=8" + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.0.tgz", + "integrity": "sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==", "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.0.tgz", + "integrity": "sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==", "dev": true, + "license": "MIT", "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.0.tgz", + "integrity": "sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==", "dev": true, + "license": "MIT", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.0.tgz", + "integrity": "sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==", "dev": true, + "license": "MIT", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.0.tgz", + "integrity": "sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==", "dev": true, + "license": "MIT", "dependencies": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.0.tgz", + "integrity": "sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==", "dev": true, + "license": "MIT", "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.2.tgz", + "integrity": "sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "browserslist": "^4.23.3", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.0.tgz", + "integrity": "sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==", "dev": true, + "license": "MIT", "dependencies": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.0.tgz", + "integrity": "sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==", "dev": true, + "license": "MIT", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.1.tgz", + "integrity": "sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==", "dev": true, + "license": "MIT", "dependencies": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "cssnano-utils": "^5.0.0", + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.2.tgz", + "integrity": "sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" + "browserslist": "^4.23.3", + "caniuse-api": "^3.0.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dev": true, - "dependencies": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-reduce-transforms": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.0.tgz", + "integrity": "sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==", "dev": true, + "license": "MIT", "dependencies": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" + "postcss-value-parser": "^4.2.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-svgo/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dev": true, - "dependencies": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", - "dev": true, - "engines": { - "node": ">=4" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-svgo": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.0.1.tgz", + "integrity": "sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "postcss-value-parser": "^4.2.0", + "svgo": "^3.3.2" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/css-minimizer-webpack-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, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" + "node": "^18.12.0 || ^20.9.0 || >= 18" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/stylehacks/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "node_modules/css-minimizer-webpack-plugin/node_modules/postcss-unique-selectors": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.3.tgz", + "integrity": "sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g==", "dev": true, + "license": "MIT", "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" + "postcss-selector-parser": "^6.1.2" }, "engines": { - "node": ">=8" + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "deprecated": "This SVGO version is no longer supported. Upgrade to v2.x.x.", + "node_modules/css-minimizer-webpack-plugin/node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=4.0.0" + "randombytes": "^2.1.0" } }, - "node_modules/css-minimizer-webpack-plugin/node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "node_modules/css-minimizer-webpack-plugin/node_modules/stylehacks": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.4.tgz", + "integrity": "sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww==", "dev": true, + "license": "MIT", "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" + "browserslist": "^4.23.3", + "postcss-selector-parser": "^6.1.2" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" } }, "node_modules/css-select": { @@ -7443,11 +7169,12 @@ "url": "https://github.com/sponsors/fb55" } }, - "node_modules/css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true + "node_modules/css-selector-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", + "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==", + "dev": true, + "license": "MIT" }, "node_modules/css-tree": { "version": "1.1.3", @@ -7550,68 +7277,6 @@ "postcss": "^8.2.15" } }, - "node_modules/cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha512-6RIcwmV3/cBMG8Aj5gucQRsJb4vv4I4rn6YjPbVWd5+Pn/fuG+YseGvXGk00XLkoZkaj31QOD7vMUpNPC4FIuw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha512-JPMZ1TSMRUPVIqEalIBNoBtAYbi8okvcFns4O0YIhcdGebeYZK7dMyHJiQ6GqNBA9kE0Hym4Aqym5rPdsV/4Cw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/cssnano-util-raw-cache/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/cssnano-util-raw-cache/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/cssnano-utils": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", @@ -7661,10 +7326,10 @@ "dev": true }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", - "dev": true + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/data-urls": { "version": "3.0.2", @@ -7680,12 +7345,6 @@ "node": ">=12" } }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true - }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -7738,22 +7397,6 @@ "node": ">=0.10.0" } }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/del": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz", @@ -7943,18 +7586,6 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/dotenv": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", @@ -7967,6 +7598,13 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/easygettext": { "version": "2.17.0", "resolved": "https://registry.npmjs.org/easygettext/-/easygettext-2.17.0.tgz", @@ -7997,10 +7635,11 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.544", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.544.tgz", - "integrity": "sha512-54z7squS1FyFRSUqq/knOFSptjjogLZXbKcYk3B0qkE1KZzvqASwRZnY2KzZQJqIYLVD38XZeoiMRflYSwyO4w==", - "dev": true + "version": "1.5.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz", + "integrity": "sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", @@ -8030,10 +7669,11 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -8042,23 +7682,10 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -8066,11 +7693,22 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/envinfo": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", - "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "dev": true, + "license": "MIT", "bin": { "envinfo": "dist/cli.js" }, @@ -8087,97 +7725,12 @@ "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-array-method-boxes-properly": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", - "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", - "dev": true - }, "node_modules/es-module-lexer": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", "dev": true }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -8185,23 +7738,15 @@ "dev": true }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/escodegen": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", @@ -8233,251 +7778,174 @@ } }, "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-plugin-vue": { - "version": "9.17.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz", - "integrity": "sha512-r7Bp79pxQk9I5XDP0k2dpUC7Ots3OSWgvGZNu3BxmKK6Zg7NgVtcOB6OCna5Kb9oQwJPl5hq183WD0SY5tZtIQ==", + "version": "9.28.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz", + "integrity": "sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", + "globals": "^13.24.0", "natural-compare": "^1.4.0", "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.13", - "semver": "^7.5.4", - "vue-eslint-parser": "^9.3.1", + "postcss-selector-parser": "^6.0.15", + "semver": "^7.6.3", + "vue-eslint-parser": "^9.4.3", "xml-name-validator": "^4.0.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" }, "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", - "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "node_modules/eslint-plugin-vue/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" + "type-fest": "^0.20.2" }, "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "node": ">=8" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/eslint-plugin-vue/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "node_modules/eslint-webpack-plugin/node_modules/schema-utils": { + "node_modules/eslint-webpack-plugin": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-rsfpFQ01AWQbqtjgPRr2usVRxhWDuG0YDYcG8DJOteD3EFnpeuYuOwk0PQiN7PRBTqS6ElNdtPZPggj8If9WnA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "@types/eslint": "^8.56.10", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^8.0.0 || ^9.0.0", + "webpack": "^5.0.0" } }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/eslint/node_modules/ansi-styles": { @@ -8495,6 +7963,13 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8535,6 +8010,76 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/eslint/node_modules/globals": { "version": "13.20.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", @@ -8550,22 +8095,49 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, "engines": { - "node": ">= 4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint/node_modules/supports-color": { @@ -8593,26 +8165,47 @@ } }, "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -8682,8 +8275,7 @@ "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" }, "node_modules/esutils": { "version": "2.0.3", @@ -8752,48 +8344,26 @@ } }, "node_modules/expose-loader": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/expose-loader/-/expose-loader-1.0.1.tgz", - "integrity": "sha512-FcxYU+tfzik+0Ve6Ymw8lKJNWhMQpuJOEkLhz0fGIgfDdFKxkr+BSSTkw+MRkK51hemQ+1eR7c2H46E5CxtBZw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/expose-loader/-/expose-loader-5.0.0.tgz", + "integrity": "sha512-BtUqYRmvx1bEY5HN6eK2I9URUZgNmN0x5UANuocaNjXSgfoDlkXt+wyEMe7i5DzDNh2BKJHPc5F4rBwEdSQX6w==", "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/expose-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "webpack": "^5.0.0" } }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.0", @@ -8823,6 +8393,13 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", @@ -8906,6 +8483,19 @@ "node": ">=6" } }, + "node_modules/find-replace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", + "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^3.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -8919,6 +8509,16 @@ "node": ">=8" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", @@ -8978,23 +8578,24 @@ } }, "node_modules/focus-trap": { - "version": "6.9.4", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-6.9.4.tgz", - "integrity": "sha512-v2NTsZe2FF59Y+sDykKY+XjqZ0cPfhq/hikWVL88BqLivnNiEffAsac6rP6H45ff9wG9LL5ToiDqrLEP9GX9mw==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.2.tgz", + "integrity": "sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==", "dev": true, - "peer": true, + "license": "MIT", "dependencies": { - "tabbable": "^5.3.3" + "tabbable": "^6.2.0" } }, "node_modules/focus-trap-vue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/focus-trap-vue/-/focus-trap-vue-1.1.1.tgz", - "integrity": "sha512-N+M4d4uYymCogct417gUL7wWSMIW/oUcCicfg3eRdo+gz7jlQnIGwUwViFxPkKV7iyzpc81g6JeSxRWiYWU3eQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/focus-trap-vue/-/focus-trap-vue-4.0.3.tgz", + "integrity": "sha512-cIX5rybkCAlNZ4IHYJ3nCFIsipDDljJHHjtTO2IgYWkVYg7X9ipUVdab3HzYp88kmHgMwjcB71LYnXRRsF6ZqQ==", "dev": true, + "license": "MIT", "peerDependencies": { - "focus-trap": "^6.0.1", - "vue": "^2.6.0" + "focus-trap": "^7.0.0", + "vue": "^3.0.0" } }, "node_modules/follow-redirects": { @@ -9017,13 +8618,34 @@ } } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", "dev": true, + "license": "ISC", "dependencies": { - "is-callable": "^1.1.3" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/form-data": { @@ -9041,10 +8663,11 @@ } }, "node_modules/fraction.js": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.6.tgz", - "integrity": "sha512-n2aZ9tNfYDwaHhvFTkhFErqOMIb8uyzSQ+vGJBjZyanAKZVbGUQ1sngfk9FdkBw7G26O7AgNjLcecLffD1c7eg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, @@ -9105,39 +8728,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -9161,6 +8751,7 @@ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dev": true, + "optional": true, "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -9192,22 +8783,38 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/gettext-extractor": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/gettext-extractor/-/gettext-extractor-3.8.0.tgz", + "integrity": "sha512-i/3mDQufQoJd2/EKm/B+VlaYrt3yGjVfLZu8DQpESKH29klNiW6z2S89FVCIEB85bDNgtGCeM/3A/yR1njr/Lw==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "@types/glob": "5 - 7", + "@types/parse5": "^5", + "css-selector-parser": "^1.3", + "glob": "5 - 7", + "parse5": "5 - 6", + "pofile": "1.0.x", + "typescript": "4 - 5" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, + "node_modules/gettext-extractor/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/gettext-extractor/node_modules/pofile": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pofile/-/pofile-1.0.11.tgz", + "integrity": "sha512-Vy9eH1dRD9wHjYt/QqXcTz+RnX/zg53xK+KljFSX30PvdDMb2z+c6uDUeblUGqqJgz3QFsdlA0IJvHziPmWtQg==", + "dev": true + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -9255,26 +8862,12 @@ "node": ">=4" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -9290,18 +8883,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -9312,7 +8893,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/growly": { "version": "1.3.0", @@ -9332,34 +8914,14 @@ "node": ">= 0.4.0" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=4" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/has-proto": { @@ -9367,6 +8929,7 @@ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, + "optional": true, "engines": { "node": ">= 0.4" }, @@ -9379,6 +8942,7 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, + "optional": true, "engines": { "node": ">= 0.4" }, @@ -9391,6 +8955,7 @@ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, + "optional": true, "dependencies": { "has-symbols": "^1.0.2" }, @@ -9402,25 +8967,11 @@ } }, "node_modules/hash-sum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", - "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==", - "dev": true - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true + "license": "MIT" }, "node_modules/highlight.js": { "version": "10.5.0", @@ -9431,18 +8982,6 @@ "node": "*" } }, - "node_modules/hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha512-M5ezZw4LzXbBKMruP+BNANf0k+19hDQMgpzBIYnya//Al+fjNct9Wf3b1WedLqdEs2hKBvxq/jh+DsHJLj0F9A==", - "dev": true - }, - "node_modules/hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha512-7Wn5GMLuHBjZCb2bTmnDOycho0p/7UVaAeqXZGbHrBCl6Yd/xDhQJAXe6Ga9AXJH2I5zY1dEdYw2u1UptnSBJA==", - "dev": true - }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -9575,10 +9114,11 @@ ] }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -9660,12 +9200,6 @@ "node": ">=8" } }, - "node_modules/indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", - "dev": true - }, "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -9688,20 +9222,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -9711,47 +9231,12 @@ "node": ">= 0.10" } }, - "node_modules/is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha512-vOx7VprsKyllwjSkLV79NIhpyLfr3jAp7VaTCMXOJHu4m0Ew1CZ2fcjASwmV1jI3BWuWHB013M48eyeldk9gYg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -9764,54 +9249,12 @@ "node": ">=8" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "dev": true }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha512-H1U8Vz0cfXNujrJzEcvvwMDW9Ra+biSYA3ThdQvAnMLJkEHQXn6bWzLkxHtVYJ+Sdbx0b6finn3jZiaVe7MAHA==", - "dev": true, - "dependencies": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, "node_modules/is-core-module": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", @@ -9824,30 +9267,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-docker": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", @@ -9922,18 +9341,6 @@ "node": ">=8" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -9943,30 +9350,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -9981,121 +9364,43 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true, - "optional": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "isobject": "^3.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "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==", + "dev": true + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true, + "optional": true + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, + "optional": true, "dependencies": { - "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" }, "engines": { @@ -10105,16 +9410,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2" + "engines": { + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-wsl": { @@ -10189,15 +9494,6 @@ "node": ">=10" } }, - "node_modules/istanbul-lib-report/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-report/node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -10252,6 +9548,25 @@ "node": ">=8" } }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/javascript-stringify": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-1.6.0.tgz", @@ -10372,15 +9687,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-circus/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-circus/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10469,15 +9775,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-cli/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10578,15 +9875,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-config/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-config/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10657,15 +9945,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-diff/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-diff/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10749,15 +10028,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-each/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-each/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -10848,15 +10118,6 @@ "fsevents": "^2.3.2" } }, - "node_modules/jest-haste-map/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-haste-map/node_modules/jest-worker": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", @@ -10872,21 +10133,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-haste-map/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/jest-junit": { "version": "16.0.0", "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", @@ -10973,15 +10219,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-matcher-utils/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11057,15 +10294,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-message-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-message-util/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11194,15 +10422,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-resolve/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-resolve/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11290,15 +10509,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-runner/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runner/node_modules/jest-worker": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", @@ -11427,15 +10637,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-runtime/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-runtime/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11522,15 +10723,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-snapshot/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-snapshot/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11603,15 +10795,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-util/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-util/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11696,15 +10879,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-validate/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11779,15 +10953,6 @@ "node": ">=7.0.0" } }, - "node_modules/jest-watcher/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-watcher/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11814,15 +10979,6 @@ "node": ">= 10.13.0" } }, - "node_modules/jest-worker/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-worker/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -11835,6 +10991,16 @@ "node": ">=8" } }, + "node_modules/jiti": { + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/jquery": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", @@ -11897,7 +11063,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", @@ -11970,23 +11137,18 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -12187,11 +11349,19 @@ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", "dev": true }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", @@ -12211,12 +11381,6 @@ "integrity": "sha512-kn1IDX0aHfg0FsnPIyxCHTamZXt3YK3aExRH1LW8YhzP6+sCldTm8+E4aIg+nSmM6R4eqdWGrXWtfYI961bwIw==", "dev": true }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -12228,21 +11392,18 @@ "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/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", - "dev": true, - "optional": true, + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -12293,15 +11454,6 @@ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, - "node_modules/merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "dependencies": { - "source-map": "^0.6.1" - } - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -12359,54 +11511,26 @@ "engines": { "node": ">=6" } - }, - "node_modules/mini-css-extract-plugin": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.1.tgz", - "integrity": "sha512-jIOheqh9EU98rqj6ZaFTYNNDSFqdakNqaUZfkYwaXPjI9batmXVXX+K71NrqRAgtoGefELBMld1EQ7dqSAD5SQ==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", - "webpack-sources": "^1.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.4.0 || ^5.0.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" + }, + "peerDependencies": { + "webpack": "^5.0.0" } }, "node_modules/minimatch": { @@ -12504,10 +11628,11 @@ "dev": true }, "node_modules/mitt": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", - "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==", - "dev": true + "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/mkdirp": { "version": "1.0.4", @@ -12552,16 +11677,16 @@ } }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "dev": true, + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -12611,10 +11736,11 @@ } }, "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==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", @@ -12686,78 +11812,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.getownpropertydescriptors": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.6.tgz", - "integrity": "sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==", - "dev": true, - "dependencies": { - "array.prototype.reduce": "^1.0.5", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.21.2", - "safe-array-concat": "^1.0.0" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -12965,6 +12019,43 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -13000,10 +12091,10 @@ "optional": true }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -13026,6 +12117,60 @@ "node": ">=6" } }, + "node_modules/pinia": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.2.8.tgz", + "integrity": "sha512-NRTYy2g+kju5tBRe0oNlriZIbMNvma8ZJrpHsp3qudyiMEA8jMmPPKQ2QMHg0Oc4BkUyQYWagACabrwriCK9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.5.11" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pinia/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/pirates": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", @@ -13145,19 +12290,27 @@ "dev": true }, "node_modules/portal-vue": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-2.1.7.tgz", - "integrity": "sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/portal-vue/-/portal-vue-3.0.0.tgz", + "integrity": "sha512-9eprMxNURLx6ijbcgkWjYNcTWJYu/H8QF8nyAeBzOmk9lKCea01BW1hYBeLkgz+AestmPOvznAEOFmNuO4Adjw==", "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.19" + }, "peerDependencies": { - "vue": "^2.5.18" + "vue": "^3.0.4" + }, + "peerDependenciesMeta": { + "vue": { + "optional": true + } } }, "node_modules/postcss": { - "version": "8.4.31", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", - "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", - "dev": true, + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "funding": [ { "type": "opencollective", @@ -13172,10 +12325,11 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -13313,45 +12467,82 @@ } }, "node_modules/postcss-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.1.0.tgz", - "integrity": "sha512-vbCkP70F3Q9PIk6d47aBwjqAMI4LfkXCoyxj+7NPNuVIwfTGdzv2KVQes59/RuxMniIgsYQCFSY42P3+ykJfaw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", "dev": true, + "license": "MIT", "dependencies": { - "cosmiconfig": "^7.0.0", - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, - "node_modules/postcss-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "node_modules/postcss-loader/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/postcss-loader/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">=14" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss-loader/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, "node_modules/postcss-merge-longhand": { @@ -13475,10 +12666,11 @@ } }, "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "dev": true, + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -13487,13 +12679,14 @@ } }, "node_modules/postcss-modules-local-by-default": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz", - "integrity": "sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.1.0.tgz", + "integrity": "sha512-rm0bdSv4jC3BDma3s9H19ZddW0aHX6EoqwDYU2IfZhRN+53QrufTRo2IdkAbRqLx4R2IYbZnbjKKxg4VN5oU9Q==", "dev": true, + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", + "postcss-selector-parser": "^7.0.0", "postcss-value-parser": "^4.1.0" }, "engines": { @@ -13503,13 +12696,28 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "dev": true, + "license": "ISC", "dependencies": { - "postcss-selector-parser": "^6.0.4" + "postcss-selector-parser": "^7.0.0" }, "engines": { "node": "^10 || ^12 || >= 14" @@ -13518,6 +12726,20 @@ "postcss": "^8.1.0" } }, + "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz", + "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss-modules-values": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", @@ -13761,10 +12983,11 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -13924,22 +13147,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "optional": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -13972,15 +13179,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", @@ -14010,12 +13208,6 @@ "node": ">= 6" } }, - "node_modules/pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -14183,16 +13375,6 @@ } ] }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "dev": true, - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -14343,13 +13525,15 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", "dev": true, + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -14359,58 +13543,31 @@ }, "node_modules/regenerator-runtime": { "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true - }, - "node_modules/regenerator-transform": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.8.4" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "node_modules/regenerator-transform": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", + "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" } }, "node_modules/regexpu-core": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.1.0", - "regjsparser": "^0.9.1", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -14418,27 +13575,26 @@ "node": ">=4" } }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "jsesc": "~0.5.0" + "jsesc": "~3.0.2" }, "bin": { "regjsparser": "bin/parser" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -14542,18 +13698,6 @@ "node": ">=0.10.0" } }, - "node_modules/rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha512-gDK5mkALDFER2YLqH6imYvK6g02gpNGM4ILDZ472EwWfXZnC2ZEpoB2ECXTyOVUKuk/bPJZMzwQPBYICzP+D3w==", - "dev": true - }, - "node_modules/rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha512-zgn5OjNQXLUTdq8m17KdaicF6w89TZs8ZU8y0AYENIU6wG8GG6LLm0yLSiPY8DmaYmHdgRW8rnApjoT0fQRfMg==", - "dev": true - }, "node_modules/rgbcolor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", @@ -14602,50 +13746,12 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -14705,32 +13811,30 @@ } }, "node_modules/sass-loader": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.4.1.tgz", - "integrity": "sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.4.tgz", + "integrity": "sha512-LavLbgbBGUt3wCiYzhuLLu65+fWXaXLmq7YxivLhEqmiupCFZ5sKUAipK3do6V80YSU0jvSxNhEdT13IXNr3rg==", "dev": true, + "license": "MIT", "dependencies": { - "klona": "^2.0.4", - "loader-utils": "^2.0.0", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "semver": "^7.3.2" + "neo-async": "^2.6.2" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", "sass": "^1.3.0", - "webpack": "^4.36.0 || ^5.0.0" + "sass-embedded": "*", + "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "fibers": { + "@rspack/core": { "optional": true }, "node-sass": { @@ -14738,33 +13842,15 @@ }, "sass": { "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true } } }, - "node_modules/sass-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -14778,23 +13864,62 @@ } }, "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 8.9.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" } }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/select2": { "version": "4.0.13", "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.13.tgz", @@ -14802,13 +13927,11 @@ "dev": true }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -14816,24 +13939,6 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", @@ -14905,41 +14010,12 @@ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", "dev": true }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -14955,55 +14031,11 @@ "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, "node_modules/sortablejs": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz", - "integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A==", - "dev": true + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz", + "integrity": "sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==", + "license": "MIT" }, "node_modules/source-list-map": { "version": "2.0.1", @@ -15021,10 +14053,10 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -15155,56 +14187,41 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -15243,41 +14260,20 @@ } }, "node_modules/style-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", - "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/style-loader/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", + "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, + "license": "MIT", "engines": { - "node": ">= 10.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.27.0" } }, "node_modules/stylehacks": { @@ -15313,15 +14309,19 @@ } }, "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==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/supports-preserve-symlinks-flag": { @@ -15430,49 +14430,11 @@ "dev": true }, "node_modules/tabbable": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-5.3.3.tgz", - "integrity": "sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA==", - "dev": true, - "peer": true - }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "license": "MIT" }, "node_modules/tablesorter": { "version": "2.31.3", @@ -15525,10 +14487,11 @@ "dev": true }, "node_modules/terser": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.2.tgz", - "integrity": "sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w==", + "version": "5.34.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.34.1.tgz", + "integrity": "sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -15708,27 +14671,12 @@ "readable-stream": "2 || 3" } }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "dev": true - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, - "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, - "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", @@ -15785,22 +14733,24 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" } }, "node_modules/ts-loader": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.0.tgz", - "integrity": "sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", @@ -15859,15 +14809,6 @@ "node": ">=7.0.0" } }, - "node_modules/ts-loader/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ts-loader/node_modules/source-map": { "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", @@ -15889,6 +14830,13 @@ "node": ">=8" } }, + "node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "dev": true, + "license": "0BSD" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -15922,25 +14870,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "devOptional": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15949,26 +14884,22 @@ "node": ">=14.17" } }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "node_modules/typical": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", + "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -15978,6 +14909,7 @@ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -15987,10 +14919,11 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -16000,22 +14933,11 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", - "dev": true - }, - "node_modules/uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha512-mZdDpf3vBV5Efh29kMw5tXoup/buMgxLzOt/XKFKcVmi+15ManNQWr6HfZ2aiZTYlYixbdNJ0KFmIZIv52tHSQ==", - "dev": true - }, "node_modules/unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", @@ -16043,16 +14965,10 @@ "node": ">= 4.0.0" } }, - "node_modules/unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==", - "dev": true - }, "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.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -16068,9 +14984,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -16104,21 +15021,6 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, - "node_modules/util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/utrie": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", @@ -16138,12 +15040,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/v8-to-istanbul": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz", @@ -16164,16 +15060,6 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, - "node_modules/vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/vlq": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", @@ -16190,36 +15076,43 @@ "node": ">=0.10.0" } }, - "node_modules/vrp-vue-resizable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/vrp-vue-resizable/-/vrp-vue-resizable-1.2.7.tgz", - "integrity": "sha512-pmhapoAQeTd/ci7pkyeALW98O9hNRqb84vLQqvCOTDnJZBhxq59qGCegKDrYOvI/KBkeaxdQOEfSHD9i1Bkk7A==", - "dev": true, + "node_modules/vue": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz", + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" + }, "peerDependencies": { - "vue": "2.x" + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/vue": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/vue/-/vue-2.7.14.tgz", - "integrity": "sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==", + "node_modules/vue-dragscroll": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/vue-dragscroll/-/vue-dragscroll-4.0.6.tgz", + "integrity": "sha512-zW1k58p41yhmFhmg/JxfesUM4Srl0JfXg7xSINqffVGpHJKvnEHMK4QgF6mUVkPMTgibn976fhPYkomcXPvvFA==", "dev": true, + "license": "MIT", "dependencies": { - "@vue/compiler-sfc": "2.7.14", - "csstype": "^3.1.0" + "vue": "^3.2.37" } }, - "node_modules/vue-dragscroll": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vue-dragscroll/-/vue-dragscroll-3.0.1.tgz", - "integrity": "sha512-4Oq3S1RGm94YMy/DcjcvM+itRLoTGnKaxlpUUVICPPkNEvMMKzArZUNDXxmDInVa8t4GtrfM0uGAShFP+0JIUw==", - "dev": true - }, "node_modules/vue-eslint-parser": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz", - "integrity": "sha512-Clr85iD2XFZ3lJ52/ppmUDG/spxQu6+MAeHXjjyI4I1NUYZ9xmenQp4N0oaHJhrA8OOxltCVxMRfANGa70vU0g==", + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", + "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4", "eslint-scope": "^7.1.1", @@ -16239,18 +15132,6 @@ "eslint": ">=6.0.0" } }, - "node_modules/vue-eslint-parser/node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/vue-eslint-parser/node_modules/eslint-scope": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", @@ -16267,248 +15148,385 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", - "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz", + "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/vue-eslint-parser/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vue-loader": { + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.4.2.tgz", + "integrity": "sha512-yTKOA4R/VN4jqjw4y5HrynFL8AK0Z3/Jt7eOJXEitsm0GMRHDBjCfCiuTiLP7OESvsZYo2pATCWhDqxC5ZrM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "watchpack": "^2.4.0" + }, + "peerDependencies": { + "webpack": "^4.1.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/vue-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/vue-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/vue-loader/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/vue-loader/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vue-resizable": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/vue-resizable/-/vue-resizable-2.1.7.tgz", + "integrity": "sha512-zEbWhRR8iXT8+nt3u8rkfrNpkPNsPkf7HteBh+AlPIsJ7rf9fyNwMqr0Q4FRzIpNIpZD5Zrr4+3+YELU0vc1Iw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue-router": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.0.tgz", + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-select": { + "version": "4.0.0-beta.6", + "resolved": "https://registry.npmjs.org/vue-select/-/vue-select-4.0.0-beta.6.tgz", + "integrity": "sha512-K+zrNBSpwMPhAxYLTCl56gaMrWZGgayoWCLqe5rWwkB8aUbAUh7u6sXjIR7v4ckp2WKC7zEEUY27g6h1MRsIHw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "vue": "3.x" + } + }, + "node_modules/vue-typer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vue-typer/-/vue-typer-1.2.0.tgz", + "integrity": "sha512-o0n2F9yOnbdQak1OiPFbZonIzysL5jiS1OPgaEX0KnMlKqXRKi808QHRdoMuqw44oYQM/vtxCt3AaNb9OzKH1Q==", + "dev": true, + "dependencies": { + "lodash.split": "^4.4.2" + } + }, + "node_modules/vue3-gettext": { + "version": "3.0.0-beta.5", + "resolved": "https://registry.npmjs.org/vue3-gettext/-/vue3-gettext-3.0.0-beta.5.tgz", + "integrity": "sha512-Dn1qZrFgtaKg/9mMMypvQn+lyyHPAAylQBN4kPGqqr8oAMOJGyKg+rCLCcoyuLGLDvPGBgtawOTQ/0dFmGbDrw==", "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "command-line-args": "^5.2.1", + "cosmiconfig": "^9.0.0", + "gettext-extractor": "^3.8.0", + "glob": "^10.4.1", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "pofile": "^1.1.4", + "tslib": "^2.6.2" + }, + "bin": { + "vue-gettext-compile": "dist/bin/gettext_compile.js", + "vue-gettext-extract": "dist/bin/gettext_extract.js" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 18.0.0" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "@vue/compiler-sfc": ">=3.0.0", + "vue": ">=3.0.0" } }, - "node_modules/vue-eslint-parser/node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "node_modules/vue3-gettext/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "color-convert": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/vue-eslint-parser/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/vue3-gettext/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, - "engines": { - "node": ">=4.0" - } + "license": "Python-2.0" }, - "node_modules/vue-gettext": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/vue-gettext/-/vue-gettext-2.1.12.tgz", - "integrity": "sha512-7Kw36xtKvARp8ZafQGPK9WR6EM+dhFUikR5f0+etSkiHuvUM3yf1HsRDLYoLLdJ0AMaXxKwgekumzvCk6KX8rA==", + "node_modules/vue3-gettext/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "engines": { - "npm": ">= 3.0.0" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/vue-hot-reload-api": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", - "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", - "dev": true - }, - "node_modules/vue-loader": { - "version": "15.10.2", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.10.2.tgz", - "integrity": "sha512-ndeSe/8KQc/nlA7TJ+OBhv2qalmj1s+uBs7yHDRFaAXscFTApBzY9F1jES3bautmgWjDlDct0fw8rPuySDLwxw==", + "node_modules/vue3-gettext/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { - "@vue/component-compiler-utils": "^3.1.0", - "hash-sum": "^1.0.2", - "loader-utils": "^1.1.0", - "vue-hot-reload-api": "^2.3.0", - "vue-style-loader": "^4.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, - "peerDependencies": { - "css-loader": "*", - "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" + "engines": { + "node": ">=10" }, - "peerDependenciesMeta": { - "cache-loader": { - "optional": true - }, - "prettier": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/vue-loader/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "node_modules/vue3-gettext/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { - "minimist": "^1.2.0" + "color-name": "~1.1.4" }, - "bin": { - "json5": "lib/cli.js" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/vue-loader/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "node_modules/vue3-gettext/node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/vue-router": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz", - "integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==", - "dev": true - }, - "node_modules/vue-select": { - "version": "3.20.2", - "resolved": "https://registry.npmjs.org/vue-select/-/vue-select-3.20.2.tgz", - "integrity": "sha512-ZSzIDzyYsWZULGUxVp1h6u3yi9IZQBWX8r6kSudUI/I5J1HQKpBjRntvkrg6pr87xmm16kdChvHCDN+W84vTKw==", - "dev": true, + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, "peerDependencies": { - "vue": "2.x" - } - }, - "node_modules/vue-style-loader": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", - "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", - "dev": true, - "dependencies": { - "hash-sum": "^1.0.2", - "loader-utils": "^1.0.2" + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/vue-style-loader/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "node_modules/vue3-gettext/node_modules/glob": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz", + "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==", "dev": true, + "license": "ISC", "dependencies": { - "minimist": "^1.2.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "path-scurry": "^1.11.1" }, "bin": { - "json5": "lib/cli.js" + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vue-style-loader/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "node_modules/vue3-gettext/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" + "argparse": "^2.0.1" }, - "engines": { - "node": ">=4.0.0" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/vue-template-babel-compiler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vue-template-babel-compiler/-/vue-template-babel-compiler-1.2.0.tgz", - "integrity": "sha512-CScBSX1/wCdmmZ/Lvj/63p2CCVTS0FMj0F69VRBo73CuJrjvPAPGmeNJ7D/cwt/VS2PduowRWbO8N4Zh4Z3b0g==", + "node_modules/vue3-gettext/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, + "license": "ISC", "dependencies": { - "@babel/core": "^7.14.3", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.14.5", - "@babel/plugin-proposal-object-rest-spread": "^7.15.6", - "@babel/plugin-proposal-optional-chaining": "^7.14.2", - "@babel/plugin-transform-arrow-functions": "^7.14.5", - "@babel/plugin-transform-block-scoping": "^7.14.5", - "@babel/plugin-transform-computed-properties": "^7.14.5", - "@babel/plugin-transform-destructuring": "^7.14.5", - "@babel/plugin-transform-parameters": "^7.14.5", - "@babel/plugin-transform-spread": "^7.14.5", - "@babel/types": "^7.14.5", - "deepmerge": "^4.2.2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=12.0.0" + "node": ">=16 || 14 >=14.17" }, - "peerDependencies": { - "vue-template-compiler": "^2.6.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/vue-template-compiler": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.14.tgz", - "integrity": "sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==", + "node_modules/vue3-gettext/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "node_modules/vue-template-es2015-compiler": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", - "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", - "dev": true - }, - "node_modules/vue-twentytwenty": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/vue-twentytwenty/-/vue-twentytwenty-0.10.1.tgz", - "integrity": "sha512-QyfmJ5agedN3rbNZwhKLQFTSScGXReaI6FIHtoCm0kyPgm7n0IzoMg1opXXz+SRCFXm7jjxOArtQta9Nv9u+cQ==", - "dev": true + "node_modules/vue3-gettext/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true, + "license": "MIT" }, - "node_modules/vue-typer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vue-typer/-/vue-typer-1.2.0.tgz", - "integrity": "sha512-o0n2F9yOnbdQak1OiPFbZonIzysL5jiS1OPgaEX0KnMlKqXRKi808QHRdoMuqw44oYQM/vtxCt3AaNb9OzKH1Q==", + "node_modules/vue3-gettext/node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "dev": true, + "license": "MIT", "dependencies": { - "lodash.split": "^4.4.2" + "parse5": "^6.0.1" } }, - "node_modules/vue/node_modules/@vue/compiler-sfc": { - "version": "2.7.14", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.14.tgz", - "integrity": "sha512-aNmNHyLPsw+sVvlQFQ2/8sjNuLtK54TC6cuKnVzAY93ks4ZBrvwQSnkkIh7bsbNhum5hJBS00wSDipQ937f5DA==", + "node_modules/vue3-gettext/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.18.4", - "postcss": "^8.4.14", - "source-map": "^0.6.1" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/vuedraggable": { - "version": "2.24.3", - "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz", - "integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz", + "integrity": "sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==", + "license": "MIT", "dependencies": { - "sortablejs": "1.10.2" + "sortablejs": "1.14.0" + }, + "peerDependencies": { + "vue": "^3.0.1" } }, "node_modules/vuex": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.2.tgz", - "integrity": "sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vuex/-/vuex-4.1.0.tgz", + "integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.0.0-beta.11" + }, "peerDependencies": { - "vue": "^2.0.0" + "vue": "^3.2.0" } }, "node_modules/w3c-xmlserializer": { @@ -16533,10 +15551,11 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -16564,34 +15583,34 @@ } }, "node_modules/webpack": { - "version": "5.88.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.2.tgz", - "integrity": "sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", + "version": "5.97.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.0.tgz", + "integrity": "sha512-CWT8v7ShSfj7tGs4TLRtaOLmOCPWhoKEvp+eA7FVx8Xrjb3XfT0aXdxDItnRZmE8sHcH+a8ayDrJCOjXKxVFfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -16611,44 +15630,43 @@ } }, "node_modules/webpack-cli": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.10.0.tgz", - "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, + "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.2.0", - "@webpack-cli/info": "^1.5.0", - "@webpack-cli/serve": "^1.7.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", "colorette": "^2.0.14", - "commander": "^7.0.0", + "commander": "^10.0.1", "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", "webpack-merge": "^5.7.3" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=10.13.0" + "node": ">=14.15.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "4.x.x || 5.x.x" + "webpack": "5.x.x" }, "peerDependenciesMeta": { "@webpack-cli/generators": { "optional": true }, - "@webpack-cli/migrate": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -16657,25 +15675,37 @@ } } }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/webpack-cli/node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=10.13.0" } }, "node_modules/webpack-cli/node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, + "license": "MIT", "dependencies": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 10.13.0" } }, "node_modules/webpack-cli/node_modules/webpack-merge": { @@ -16692,16 +15722,18 @@ } }, "node_modules/webpack-merge": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.4.0.tgz", - "integrity": "sha512-/scBgu8LVPlHDgqH95Aw1xS+L+PHrpHKOwYVGFaNOQl4Q4wwwWDarwB1WdZAbLQ24SKhY3Awe7VZGYAdp+N+gQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" + "flat": "^5.0.2", + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-notifier": { @@ -16736,10 +15768,11 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -16747,29 +15780,12 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/webpack/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/webpack/node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -16784,6 +15800,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -16798,40 +15815,27 @@ } }, "node_modules/webpack/node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, - "node_modules/webpack/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/webpack/node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -16913,42 +15917,6 @@ "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", @@ -16988,6 +15956,54 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -17089,7 +16105,8 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", diff --git a/package.json b/package.json index b716f57ec3ab88dfbe7ea7fbe51711794005e9fe..89c6b41fbb9b0b90413a26d0ae6b2ec6fc88ad6b 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ }, "devDependencies": { "@axe-core/playwright": "^4.6.1", - "@babel/core": "^7.17.9", - "@babel/eslint-parser": "^7.17.0", + "@babel/core": "^7.26.0", + "@babel/eslint-parser": "^7.25.9", "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-runtime": "^7.12.1", - "@babel/preset-env": "^7.12.1", - "@babel/register": "^7.12.1", + "@babel/plugin-transform-runtime": "^7.25.9", + "@babel/preset-env": "^7.26.0", + "@babel/register": "^7.25.9", "@ckeditor/ckeditor5-alignment": "^36.x", "@ckeditor/ckeditor5-autoformat": "^36.x", "@ckeditor/ckeditor5-basic-styles": "^36.x", @@ -55,8 +55,7 @@ "@ckeditor/ckeditor5-theme-lark": "^36.x", "@ckeditor/ckeditor5-typing": "^36.x", "@ckeditor/ckeditor5-upload": "^36.x", - "@ckeditor/ckeditor5-vue2": "^3.0.1", - "@elan-ev/reststate-vuex": "~1.0.5", + "@ckeditor/ckeditor5-vue": "^5.1.0", "@fullcalendar/core": "^4.3.1", "@fullcalendar/daygrid": "^4.3.0", "@fullcalendar/interaction": "^4.3.0", @@ -64,17 +63,17 @@ "@fullcalendar/resource-timegrid": "^4.3.0", "@fullcalendar/resource-timeline": "^4.3.0", "@fullcalendar/timegrid": "^4.3.0", - "@johmun/vue-tags-input": "^2.1.0", "@playwright/test": "^1.33.0", "@popperjs/core": "^2.11.2", "@types/jquery": "^3.5.16", "@types/jqueryui": "^1.12.16", "@types/lodash": "^4.14.191", - "@vue/eslint-config-typescript": "^12.0.0", + "@vue/compiler-sfc": "^3.5.13", + "@vue/eslint-config-typescript": "^13.0.0", "altcha": "^0.3.2", - "autoprefixer": "^10.2.5", + "autoprefixer": "^10.4.20", "axios": "^0.21.0", - "babel-loader": "^8.2.1", + "babel-loader": "^9.2.1", "blueimp-file-upload": "10.31.0", "buffer": "^6.0.3", "chart.js": "^2.9.4", @@ -82,18 +81,19 @@ "ckeditor5-math": "^36.x", "colorpare": "^2.2.0", "cropperjs": "1.5.9", - "css-loader": "^5.0.1", - "css-minimizer-webpack-plugin": "^1.1.5", + "css-loader": "^7.1.2", + "css-minimizer-webpack-plugin": "^7.0.0", "dotenv": "^16.0.3", "easygettext": "^2.17.0", "es6-promise": "4.2.8", - "eslint": "^7.32.0", - "eslint-plugin-vue": "^9.10.0", - "eslint-webpack-plugin": "^3.1.1", - "expose-loader": "1.0.1", + "eslint": "^8.57.1", + "eslint-plugin-vue": "^9.28.0", + "eslint-webpack-plugin": "^4.2.0", + "expose-loader": "^5.0.0", "favico.js": "0.3.10", "file-saver": "^2.0.5", - "focus-trap-vue": "^1.1.1", + "focus-trap": "^7.6.2", + "focus-trap-vue": "^4.0.3", "highlight.js": "10.5.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", @@ -109,43 +109,41 @@ "jszip": "^3.8.0", "lodash": "^4.17.20", "md5": "^2.3.0", - "mini-css-extract-plugin": "1.3.1", - "mitt": "2.1.0", + "mini-css-extract-plugin": "^2.9.2", + "mitt": "^3.0.1", "mp3tag.js": "3.7.1", "multiselect": "0.9.12", "pdfjs-dist": "^2.6.347", - "portal-vue": "^2.1.7", - "postcss": "^8.1.8", - "postcss-loader": "4.1.0", + "pinia": "^2.2.8", + "portal-vue": "^3.0.0", + "postcss": "^8.4.49", + "postcss-loader": "^8.1.1", "postcss-scss": "^4.0.4", "raw-loader": "^4.0.2", "sanitize-html": "^2.7.0", "sass": "^1.29.0", - "sass-loader": "^10.1.0", + "sass-loader": "^16.0.4", "select2": "4.0.13", "sprintf-js": "^1.0.3", "stream-browserify": "^3.0.0", - "style-loader": "^2.0.0", + "style-loader": "^4.0.0", "svgo": "3.3.2", "tablesorter": "2.31.3", - "ts-loader": "^9.4.2", - "typescript": "^5.0.2", - "vrp-vue-resizable": "1.2.7", - "vue": "^2.7.14", - "vue-dragscroll": "^3.0.1", - "vue-gettext": "^2.1.12", - "vue-loader": "^15.9.8", - "vue-router": "^3.5.1", - "vue-select": "^3.11.2", - "vue-template-babel-compiler": "^1.2.0", - "vue-template-compiler": "^2.6.12", - "vue-twentytwenty": "^0.10.1", + "ts-loader": "^9.5.1", + "typescript": "^5.7.2", + "vue": "^3.5.13", + "vue-dragscroll": "^4.0.6", + "vue-loader": "^17.4.2", + "vue-resizable": "^2.1.7", + "vue-router": "^4.5.0", + "vue-select": "^4.0.0-beta.6", "vue-typer": "^1.2.0", - "vuedraggable": "^2.24.3", - "vuex": "^3.6.2", - "webpack": "^5.70.0", - "webpack-cli": "^4.10.0", - "webpack-merge": "5.4.0", + "vue3-gettext": "^3.0.0-beta.5", + "vuedraggable": "^4.1.0", + "vuex": "^4.1.0", + "webpack": "^5.97.0", + "webpack-cli": "^5.1.4", + "webpack-merge": "^6.0.1", "webpack-notifier": "^1.15.0" }, "babel": { @@ -171,5 +169,8 @@ }, "eslint-junit": { "output": "./.reports/eslint-report.xml" + }, + "dependencies": { + "@vojtechlanka/vue-tags-input": "^3.1.1" } } diff --git a/resources/assets/javascripts/bootstrap/avatar.js b/resources/assets/javascripts/bootstrap/avatar.js index 31d724dec535e9ae5235975688370fdb07c31021..9c1de1c7a0ccb659528806c1162b5f148236904c 100644 --- a/resources/assets/javascripts/bootstrap/avatar.js +++ b/resources/assets/javascripts/bootstrap/avatar.js @@ -4,13 +4,13 @@ STUDIP.domReady(() => { avatarTypes.forEach((type) => { if (document.getElementById(`avatar-${type}-app`)) { Promise.all([ - STUDIP.loadChunk('avatar'), + STUDIP.loadChunk('vue'), import( /* webpackChunkName: "avatar-app" */ '@/vue/avatar-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, `#avatar-${type}-app`); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, `#avatar-${type}-app`); }); } }); diff --git a/resources/assets/javascripts/bootstrap/courseware.js b/resources/assets/javascripts/bootstrap/courseware.js index b90cc454b47e6955bcea91bd2a5ed789d1a7b005..72503e0deebfe208378c2c2a449d88535e5cecae 100644 --- a/resources/assets/javascripts/bootstrap/courseware.js +++ b/resources/assets/javascripts/bootstrap/courseware.js @@ -6,8 +6,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-shelf-app" */ '@/vue/courseware-shelf-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-shelf-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-shelf-app'); }); } @@ -18,8 +18,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-index-app" */ '@/vue/courseware-index-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-index-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-index-app'); }); } @@ -30,8 +30,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-activities-app" */ '@/vue/courseware-activities-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-activities-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-activities-app'); }); } @@ -42,8 +42,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-tasks-app" */ '@/vue/courseware-tasks-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-tasks-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-tasks-app'); }); } @@ -54,8 +54,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-content-bookmark-app" */ '@/vue/courseware-content-bookmark-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-content-bookmark-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-content-bookmark-app'); }); } @@ -66,8 +66,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-content-bookmark-app" */ '@/vue/courseware-admin-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-admin-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-admin-app'); }); } @@ -78,8 +78,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-public-app" */ '@/vue/courseware-public-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-public-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-public-app'); }); } @@ -90,8 +90,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-content-releases-app" */ '@/vue/courseware-content-releases-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-content-releases-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-content-releases-app'); }); } @@ -102,8 +102,8 @@ STUDIP.domReady(() => { /* webpackChunkName: "courseware-comments-app" */ '@/vue/courseware-comments-app.js' ), - ]).then(([{ createApp }, { default: mountApp }]) => { - return mountApp(STUDIP, createApp, '#courseware-comments-app'); + ]).then(([{ createApp, store }, { default: mountApp }]) => { + return mountApp(STUDIP, createApp, store, '#courseware-comments-app'); }); } diff --git a/resources/assets/javascripts/bootstrap/forms.js b/resources/assets/javascripts/bootstrap/forms.js index e159699421b56a57a8797974e4f505215749b4f9..bd863eb576ecc7a5ff0fb8a3ead7980bd873f207 100644 --- a/resources/assets/javascripts/bootstrap/forms.js +++ b/resources/assets/javascripts/bootstrap/forms.js @@ -1,5 +1,6 @@ -import { $gettext, $gettextInterpolate } from '../lib/gettext'; +import { $gettext } from '../lib/gettext'; import Report from '../lib/report.ts'; +import Dialog from "../lib/dialog"; // Allow fieldsets to collapse $(document).on( @@ -242,12 +243,13 @@ function createSelect2(element) { } STUDIP.ready(function () { - let forms = window.document.querySelectorAll('form.default.studipform:not(.vueified)'); + let forms = window.document.querySelectorAll('.studipform:not(.vueified)'); if (forms.length > 0) { STUDIP.Vue.load().then(({createApp}) => { forms.forEach(f => { - createApp({ - el: f, + f.classList.add('vueified'); + + const app = createApp({ data() { let params = JSON.parse(f.dataset.inputs); params.STUDIPFORM_REQUIRED = f.dataset.required ? JSON.parse(f.dataset.required) : []; @@ -343,9 +345,9 @@ STUDIP.ready(function () { note.description = $(this).data('validation_requirement'); } if (this.validity.tooShort) { - note.description = $gettextInterpolate( - $gettext('Geben Sie mindestens %{min} Zeichen ein.'), - {min: this.minLength} + note.description = $gettext( + 'Geben Sie mindestens %{min} Zeichen ein.', + { min: this.minLength } ); } if (this.validity.valueMissing) { @@ -353,9 +355,9 @@ STUDIP.ready(function () { note.description = $gettext('Dieses Feld muss ausgewählt sein.'); } else { if (this.minLength > 0) { - note.description = $gettextInterpolate( - $gettext('Hier muss ein Wert mit mindestens %{min} Zeichen eingetragen werden.'), - {min: this.minLength} + note.description = $gettext( + 'Hier muss ein Wert mit mindestens %{min} Zeichen eingetragen werden.', + { min: this.minLength } ); } else { note.description = $gettext('Hier muss ein Wert eingetragen werden.'); @@ -419,10 +421,19 @@ STUDIP.ready(function () { return orderedNotes; } }, - mounted () { - $(this.$el).addClass("vueified"); + mounted() { + if (this.$el.closest('.ui-dialog')) { + const cancelButton = this.$el.querySelector('footer .button.cancel:last-of-type'); + if (cancelButton) { + cancelButton.addEventListener('click', (e) => { + Dialog.close(); + e.preventDefault(); + }) + } + } } }); + app.mount(f); }); }); } @@ -435,12 +446,8 @@ STUDIP.ready(function () { if (simple_vue_items.length > 0) { STUDIP.Vue.load().then(({createApp}) => { simple_vue_items.forEach(f => { - createApp({ - el: f, - mounted() { - this.$el.classList.add('vueified'); - } - }); + f.classList.add('vueified'); + createApp().mount(f); }); }); } diff --git a/resources/assets/javascripts/bootstrap/mvv_difflog.js b/resources/assets/javascripts/bootstrap/mvv_difflog.js index 8ade9181925dd45cd2980a6c81cd719e686ca9ed..0d970ec6f0ff0d1092d289be35c3219d9badf4f8 100644 --- a/resources/assets/javascripts/bootstrap/mvv_difflog.js +++ b/resources/assets/javascripts/bootstrap/mvv_difflog.js @@ -1,4 +1,4 @@ -import { $gettext, $gettextInterpolate } from '../lib/gettext'; +import { $gettext } from '../lib/gettext'; STUDIP.domReady(() => { $('del.diffdel').each(function() { @@ -44,8 +44,8 @@ STUDIP.domReady(() => { senddata, function(data) { if (data) { - var info = $gettextInterpolate( - $gettext('Entfernt von %{user} am %{time}'), + var info = $gettext( + 'Entfernt von %{user} am %{time}', data ); del.attr('title', info); @@ -140,8 +140,8 @@ STUDIP.domReady(() => { senddata, function(data) { if (data) { - var info = $gettextInterpolate( - $gettext('Änderung durch %{user} am %{time}'), + var info = $gettext( + 'Änderung durch %{user} am %{time}', data ); ins.attr('title', info); @@ -175,8 +175,8 @@ STUDIP.domReady(() => { ); function onSuccess(data) { if (data) { - var info = $gettextInterpolate( - $gettext('Hinzugefügt von %{user} am %{time}'), + var info = $gettext( + 'Hinzugefügt von %{user} am %{time}', data ); curtable.attr('title', info); @@ -210,8 +210,8 @@ STUDIP.domReady(() => { ); function onSuccess(data) { if (data) { - var info = $gettextInterpolate( - $gettext('Entfernt von %{user} am %{time}'), + var info = $gettext( + 'Entfernt von %{user} am %{time}', data ); curtable.attr('title', info); diff --git a/resources/assets/javascripts/bootstrap/oer.js b/resources/assets/javascripts/bootstrap/oer.js index 2b471496a64a13ba051119b69d50593b4c974831..0854e8bf289918c6de3a286b696265b52dddc468 100644 --- a/resources/assets/javascripts/bootstrap/oer.js +++ b/resources/assets/javascripts/bootstrap/oer.js @@ -1,5 +1,3 @@ -import Quicksearch from '../../../vue/components/Quicksearch.vue'; - STUDIP.domReady(() => { if (jQuery(".oer_search").length) { STUDIP.OER.initSearch(); @@ -55,16 +53,15 @@ STUDIP.ready(() => { if ($('.oercampus_editmaterial').length) { STUDIP.Vue.load().then(({createApp}) => { - STUDIP.OER.EditApp = createApp({ - el: '.oercampus_editmaterial', + const app = createApp({ data() { return { name: $('.oercampus_editmaterial input.oername').val(), - logo_url: $('.oercampus_editmaterial .logo_file').data("oldurl"), - customlogo: $('.oercampus_editmaterial .logo_file').data("customlogo"), + logo_url: $('.oercampus_editmaterial .logo_file').data("oldurl") ?? null, + customlogo: $('.oercampus_editmaterial .logo_file').data("customlogo") == '1', filename: $('.oercampus_editmaterial .file.drag-and-drop').data("filename"), filesize: $('.oercampus_editmaterial .file.drag-and-drop').data("filesize"), - tags: $('.oercampus_editmaterial .oer_tags').data("defaulttags"), + tags: $('.oercampus_editmaterial .oer_tags').data("defaulttags") ?? [], minimumTags: 5 }; }, @@ -87,10 +84,9 @@ STUDIP.ready(() => { }, editImage: function (event) { let reader = new FileReader(); - let vue = this; - reader.addEventListener("load", function () { - vue.logo_url = reader.result; - vue.customlogo = true; + reader.addEventListener("load", () => { + this.logo_url = reader.result; + this.customlogo = true; }, false); reader.readAsDataURL( event.target.files.length > 0 @@ -137,8 +133,9 @@ STUDIP.ready(() => { return result; } }, - components: { Quicksearch } }); + app.mount('.oercampus_editmaterial'); + STUDIP.OER.EditApp = app; }); } }); diff --git a/resources/assets/javascripts/bootstrap/vue.js b/resources/assets/javascripts/bootstrap/vue.js index 513c796cb4322d456ceae43e85cbd0a19accb55a..4b1ac6daf249abd87a62d8ff59c7cc7da809cad9 100644 --- a/resources/assets/javascripts/bootstrap/vue.js +++ b/resources/assets/javascripts/bootstrap/vue.js @@ -1,5 +1,37 @@ +import { defineAsyncComponent } from 'vue'; + +function attachComponents(app, configuredComponents) { + configuredComponents.forEach(component => { + const name = component.split('/').reverse()[0]; + app.component(name, defineAsyncComponent(() => { + const temp = import(`../../../vue/components/${component}.vue`); + temp.then(({default: c}) => { + const mounted = c.mounted ?? null; + c.mounted = function (...args) { + if ( + this.$el instanceof Element + && this.$el.closest('.studip-dialog') + && this.$el.querySelector('[data-dialog-button]') + ) { + this.$el.closest('.studip-dialog') + .querySelector('.ui-dialog-buttonpane') + .remove(); + } + if (mounted) { + mounted.call(this, args); + } + }; + return c; + }) + return temp; + })); + }); +} + STUDIP.ready(() => { - document.querySelectorAll('[data-vue-app]:not([data-vue-app-created])').forEach((node) => { + document.querySelectorAll('[data-vue-app]:not([data-vue-app-created])').forEach(async (node) => { + node.dataset.vueAppCreated = 'true'; + const config = Object.assign( { components: [], @@ -9,96 +41,70 @@ STUDIP.ready(() => { JSON.parse(node.dataset.vueApp) ); - let components = {}; - config.components.forEach(component => { - const name = component.split('/').reverse()[0]; - components[name] = () => { - // TODO: I wonder if this works with Vue3 + const { createApp, store } = await STUDIP.Vue.load(); - const temp = import(`../../../vue/components/${component}.vue`); - temp.then(({default: c}) => { - const mounted = c.mounted ?? null; - c.mounted = function (...args) { - if ( - this.$el instanceof Element - && this.$el.closest('.studip-dialog') - && this.$el.querySelector('[data-dialog-button]') - ) { - this.$el.closest('.studip-dialog') - .querySelector('.ui-dialog-buttonpane') - .remove(); - } - if (mounted) { - mounted.call(this, args); - } - }; - return c; - }) - return temp; - }; - }); + const promises = [Promise.resolve()]; - STUDIP.Vue.load().then(({createApp, store, Vue}) => { - const promises = [Promise.resolve()]; + for (const [index, name] of Object.entries(config.stores)) { + promises.push( + import(`../../../vue/store/${name}.js`).then(storeConfig => { + store.registerModule(index, storeConfig.default); - for (const [index, name] of Object.entries(config.stores)) { - promises.push( - import(`../../../vue/store/${name}.js`).then(storeConfig => { - store.registerModule(index, storeConfig.default); + const dataElement = document.getElementById(`vue-store-data-${index}`); + if (dataElement) { + const data = JSON.parse(dataElement.innerText); + Object.keys(data).forEach(command => { + store.commit(`${index}/${command}`, data[command]); + }); - const dataElement = document.getElementById(`vue-store-data-${index}`); - if (dataElement) { - const data = JSON.parse(dataElement.innerText); - Object.keys(data).forEach(command => { - store.commit(`${index}/${command}`, data[command]); - }); + dataElement.remove(); + } + }) + ); + } - dataElement.remove(); - } - }) - ); - } + const plugins = []; + for (const [plugin, filename] of Object.entries(config.plugins)) { + promises.push( + import(`../../../vue/plugins/${filename}.js`) + .then((temp) => plugins.push(temp[plugin])) + ); + } - for (const [plugin, filename] of Object.entries(config.plugins)) { - promises.push( - import(`../../../vue/plugins/${filename}.js`) - .then((temp) => Vue.use(temp[plugin], { store })) - ); - } + await Promise.all(promises); - Promise.all(promises).then(() => { - createApp({ - components, - store, + const app = createApp({ + store, - beforeCreate() { - STUDIP.Vue.emit('VueAppWillCreate', this); - }, - created() { - STUDIP.Vue.emit('VueAppDidCreate', this); - }, - beforeMount() { - STUDIP.Vue.emit('VueAppWillMount', this); - }, - mounted() { - STUDIP.Vue.emit('VueAppDidMount', this); - }, - beforeUpdate() { - STUDIP.Vue.emit('VueAppWillUpdate', this); - }, - updated() { - STUDIP.Vue.emit('VueAppDidUpdate', this); - }, - beforeDestroy() { - STUDIP.Vue.emit('VueAppWillDestroy', this); - }, - destroyed() { - STUDIP.Vue.emit('VueAppDidDestroy', this); - }, - }).$mount(node); - }); + beforeCreate() { + STUDIP.Vue.emit('VueAppWillCreate', this); + }, + created() { + STUDIP.Vue.emit('VueAppDidCreate', this); + }, + beforeMount() { + STUDIP.Vue.emit('VueAppWillMount', this); + }, + mounted() { + STUDIP.Vue.emit('VueAppDidMount', this); + }, + beforeUpdate() { + STUDIP.Vue.emit('VueAppWillUpdate', this); + }, + updated() { + STUDIP.Vue.emit('VueAppDidUpdate', this); + }, + beforeUnmount() { + STUDIP.Vue.emit('VueAppWillUnmount', this); + }, + unmounted() { + STUDIP.Vue.emit('VueAppDidUnmount', this); + }, }); - node.dataset.vueAppCreated = 'true'; + attachComponents(app, config.components); + plugins.forEach(plugin => app.use(plugin, { store })) + + app.mount(node); }); }); diff --git a/resources/assets/javascripts/chunk-loader.js b/resources/assets/javascripts/chunk-loader.js index 995b35f4d8f4cadaf5ef8f347b9eba9971ddd659..8cb692cf87eba19430c2c4c8419aea3854929545 100644 --- a/resources/assets/javascripts/chunk-loader.js +++ b/resources/assets/javascripts/chunk-loader.js @@ -31,16 +31,6 @@ export const loadChunk = function (chunk, { silent = false } = {}) { ]).then(([Vue]) => Vue); break; - case 'avatar': - promise = Promise.all([ - STUDIP.loadChunk('vue'), - import( - /* webpackChunkName: "avatar" */ - './chunks/avatar' - ), - ]).then(([Vue]) => Vue); - break; - case 'code-highlight': promise = import( /* webpackChunkName: "code-highlight" */ diff --git a/resources/assets/javascripts/chunks/avatar.js b/resources/assets/javascripts/chunks/avatar.js deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/resources/assets/javascripts/chunks/vue.js b/resources/assets/javascripts/chunks/vue.js index 8d506a1dfc8c797a254db29ec796ce1107ff2e1f..80b111ee920231bdb04e95b4fabf91fd5289162a 100644 --- a/resources/assets/javascripts/chunks/vue.js +++ b/resources/assets/javascripts/chunks/vue.js @@ -1,70 +1,89 @@ -import Vue from 'vue'; -import Vuex from 'vuex'; -import Router from "vue-router"; -import eventBus from '../lib/event-bus.ts'; -import GetTextPlugin from 'vue-gettext'; -import { getLocale, getVueConfig } from '../lib/gettext'; +import { createApp as vueCreateApp } from 'vue'; +import { createStore as vuexCreateStore } from 'vuex'; +import eventBus from '../lib/event-bus'; +import gettext from '../lib/gettext'; import PortalVue from 'portal-vue'; import BaseComponents from '../../../vue/base-components.js'; import BaseDirectives from "../../../vue/base-directives.js"; import StudipStore from "../../../vue/store/StudipStore.js"; -import CKEditor from '@ckeditor/ckeditor5-vue2'; +import { resourceModule } from '@/assets/javascripts/lib/reststate-vuex.js'; +import axios from 'axios'; -// Setup gettext -Vue.use(GetTextPlugin, getVueConfig()); -eventBus.on('studip:set-locale', (locale) => { - Vue.config.language = locale; -}) +import CKEditor from '@ckeditor/ckeditor5-vue'; -// Register global components and directives -registerGlobalComponents(); -registerGlobalDirectives(); +const getHttpClient = () => + axios.create({ + baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), + headers: { + 'Content-Type': 'application/vnd.api+json', + }, + }); -// Setup store and default Stud.IP store -Vue.use(Vuex); -const store = new Vuex.Store({}); +const httpClient = getHttpClient(); -store.registerModule('studip', StudipStore); +const createStore = () => { + const store = vuexCreateStore({}); -// Setup router and PortalVue -Vue.use(Router); -Vue.use(PortalVue); + store.registerModule('studip', StudipStore); -// Define our own global mixin for Vue -Vue.mixin({ - methods: { - globalEmit(...args) { - eventBus.emit(...args); - }, - globalOn(...args) { - eventBus.on(...args); - }, - globalOff(...args) { - eventBus.off(...args); - }, - getStudipConfig: store.getters['studip/getConfig'] - }, -}); + STUDIP.jsonapi_schemas.forEach((name) => { + store.registerModule(name, resourceModule({ name, httpClient })); + }); -Vue.use(CKEditor); + return store; +} + +// Setup store +const store = createStore(); // Define createApp function -function createApp(options, ...args) { - Vue.config.language = getLocale(); - return new Vue({ store, ...options }, ...args); +function createApp(options = {}, ...args) { + const app = vueCreateApp({ store, ...options }, ...args); + + app.config.compilerOptions.whitespace = 'condense'; + + // Define our own global mixin for Vue + app.mixin({ + methods: { + globalEmit(...args) { + eventBus.emit(...args); + }, + globalOn(...args) { + eventBus.on(...args); + }, + globalOff(...args) { + eventBus.off(...args); + }, + getStudipConfig: store.getters['studip/getConfig'] + }, + }); + + app.use(CKEditor); + app.use(gettext); + app.use(PortalVue); + app.use(store); + + // Register global components and directives + registerGlobalComponents(app); + registerGlobalDirectives(app); + + if (options.el) { + app.mount(options.el); + } + return app; } // Define global registration functions for components and directives -function registerGlobalComponents() { +function registerGlobalComponents(app) { for (const [name, component] of Object.entries(BaseComponents)) { - Vue.component(name, component); + app.component(name, component); } } -function registerGlobalDirectives() { +function registerGlobalDirectives(app) { for (const [name, directive] of Object.entries(BaseDirectives)) { - Vue.directive(name, directive); + app.directive(name, directive); } } -export { Vue, createApp, eventBus, store }; +export { createApp, eventBus, store, httpClient }; diff --git a/resources/assets/javascripts/jquery-bundle.js b/resources/assets/javascripts/jquery-bundle.js index bd1642260eae74610ced75bd88d8b8d1c3b54b13..bfa9eefcd0c7d49877d0641146039d6ab9c0635a 100644 --- a/resources/assets/javascripts/jquery-bundle.js +++ b/resources/assets/javascripts/jquery-bundle.js @@ -1,6 +1,6 @@ -import 'expose-loader?exposes[]=$&exposes[]=jQuery!jquery'; +import $ from 'expose-loader?exposes=$,jQuery!jquery'; -import { setLocale } from './lib/gettext'; + import { setLocale } from './lib/gettext'; import 'jquery-ui/ui/widget.js'; import 'jquery-ui/ui/position.js'; diff --git a/resources/assets/javascripts/lib/admission.js b/resources/assets/javascripts/lib/admission.js index 4b135118930d467452fbea9e3db376e99a999ce5..992c8be1be85133592234a3079ed16697338118a 100644 --- a/resources/assets/javascripts/lib/admission.js +++ b/resources/assets/javascripts/lib/admission.js @@ -23,7 +23,7 @@ const Admission = { getCourses: function(targetUrl) { var courseFilter = $('input[name="course_filter"]').val(); - if (courseFilter == '') { + if (courseFilter === '') { courseFilter = '%%%'; } var data = { diff --git a/resources/assets/javascripts/lib/blubber.js b/resources/assets/javascripts/lib/blubber.js index 4e724b46cbd0f1cd2c49a691dbb02f0c644420c2..783abe18ae0639298303a7e4530f1a9015319575 100644 --- a/resources/assets/javascripts/lib/blubber.js +++ b/resources/assets/javascripts/lib/blubber.js @@ -1,3 +1,5 @@ +import { resolveComponent, h } from "vue"; + const Blubber = { init() { const blubberPage = document.querySelector('#blubber-index, #messenger-course, .blubber_panel.vueinstance'); @@ -18,12 +20,13 @@ const Blubber = { function connectBlubber(blubberPanel, componentName) { return Promise.all([window.STUDIP.Vue.load(), Blubber.plugin()]).then( ([{ Vue, createApp, store }, BlubberPlugin]) => { - Vue.use(BlubberPlugin, { store }); const { initialThreadId, search } = blubberPanel.dataset; - return createApp({ - el: blubberPanel, - render: (h) => h(Vue.component(componentName), { props: { initialThreadId, search } }), + const app = createApp({ + render: () => h(resolveComponent(componentName), { initialThreadId, search }), }); + app.use(BlubberPlugin, { store }); + app.mount(blubberPanel); + return app; } ); } diff --git a/resources/assets/javascripts/lib/datetime.js b/resources/assets/javascripts/lib/datetime.js index 50f91f22e5b3c19002b74e93ce932016e401407f..04d72605bcbff58d947fcb5f24a01b2044853932 100644 --- a/resources/assets/javascripts/lib/datetime.js +++ b/resources/assets/javascripts/lib/datetime.js @@ -1,4 +1,4 @@ -import { $gettext, $gettextInterpolate } from "./gettext.ts"; +import { $gettext } from "./gettext.ts"; const DateTime = { @@ -43,8 +43,8 @@ const DateTime = { return $gettext('Jetzt'); } if (now - date < 2 * 60 * 60 * 1000) { - return $gettextInterpolate( - $gettext('Vor %{ minutes } Minuten'), + return $gettext( + 'Vor %{ minutes } Minuten', {minutes: Math.floor((now - date) / (1000 * 60))} ); } diff --git a/resources/assets/javascripts/lib/files.js b/resources/assets/javascripts/lib/files.js index d05112decd89b1a6d9cd1154e38790a4ad1c7cfa..39bd8934b28568c65431f7f7cdffafe1a4ea3d79 100644 --- a/resources/assets/javascripts/lib/files.js +++ b/resources/assets/javascripts/lib/files.js @@ -1,6 +1,7 @@ import { $gettext } from './gettext'; import Dialog from './dialog.js'; import FilesTable from '../../../vue/components/FilesTable.vue'; +import { h } from 'vue'; const Files = { init () { @@ -8,8 +9,7 @@ const Files = { && jQuery("#files_table_form").length) { STUDIP.Vue.load().then(({createApp}) => { - this.filesapp = createApp({ - el: "#content", + const app = createApp({ data() { return { files: jQuery("#files_table_form").data("files") || [], @@ -27,6 +27,9 @@ const Files = { } return false; }, + pushFile(file) { + this.files.push(file); + }, removeFile(id) { this.files = this.files.filter(file => file.id != id) }, @@ -36,14 +39,15 @@ const Files = { }); } }, - components: { FilesTable, }, updated () { this.onUpdated(); }, created () { this.onUpdated(); - } + }, }); + app.component('files-table', FilesTable); + this.filesapp = app.mount('#files_table_form'); }); } @@ -258,7 +262,7 @@ const Files = { } } if (insert) { - STUDIP.Files.filesapp.files.push(value); + STUDIP.Files.filesapp.pushFile(value); } }); $(document).trigger('refresh-handlers'); diff --git a/resources/assets/javascripts/lib/gettext.ts b/resources/assets/javascripts/lib/gettext.ts index 23daaaa075e371bd14b74cf7d4fb048792539b90..c63831ebab856f484930033d897edbcc2d07eafc 100644 --- a/resources/assets/javascripts/lib/gettext.ts +++ b/resources/assets/javascripts/lib/gettext.ts @@ -1,4 +1,4 @@ -import { translate } from 'vue-gettext'; +import { createGettext, LanguageData } from 'vue3-gettext'; import * as defaultTranslations from '../../../../locale/de/LC_MESSAGES/js-resources.json'; import eventBus from './event-bus'; @@ -15,73 +15,92 @@ interface InstalledLanguages { [key: string]: InstalledLanguage; } -type TranslationDict = StringDict; +type Translation = LanguageData; -interface TranslationDicts { - [key: string]: TranslationDict | null; -} +type Translations = { + [language: string]: LanguageData; +}; const DEFAULT_LANG = 'de_DE'; const DEFAULT_LANG_NAME = 'Deutsch'; const state = getInitialState(); -const $gettext = translate.gettext.bind(translate); -const $ngettext = translate.ngettext.bind(translate); -const $gettextInterpolate = translate.gettextInterpolate.bind(translate); - -export { $gettext, $ngettext, $gettextInterpolate, translate, getLocale, setLocale, getVueConfig }; +const gettext = createGettext({ + availableLanguages: getAvailableLanguages(), + defaultLanguage: state.locale, + silent: false, + translations: { + [DEFAULT_LANG]: {} + }, + mutedLanguages: [DEFAULT_LANG], + setGlobalProperties: true, + globalProperties: { + language: ['$language'], + gettext: ['$gettext'], + pgettext: ['$pgettext'], + ngettext: ['$ngettext'], + npgettext: ['$npgettext'], + interpolate: ['$gettextInterpolate'], + }, + provideDirective: true, + provideComponent: true, +}); + +setLocale(state.locale); + +export default gettext; + +async function updateTranslations() { + let translations: Translations = {}; + + for (const [key, value] of Object.entries(getAvailableLanguages())) { + if (state.locale === key) { + const translation = await getTranslations(key); + translations[key] = translation; + } + } + gettext.translations = translations; +} -function getLocale() { +export function getLocale() { return state.locale; } -async function setLocale(locale = getInitialLocale()) { +export async function setLocale(locale = getInitialLocale()) { if (!(locale in getInstalledLanguages())) { throw new Error('Invalid locale: ' + locale); } state.locale = locale; if (state.translations[state.locale] === null) { - const translations: TranslationDict = await getTranslations(state.locale); + const translations: Translation = await getTranslations(state.locale); state.translations[state.locale] = translations; } - translate.initTranslations(state.translations, { - getTextPluginMuteLanguages: [DEFAULT_LANG], - getTextPluginSilent: false, - language: state.locale, - silent: false, - }); + updateTranslations(); eventBus.emit('studip:set-locale', state.locale); } -function getVueConfig() { - const availableLanguages = Object.entries(getInstalledLanguages()).reduce((memo, [lang, { name }]) => { +function getAvailableLanguages() { + return Object.entries(getInstalledLanguages()).reduce((memo, [lang, { name }]) => { memo[lang] = name; return memo; }, {} as StringDict); - - return { - availableLanguages, - defaultLanguage: DEFAULT_LANG, - muteLanguages: [DEFAULT_LANG], - silent: false, - translations: state.translations, - }; } + function getInitialState() { - const translations: TranslationDicts = Object.entries(getInstalledLanguages()).reduce((memo, [lang]) => { - memo[lang] = lang === DEFAULT_LANG ? defaultTranslations : null; + const translations: Translations = Object.entries(getInstalledLanguages()).reduce((memo, [lang]) => { + memo[lang] = lang === DEFAULT_LANG ? defaultTranslations : ''; return memo; - }, {} as TranslationDicts); + }, {} as Translations); return { - locale: DEFAULT_LANG, + locale: getInitialLocale(), translations, }; } @@ -100,7 +119,7 @@ function getInstalledLanguages(): InstalledLanguages { return window?.STUDIP?.INSTALLED_LANGUAGES ?? { [DEFAULT_LANG]: { name: DEFAULT_LANG_NAME, selected: true } }; } -async function getTranslations(locale: string): Promise<TranslationDict> { +async function getTranslations(locale: string): Promise<Translation> { try { const language = locale.split(/[_-]/)[0]; const translation = await import(`../../../../locale/${language}/LC_MESSAGES/js-resources.json`); @@ -112,3 +131,7 @@ async function getTranslations(locale: string): Promise<TranslationDict> { return {}; } } + +export const $gettext = gettext.$gettext; +export const $ngettext = gettext.$ngettext; +export const $gettextInterpolate = gettext.interpolate; diff --git a/resources/assets/javascripts/lib/personal_notifications.js b/resources/assets/javascripts/lib/personal_notifications.js index d05fbaa08bb547ced474b6709bd6bc787ed6b635..34890880ca65df24525783670d78c58bc763f21b 100644 --- a/resources/assets/javascripts/lib/personal_notifications.js +++ b/resources/assets/javascripts/lib/personal_notifications.js @@ -1,7 +1,7 @@ import Favico from 'favico.js'; import Cache from './cache.js'; import PageLayout from './page_layout.js'; -import { $gettextInterpolate, $ngettext } from './gettext'; +import { $ngettext } from './gettext'; var stack = {}; var audio_notification = false; @@ -189,8 +189,13 @@ const PersonalNotifications = { } if (old_count !== count) { $('#notification_marker .count').text(count); - let notification_text = $ngettext('%{ count } Benachrichtigung', '%{ count } Benachrichtigungen', count); - $('#notification_marker').attr('title', $gettextInterpolate(notification_text, {count: count})); + let notification_text = $ngettext( + '%{ count } Benachrichtigung', + '%{ count } Benachrichtigungen', + count, + { count } + ); + $('#notification_marker').attr('title', notification_text); updateFavicon(count); $('#notification-container .mark-all-as-read').toggleClass('invisible', count < 2); } diff --git a/resources/assets/javascripts/lib/reststate-client.js b/resources/assets/javascripts/lib/reststate-client.js new file mode 100644 index 0000000000000000000000000000000000000000..5514d1534ab00fee5ed19e4bcda1df9c54a1691e --- /dev/null +++ b/resources/assets/javascripts/lib/reststate-client.js @@ -0,0 +1,141 @@ +function filterQueryString(obj) { + return Object.keys(obj) + .map(k => `filter[${k}]=${encodeURIComponent(obj[k])}`) + .join('&'); +} + +const getOptionsQuery = (optionsObject = {}) => + Object.keys(optionsObject) + .filter(k => typeof optionsObject[k] !== 'undefined') + .map(k => `${k}=${encodeURIComponent(optionsObject[k])}`) + .join('&'); + +const relatedResourceUrl = ({ parent, relationship }) => { + const builtUrl = `${parent.type}/${parent.id}/${relationship}`; + + if ( + parent.relationships + && Object.keys(parent.relationships).includes(relationship) + ) { + return parent.relationships[relationship].links?.related ?? builtUrl; + } + return builtUrl; +}; + +const extractData = response => response.data; + +const extractErrorResponse = error => { + if (error && error.response) { + throw error.response; + } else { + throw error; + } +}; + +class Resource { + constructor({ name, httpClient }) { + this.name = name; + this.api = httpClient; + } + + all({ options = {} } = {}) { + let url; + + if (options.url) { + ({ url } = options); + } else { + url = `${this.name}?${getOptionsQuery(options)}`; + } + + return this.api.get(url).then(extractData).catch(extractErrorResponse); + } + + find({ id, options } = {}) { + const url = `${this.name}/${id}?${getOptionsQuery(options)}`; + + return this.api.get(url).then(extractData).catch(extractErrorResponse); + } + + where({ filter, options } = {}) { + const queryString = filterQueryString(filter); + return this.api + .get(`${this.name}?${queryString}&${getOptionsQuery(options)}`) + .then(extractData) + .catch(extractErrorResponse); + } + + related({ parent, relationship = this.name, options }) { + const baseUrl = relatedResourceUrl({ parent, relationship }); + const url = `${baseUrl}?${getOptionsQuery(options)}`; + return this.api.get(url).then(extractData).catch(extractErrorResponse); + } + + create(partialRecord) { + const record = Object.assign({}, partialRecord, { type: this.name }); + const requestData = { data: record }; + return this.api + .post(`${this.name}`, requestData) + .then(extractData) + .catch(extractErrorResponse); + } + + createRelated(partialRecord) { + const record = Object.assign({}, partialRecord, { type: this.name }); + const requestData = { data: record }; + return this.api + .post(`${this.name}`, requestData) + .then(extractData) + .catch(extractErrorResponse); + } + + updateRelationships(parent, relationship, records) { + // https://jsonapi.org/format/#crud-updating-to-many-relationships + const requestData = { data: records }; + return this.api + .patch( + `${parent.type}/${parent.id}/relationships/${relationship}`, + requestData, + ) + .then(extractData) + .catch(extractErrorResponse); + } + + createRelationships(parent, relationship, records) { + // https://jsonapi.org/format/#crud-updating-to-many-relationships + const requestData = { data: records }; + return this.api + .post( + `${parent.type}/${parent.id}/relationships/${relationship}`, + requestData, + ) + .then(extractData) + .catch(extractErrorResponse); + } + + removeRelationships(parent, relationship, records) { + // https://jsonapi.org/format/#crud-updating-to-many-relationships + const requestData = { data: records }; + return this.api + .delete( + `${parent.type}/${parent.id}/relationships/${relationship}`, + requestData, + ) + .then(extractData) + .catch(extractErrorResponse); + } + + update(record) { + // http://jsonapi.org/faq/#wheres-put + const requestData = { data: record }; + return this.api + .patch(`${this.name}/${record.id}`, requestData) + .then(extractData) + .catch(extractErrorResponse); + } + + delete({ id }) { + return this.api.delete(`${this.name}/${id}`).catch(extractErrorResponse); + } +} + +export default Resource; diff --git a/resources/assets/javascripts/lib/reststate-vuex.js b/resources/assets/javascripts/lib/reststate-vuex.js new file mode 100644 index 0000000000000000000000000000000000000000..a3dd6ca0e9e6e20d59a57861086f026b1766c743 --- /dev/null +++ b/resources/assets/javascripts/lib/reststate-vuex.js @@ -0,0 +1,522 @@ +import ResourceClient from './reststate-client.js'; +import { isEqual } from 'lodash'; + +const STATUS_INITIAL = 'INITIAL'; +const STATUS_LOADING = 'LOADING'; +const STATUS_ERROR = 'ERROR'; +const STATUS_SUCCESS = 'SUCCESS'; + +const storeRecord = records => newRecord => { + const existingRecord = records.find(r => r.id === newRecord.id); + if (existingRecord) { + Object.assign(existingRecord, newRecord); + } else { + records.push(newRecord); + } +}; + +const getResourceIdentifier = resource => { + if (!resource) { + return resource; + } + + return { + type: resource.type, + id: resource.id, + }; +}; + +const getRelationshipType = relationship => { + const data = Array.isArray(relationship.data) + ? relationship.data[0] + : relationship.data; + + return data && data.type; +}; + +const storeIncluded = ({ commit, dispatch }, result) => { + if (result.included) { + // store the included records + result.included.forEach(relatedRecord => { + const action = `${relatedRecord.type}/storeRecord`; + dispatch(action, relatedRecord, { root: true }); + }); + + // store the relationship for primary and secondary records + let allRecords = [...result.included]; + if (Array.isArray(result.data)) { + allRecords = [...allRecords, ...result.data]; + } else { + allRecords = [...allRecords, result.data]; + } + + allRecords.forEach(primaryRecord => { + if (primaryRecord.relationships) { + Object.keys(primaryRecord.relationships).forEach(relationshipName => { + const relationship = primaryRecord.relationships[relationshipName]; + if (!relationship.data || relationship.data.length === 0) { + return; + } + + const type = getRelationshipType(relationship); + let relatedIds; + if (Array.isArray(relationship.data)) { + relatedIds = relationship.data.map( + relatedRecord => relatedRecord.id, + ); + } else { + ({ id: relatedIds } = relationship.data); + } + const options = { + relatedIds, + params: { + parent: getResourceIdentifier(primaryRecord), + relationship: relationshipName, + }, + }; + const action = `${type}/storeRelated`; + dispatch(action, options, { root: true }); + }); + } + }); + } +}; + +const matches = criteria => test => + Object.keys(criteria).every(key => isEqual(criteria[key], test[key])); + +const handleError = commit => errorResponse => { + commit('SET_STATUS', STATUS_ERROR); + commit('STORE_ERROR', errorResponse); + throw errorResponse; +}; + +const initialState = () => ({ + records: [], + related: [], + filtered: [], + page: [], + error: null, + status: STATUS_INITIAL, + links: {}, + lastCreated: null, + lastMeta: null, +}); + +const resourceModule = ({ name: resourceName, httpClient }) => { + const client = new ResourceClient({ name: resourceName, httpClient }); + + const getRelationshipIndex = params => { + const { parent, relationship = resourceName } = params; + const parentResourceIdentifier = getResourceIdentifier(parent); + + return { + parent: parentResourceIdentifier, + relationship, + }; + }; + + return { + namespaced: true, + + state: initialState, + + mutations: { + REPLACE_ALL_RECORDS: (state, records) => { + state.records = records; + }, + + REPLACE_ALL_RELATED: (state, related) => { + state.related = related; + }, + + SET_STATUS: (state, status) => { + state.status = status; + }, + + STORE_RECORD: (state, newRecord) => { + const { records } = state; + + storeRecord(records)(newRecord); + }, + + STORE_RECORDS: (state, newRecords) => { + const { records } = state; + + newRecords.forEach(storeRecord(records)); + }, + + STORE_PAGE: (state, records) => { + state.page = records.map(({ id }) => id); + }, + + STORE_META: (state, meta) => { + state.lastMeta = meta; + }, + + STORE_ERROR: (state, error) => { + state.error = error; + }, + + STORE_RELATED: (state, { relatedIds, params, resetRelated = true }) => { + const { related } = state; + const relationshipIndex = getRelationshipIndex(params); + const existingRecord = related.find(matches(relationshipIndex)); + if (existingRecord) { + if (resetRelated) { + existingRecord.relatedIds = relatedIds; + } else { + const ids = new Set([...existingRecord.relatedIds, ...relatedIds]) + existingRecord.relatedIds = [...ids]; + } + } else { + related.push(Object.assign({ relatedIds }, relationshipIndex)); + } + }, + + STORE_FILTERED: (state, { matchedIds, params }) => { + const { filtered } = state; + + const existingRecord = filtered.find(matches(params)); + if (existingRecord) { + existingRecord.matchedIds = matchedIds; + } else { + filtered.push(Object.assign({ matchedIds }, params)); + } + }, + + STORE_LAST_CREATED: (state, record) => { + state.lastCreated = record; + }, + + REMOVE_RECORD: (state, record) => { + state.records = state.records.filter(r => r.id !== record.id); + }, + + SET_LINKS: (state, links) => { + state.links = links || {}; + }, + + RESET_STATE: state => { + Object.assign(state, initialState()); + }, + }, + + actions: { + loadAll({ commit, dispatch }, { options } = {}) { + commit('SET_STATUS', STATUS_LOADING); + return client + .all({ options }) + .then(result => { + commit('SET_STATUS', STATUS_SUCCESS); + commit('REPLACE_ALL_RECORDS', result.data); + commit('STORE_META', result.meta); + storeIncluded({ commit, dispatch }, result); + }) + .catch(handleError(commit)); + }, + + loadById({ commit, dispatch }, { id, options }) { + commit('SET_STATUS', STATUS_LOADING); + return client + .find({ id, options }) + .then(results => { + commit('SET_STATUS', STATUS_SUCCESS); + commit('STORE_RECORD', results.data); + commit('STORE_META', results.meta); + storeIncluded({ commit, dispatch }, results); + }) + .catch(handleError(commit)); + }, + + loadWhere({ commit, dispatch }, params) { + const { filter, options } = params; + commit('SET_STATUS', STATUS_LOADING); + return client + .where({ filter, options }) + .then(results => { + commit('SET_STATUS', STATUS_SUCCESS); + const matches = results.data; + const matchedIds = matches.map(record => record.id); + commit('STORE_RECORDS', matches); + commit('STORE_FILTERED', { params, matchedIds }); + commit('STORE_META', results.meta); + storeIncluded({ commit, dispatch }, results); + }) + .catch(handleError(commit)); + }, + + loadPage({ commit, dispatch }, { options }) { + commit('SET_STATUS', STATUS_LOADING); + return client + .all({ options }) + .then(response => { + commit('SET_STATUS', STATUS_SUCCESS); + commit('STORE_RECORDS', response.data); + commit('STORE_PAGE', response.data); + commit('STORE_META', response.meta); + commit('SET_LINKS', response.links); + storeIncluded({ commit, dispatch }, response); + }) + .catch(handleError(commit)); + }, + + loadNextPage({ commit, state, dispatch }) { + const options = { + url: state.links.next, + }; + return client.all({ options }).then(response => { + commit('STORE_RECORDS', response.data); + commit('STORE_PAGE', response.data); + commit('SET_LINKS', response.links); + commit('STORE_META', response.meta); + storeIncluded({ commit, dispatch }, response); + }); + }, + + loadPreviousPage({ commit, state, dispatch }) { + const options = { + url: state.links.prev, + }; + return client.all({ options }).then(response => { + commit('STORE_RECORDS', response.data); + commit('STORE_PAGE', response.data); + commit('SET_LINKS', response.links); + commit('STORE_META', response.meta); + storeIncluded({ commit, dispatch }, response); + }); + }, + + loadRelated({ commit, dispatch }, params) { + const { parent, relationship = resourceName, options, resetRelated = true } = params; + commit('SET_STATUS', STATUS_LOADING); + const paramsToStore = { + ...params, + relationship, + }; + return client + .related({ parent, relationship, options }) + .then(results => { + commit('SET_STATUS', STATUS_SUCCESS); + const { id, type } = parent; + if (Array.isArray(results.data)) { + const relatedRecords = results.data; + const relatedIds = relatedRecords.map(record => record.id); + commit('STORE_RECORDS', relatedRecords); + commit('STORE_RELATED', { params: paramsToStore, relatedIds, resetRelated }); + } else { + const record = results.data; + const relatedIds = record.id; + commit('STORE_RECORDS', [record]); + commit('STORE_RELATED', { params: paramsToStore, relatedIds }); + } + commit('STORE_META', results.meta); + storeIncluded({ commit, dispatch }, results); + }) + .catch(handleError(commit)); + }, + + create({ commit }, recordData) { + return client.create(recordData).then(result => { + commit('STORE_RECORD', result.data); + commit('STORE_LAST_CREATED', result.data); + }); + }, + + update({ commit, dispatch, getters }, record) { + return client.update(record).then(() => { + const oldRecord = getters.byId({ id: record.id }); + + // remove old relationships first + if (oldRecord && oldRecord.relationships) { + for (const entry of Object.entries(oldRecord.relationships)) { + const [relationship, entity] = entry; + const type = getRelationshipType(entity); + const paramsToStore = { + relationship, + parent: getResourceIdentifier(oldRecord), + }; + + // we cannot update the related resource without a type + // this could possibly be very bad as we cannot remove existing + // relationships + if (type === null || type === undefined) { + continue; + } + + dispatch( + `${type}/storeRelated`, + { + params: paramsToStore, + relatedIds: null, + }, + { root: true }, + ); + } + } + + // save entity + commit('STORE_RECORD', record); + + // set new relationships + if (record.relationships) { + for (const relationship of Object.keys(record.relationships)) { + const relationshipObject = record.relationships[relationship]; + const { data } = relationshipObject; + const isNonEmptyArray = Array.isArray(data) && Boolean(data.length); + const isObject = Boolean(data && data.type && data.id); + + if (isNonEmptyArray || isObject) { + const paramsToStore = { + parent: getResourceIdentifier(record), + relationship, + }; + const type = getRelationshipType(relationshipObject); + let relatedIds; + if (Array.isArray(data)) { + relatedIds = data.map(record => record.id); + } else { + relatedIds = data.id; + } + dispatch( + `${type}/storeRelated`, + { + params: paramsToStore, + relatedIds, + }, + { root: true }, + ); + } + } + } + }); + }, + + delete({ commit }, record) { + return client.delete(record).then(() => { + commit('REMOVE_RECORD', record); + }); + }, + + storeRecord({ commit }, record) { + commit('STORE_RECORD', record); + }, + + storeRelated({ commit }, { relatedIds, params }) { + commit('STORE_RELATED', { + relatedIds, + params, + }); + }, + + removeRecord({ commit }, record) { + commit('REMOVE_RECORD', record); + }, + + resetState({ commit }) { + commit('RESET_STATE'); + }, + + addRelated({ commit, getters }, params) { + const { parent, relationship = resourceName, data } = params; + const relatedItems = getters.related(params).map(o => o.id); + const difference = data.filter(x => !relatedItems.includes(x)); + const records = difference.map(id => { + return { type: relationship, id }; + }); + return client.createRelationships(parent, relationship, records); + }, + + setRelated({ commit, dispatch }, params) { + const { parent, relationship = resourceName, data } = params; + return client.updateRelationships(parent, relationship, data).then(response => { + let relatedIds; + if (Array.isArray(data)) { + relatedIds = data.map(record => record.id); + } else if (data === null) { + relatedIds = null; + } else { + relatedIds = data.id; + } + commit('STORE_RELATED', { + params: { parent, relationship }, + relatedIds, + }); + }); + }, + + removeRelated({ commit, dispatch }, params) { + const { parent, relationship = resourceName, data } = params; + client.removeRelationships(parent, relationship, data); + let relatedIds; + if (Array.isArray(data)) { + relatedIds = data.map(record => record.id); + } else { + relatedIds = data.id; + } + commit('REMOVE_RELATED', { + params: { parent, relationship }, + relatedIds, + }); + }, + + removeAllRelated({ commit, dispatch }, params) { + const { parent, relationship = resourceName } = params; + client.updateRelationships(parent, relationship, []); + commit('REMOVE_RELATED', { + params: { parent, relationship }, + relatedIds: [], + }); + }, + }, + + getters: { + isLoading: state => state.status === STATUS_LOADING, + isError: state => state.status === STATUS_ERROR, + error: state => state.error, + hasPrevious: state => !!state.links.prev, + hasNext: state => !!state.links.next, + all: state => state.records, + lastCreated: state => state.lastCreated, + byId: state => ({ id }) => state.records.find(r => r.id == id), + lastMeta: state => state.lastMeta, + page: state => + state.page.map(id => state.records.find(record => record.id === id)), + where: state => params => { + const entry = state.filtered.find(matches(params)); + + if (!entry) { + return []; + } + + const ids = entry.matchedIds; + return ids.map(id => state.records.find(record => record.id === id)); + }, + related: state => params => { + const relationshipIndex = getRelationshipIndex(params); + const related = state.related.find(matches(relationshipIndex)); + + if (!related) { + return null; + } else if (Array.isArray(related.relatedIds)) { + const ids = related.relatedIds; + return ids + .map(id => state.records.find(record => record.id === id)) + .filter(record => record !== undefined); + } else { + const id = related.relatedIds; + return state.records.find(record => id === record.id); + } + }, + }, + }; +}; + +const mapResourceModules = ({ names, httpClient }) => + names.reduce( + (acc, name) => + Object.assign({ [name]: resourceModule({ name, httpClient }) }, acc), + {}, + ); + +export { resourceModule, mapResourceModules }; diff --git a/resources/assets/stylesheets/jquery-ui.structure.css b/resources/assets/stylesheets/jquery-ui.structure.css index 23f58da575378e950c6a0ed50c6df2a4b766e6c8..76ed1e72abcd681171143ec1a91f9e3466b69e4e 100644 --- a/resources/assets/stylesheets/jquery-ui.structure.css +++ b/resources/assets/stylesheets/jquery-ui.structure.css @@ -591,7 +591,8 @@ button.ui-button::-moz-focus-inner { .ui-dialog .ui-dialog-content { position: relative; border: 0; - padding: .5em 1em; + padding: .5em 1em 0; + margin-bottom: .5em; background: none; overflow: auto; } diff --git a/resources/assets/stylesheets/scss/blubber.scss b/resources/assets/stylesheets/scss/blubber.scss index 6e1499967cad67a53cdcff83c9222e62ca48a333..4e7bf34f880fc4c9d1621fd77e81028cafc0cf10 100644 --- a/resources/assets/stylesheets/scss/blubber.scss +++ b/resources/assets/stylesheets/scss/blubber.scss @@ -507,10 +507,13 @@ ol.tagcloud { } //Animationen des Widgets: -.blubberthreadwidget-list-move, .blubberthreadwidget-list-enter-active, .blubberthreadwidget-list-leave-active { +.blubberthreadwidget-list-move, +.blubberthreadwidget-list-enter-active, +.blubberthreadwidget-list-leave-active { transition: transform 0.5s; } -.blubberthreadwidget-list-enter, .blubberthreadwidget-list-leave-to { +.blubberthreadwidget-list-enter-from, +.blubberthreadwidget-list-leave-to { transform: translateY(-70px); } diff --git a/resources/assets/stylesheets/scss/forms.scss b/resources/assets/stylesheets/scss/forms.scss index d9280da526470b747d4829ef5f3183dbfd98d836..dd1d67cd1bdf7a844cf520418c81dd937fdf0ecc 100644 --- a/resources/assets/stylesheets/scss/forms.scss +++ b/resources/assets/stylesheets/scss/forms.scss @@ -647,11 +647,12 @@ form.inline { footer[data-dialog-button] { background: var(--white); border-top-color: var(--base-color-20); - bottom: -0.5em; + bottom: 0; margin-top: auto; padding: 0.5em 0; position: sticky; text-align: center; + z-index: 2; } } } diff --git a/resources/vue/avatar-app.js b/resources/vue/avatar-app.js index 0092ebe5f83e08c19b8340689ce8d0f0ec3ae07e..63db01c5f991a84d1a654636053ad0baf91c398a 100644 --- a/resources/vue/avatar-app.js +++ b/resources/vue/avatar-app.js @@ -1,76 +1,45 @@ import AvatarApp from './components/avatar/AvatarApp.vue'; import AvatarModule from './store/avatar.module'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; import axios from 'axios'; +import { h } from 'vue'; -const mountApp = async (STUDIP, createApp, element) => { +const mountApp = async (STUDIP, createApp, store, element) => { let entry_id = null; let entry_type = null; - let avatar_url = null; - let elem; + let elem = document.getElementById(element.substring(1)); - if ((elem = document.getElementById(element.substring(1))) !== undefined) { - if (elem.attributes !== undefined) { - if (elem.attributes['entry-type'] !== undefined) { - entry_type = elem.attributes['entry-type'].value; - } - - if (elem.attributes['entry-id'] !== undefined) { - entry_id = elem.attributes['entry-id'].value; - } - - if (elem.attributes['avatar-url'] !== undefined) { - avatar_url = elem.attributes['avatar-url'].value; - } - } + if (elem) { + entry_type = elem.attributes?.['entry-type']?.value ?? null; + entry_id = elem.attributes?.['entry-id']?.value ?? null; } - const getHttpClient = () => - axios.create({ + const httpClient = axios.create({ baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), headers: { 'Content-Type': 'application/vnd.api+json', }, }); - const httpClient = getHttpClient(); - const store = new Vuex.Store({ - modules: { - 'avatar-module': AvatarModule, - ...mapResourceModules({ - names: [ - 'avatar', - 'courses', - 'institutes', - 'stock-images', - 'studygroups', - 'users', - ], - httpClient, - }), - } - }); + store.registerModule('avatar-module', AvatarModule); const context = { type: entry_type, id: entry_id } - store.dispatch('setUserId', STUDIP.USER_ID); + await store.dispatch('setUserId', STUDIP.USER_ID); await store.dispatch('users/loadById', { id: STUDIP.USER_ID }); - store.dispatch('setHttpClient', httpClient); - store.dispatch('setContext', context); - const avatar = await store.dispatch('loadAvatar'); + await store.dispatch('setHttpClient', httpClient); + await store.dispatch('setContext', context); + await store.dispatch('loadAvatar'); const app = createApp({ - render: (h) => h(AvatarApp), + render: () => h(AvatarApp), store, }); - app.$mount(element); + app.mount(element); return app; } -export default mountApp; \ No newline at end of file +export default mountApp; diff --git a/resources/vue/base-components.js b/resources/vue/base-components.js index 567e9ff484a510d93a5cc9f323032f09f4e06a13..d9bb1b79aff209edb956dc1ef74239c5a9394b3e 100644 --- a/resources/vue/base-components.js +++ b/resources/vue/base-components.js @@ -1,36 +1,38 @@ +import { defineAsyncComponent } from 'vue'; + const BaseComponents = { - CaptchaInput: () => import('./components/form_inputs/CaptchaInput.vue'), - CalendarPermissionsTable: () => import("./components/form_inputs/CalendarPermissionsTable.vue"), - DateListInput: () => import('./components/form_inputs/DateListInput.vue'), - Datepicker: () => import('./components/Datepicker.vue'), - Datetimepicker: () => import('./components/Datetimepicker.vue'), - DayOfWeekSelect: () => import('./components/form_inputs/DayOfWeekSelect.vue'), - EditableList: () => import("./components/EditableList.vue"), - FileUpload: () => import('./components/form_inputs/FileUpload.vue'), - I18nTextarea: () => import("./components/I18nTextarea.vue"), - Multiselect: () => import('./components/Multiselect.vue'), - MyCoursesColouredTable: () => import('./components/form_inputs/MyCoursesColouredTable.vue'), - Quicksearch: () => import('./components/Quicksearch.vue'), - QuicksearchListInput: () => import('./components/form_inputs/QuicksearchListInput.vue'), - RangeInput: () => import('./components/RangeInput.vue'), - RepetitionInput: () => import("./components/form_inputs/RepetitionInput.vue"), - SerialTextMarkers: () => import('./components/form_inputs/SerialTextMarkers.vue'), - SidebarWidget: () => import('./components/SidebarWidget.vue'), - StudipActionMenu: () => import('./components/StudipActionMenu.vue'), - StudipAssetImg: () => import('./components/StudipAssetImg.vue'), - StudipDateTime: () => import('./components/StudipDateTime.vue'), - StudipDialog: () => import('./components/StudipDialog.vue'), - StudipFileSize: () => import('./components/StudipFileSize.vue'), - StudipFolderSize: () => import('./components/StudipFolderSize.vue'), - StudipIcon: () => import('./components/StudipIcon.vue'), - StudipMessageBox: () => import('./components/StudipMessageBox.vue'), - StudipMultiPersonSearch: () => import('./components/StudipMultiPersonSearch.vue'), - StudipProxiedCheckbox: () => import('./components/StudipProxiedCheckbox.vue'), - StudipProxyCheckbox: () => import('./components/StudipProxyCheckbox.vue'), - StudipSelect: () => import('./components/StudipSelect.vue'), - StudipTooltipIcon: () => import('./components/StudipTooltipIcon.vue'), - StudipWysiwyg: () => import("./components/StudipWysiwyg.vue"), - UserFilterInput: () => import('./components/form_inputs/UserFilterInput.vue') + CaptchaInput: defineAsyncComponent(() => import('./components/form_inputs/CaptchaInput.vue')), + CalendarPermissionsTable: defineAsyncComponent(() => import('./components/form_inputs/CalendarPermissionsTable.vue')), + DateListInput: defineAsyncComponent(() => import('./components/form_inputs/DateListInput.vue')), + Datepicker: defineAsyncComponent(() => import('./components/Datepicker.vue')), + Datetimepicker: defineAsyncComponent(() => import('./components/Datetimepicker.vue')), + DayOfWeekSelect: defineAsyncComponent(() => import('./components/form_inputs/DayOfWeekSelect.vue')), + EditableList: defineAsyncComponent(() => import('./components/EditableList.vue')), + FileUpload: defineAsyncComponent(() => import('./components/form_inputs/FileUpload.vue')), + I18nTextarea: defineAsyncComponent(() => import("./components/I18nTextarea.vue")), + Multiselect: defineAsyncComponent(() => import('./components/Multiselect.vue')), + MyCoursesColouredTable: defineAsyncComponent(() => import('./components/form_inputs/MyCoursesColouredTable.vue')), + Quicksearch: defineAsyncComponent(() => import('./components/Quicksearch.vue')), + QuicksearchListInput: defineAsyncComponent(() => import('./components/form_inputs/QuicksearchListInput.vue')), + RangeInput: defineAsyncComponent(() => import('./components/RangeInput.vue')), + RepetitionInput: defineAsyncComponent(() => import("./components/form_inputs/RepetitionInput.vue")), + SerialTextMarkers: defineAsyncComponent(() => import('./components/form_inputs/SerialTextMarkers.vue')), + SidebarWidget: defineAsyncComponent(() => import('./components/SidebarWidget.vue')), + StudipActionMenu: defineAsyncComponent(() => import('./components/StudipActionMenu.vue')), + StudipAssetImg: defineAsyncComponent(() => import('./components/StudipAssetImg.vue')), + StudipDateTime: defineAsyncComponent(() => import('./components/StudipDateTime.vue')), + StudipDialog: defineAsyncComponent(() => import('./components/StudipDialog.vue')), + StudipFileSize: defineAsyncComponent(() => import('./components/StudipFileSize.vue')), + StudipFolderSize: defineAsyncComponent(() => import('./components/StudipFolderSize.vue')), + StudipIcon: defineAsyncComponent(() => import('./components/StudipIcon.vue')), + StudipMessageBox: defineAsyncComponent(() => import('./components/StudipMessageBox.vue')), + StudipMultiPersonSearch: defineAsyncComponent(() => import('./components/StudipMultiPersonSearch.vue')), + StudipProxiedCheckbox: defineAsyncComponent(() => import('./components/StudipProxiedCheckbox.vue')), + StudipProxyCheckbox: defineAsyncComponent(() => import('./components/StudipProxyCheckbox.vue')), + StudipSelect: defineAsyncComponent(() => import('./components/StudipSelect.vue')), + StudipTooltipIcon: defineAsyncComponent(() => import('./components/StudipTooltipIcon.vue')), + StudipWysiwyg: defineAsyncComponent(() => import('./components/StudipWysiwyg.vue')), + UserFilterInput: defineAsyncComponent(() => import('./components/form_inputs/UserFilterInput.vue')), }; export default BaseComponents; diff --git a/resources/vue/components/ActiveFilter.vue b/resources/vue/components/ActiveFilter.vue index 5394bce50a06fc5a9b7a78a99469eca85b88d4e3..050afffdddc63117bd2cfec433d68a8e47bb174d 100644 --- a/resources/vue/components/ActiveFilter.vue +++ b/resources/vue/components/ActiveFilter.vue @@ -4,7 +4,7 @@ <button @click="onRemoveActiveFilter" type="button" - :title="$gettextInterpolate($gettext('Filter \'%{name}\' entfernen'), { name }, true)" + :title="$gettext('Filter \'%{name}\' entfernen', { name }, true)" > <StudipIcon class="text-bottom" shape="decline" role="presentation" alt="" /> </button> @@ -12,8 +12,8 @@ </template> <script> -import StudipIcon from './StudipIcon.vue'; export default { + emits: ['remove'], props: { name: { type: String, diff --git a/resources/vue/components/AdminCourses.vue b/resources/vue/components/AdminCourses.vue index c0e116051e0762988dd785670602c3fd88cc0e85..386d81d9ab5eed64e6322d322807e318c7326334 100644 --- a/resources/vue/components/AdminCourses.vue +++ b/resources/vue/components/AdminCourses.vue @@ -34,7 +34,7 @@ <th v-for="activeField in sortedActivatedFields" :key="`field-${activeField}`" :class="sort.by === activeField ? 'sort' + sort.direction.toLowerCase() : ''"> <a href="#" @click.prevent="changeSort(activeField)" - :title="sort.by === activeField && sort.direction === 'ASC' ? $gettextInterpolate('Sortiert aufsteigend nach %{field}', {field: fields[activeField]}, true) : (sort.by === activeField && sort.direction === 'DESC' ? $gettextInterpolate('Sortiert absteigend nach %{ field } ', { field: fields[activeField]}, true) : $gettextInterpolate('Sortieren nach %{ field }', { field: fields[activeField]}, true))" + :title="sort.by === activeField && sort.direction === 'ASC' ? $gettext('Sortiert aufsteigend nach %{field}', {field: fields[activeField]}, true) : (sort.by === activeField && sort.direction === 'DESC' ? $gettext('Sortiert absteigend nach %{ field } ', { field: fields[activeField]}, true) : $gettext('Sortieren nach %{ field }', { field: fields[activeField]}, true))" v-if="!unsortableFields.includes(activeField)" > {{ fields[activeField] }} @@ -72,8 +72,8 @@ @click.prevent="toggleOpenChildren(course.id)" href=""> <studip-icon :shape="open_children.indexOf(course.id) === -1 ? 'add' : 'remove'" class="text-bottom"></studip-icon> - {{ $gettextInterpolate( - $gettext('%{ n } Unterveranstaltungen'), + {{ $gettext( + '%{ n } Unterveranstaltungen', { n: getChildren(course).length } ) }} </a> @@ -89,8 +89,8 @@ <tr v-if="coursesCount > 0 && sortedCourses.length === 0"> <td :colspan="colspan"> {{ - $gettextInterpolate( - $gettext(`%{ n } Veranstaltungen entsprechen Ihrem Filter. Schränken Sie nach Möglichkeit die Filter weiter ein.`), + $gettext( + '%{ n } Veranstaltungen entsprechen Ihrem Filter. Schränken Sie nach Möglichkeit die Filter weiter ein.', { n: coursesCount } ) }} @@ -161,7 +161,7 @@ export default { this.contentWidth = Math.max(...iconCounts) * 26; }, - destroyed() { + unmounted() { this.globalOff('AdminCourses/changeActionArea', this.changeActionArea.bind(this)); this.globalOff('AdminCourses/changeFilter', this.changeFilter.bind(this)); this.globalOff('AdminCourses/loadCourse', this.loadCourse.bind(this)); diff --git a/resources/vue/components/CacheAdministration.vue b/resources/vue/components/CacheAdministration.vue index c3220753bb8b583810cb61ee2d0dc67a34b31bc2..9b15719adef400ae595988c6137c8b32654a057a 100644 --- a/resources/vue/components/CacheAdministration.vue +++ b/resources/vue/components/CacheAdministration.vue @@ -5,10 +5,10 @@ </StudipMessageBox> <fieldset> <legend> - <translate>Cachetyp</translate> + {{ $gettext('Cachetyp') }} </legend> <label> - <translate>Cachetyp auswählen</translate> + {{ $gettext('Cachetyp auswählen') }} <select name="cachetype" v-model="selectedCacheType" @change="getCacheConfig"> <option v-for="(type) in cacheTypes" :key="type.cache_id" :value="type.class_name"> @@ -24,12 +24,12 @@ <component :is="configComponent" v-bind="configProps" ref="cacheConfig" @is-valid="setValid"></component> </template> <template v-else> - <translate>Für diesen Cachetyp ist keine Konfiguration erforderlich.</translate> + {{ $gettext('Für diesen Cachetyp ist keine Konfiguration erforderlich.') }} </template> </fieldset> <footer data-dialog-button> <button class="button accept" @click.prevent="validateConfig" :disabled="!isValid"> - <translate>Speichern</translate> + {{ $gettext('Speichern') }} </button> </footer> </form> diff --git a/resources/vue/components/ConsultationCreator.vue b/resources/vue/components/ConsultationCreator.vue index 171b70d5f979f682b5b03493ea584ea2d3fd1307..aa5621cf9afd0505fbab4146e9baa4a882ab3dba 100644 --- a/resources/vue/components/ConsultationCreator.vue +++ b/resources/vue/components/ConsultationCreator.vue @@ -41,7 +41,7 @@ <span class="required">{{ $gettext('Am Wochentag') }}</span> <select required name="day-of-week" @change="evt => dayOfWeek = parseInt(evt.target.value, 10)"> - <option v-for="dow in daysOfTheWeek" :value="dow.key" :key="dow.key" :selected="dayOfWeek === dow.key"> + <option v-for="dow in daysOfTheWeek" :value="dow.key" :key="dow.key" :selected="dayOfWeek === dow.key ? true : null"> {{ dow.label }} </option> </select> @@ -267,8 +267,8 @@ <label> <input type="checkbox" v-model="confirmed"> - {{ $gettextInterpolate( - $gettext('Ja, ich möchte wirklich %{ n } Termine erstellen.'), + {{ $gettext( + 'Ja, ich möchte wirklich %{ n } Termine erstellen.', { n: slotCount } ) }} </label> @@ -352,7 +352,7 @@ export default { slotCount: null, startDate: moment().add(1, 'weeks').toDate(), startTime: '08:00', - } + }; }, computed: { csrf() { diff --git a/resources/vue/components/ContentBar.vue b/resources/vue/components/ContentBar.vue index 539c5825f8f8af9eaddcbd75d04b48e3ce1aacb8..f12879f092b6338b1ff055700473eb0bf857bb98 100644 --- a/resources/vue/components/ContentBar.vue +++ b/resources/vue/components/ContentBar.vue @@ -126,7 +126,7 @@ export default defineComponent({ } }); }, - beforeDestroy() { + beforeUnmount() { if (this.isContentBar) { window.STUDIP.eventBus.emit('courseware-contentbar-before-destroy', this); } diff --git a/resources/vue/components/ContentBarTableOfContents.vue b/resources/vue/components/ContentBarTableOfContents.vue index 525c4d69872b298a5791dc3f3d3980efd7da75c9..dea32549ef05416cf3627e64989a14c8df7d2cb4 100644 --- a/resources/vue/components/ContentBarTableOfContents.vue +++ b/resources/vue/components/ContentBarTableOfContents.vue @@ -8,7 +8,7 @@ <article v-if="tocOpen" id="toc"> <header id="toc_header"> <h1 id="toc_h1"> - {{ $gettextInterpolate('Inhalt (%{count} Elemente)', { count: tocItemsCount }) }} + {{ $gettext('Inhalt (%{count} Elemente)', {count: tocItemsCount.toString()}) }} </h1> <button class="toc-hide-button" :title="$gettext('Inhaltsverzeichnis schließen')" diff --git a/resources/vue/components/ContentModules.vue b/resources/vue/components/ContentModules.vue index e6164900787e0032362be1665e393a343989b9f0..d2223a2c84fb2ce0d39810ccc8cc25d26edc9725 100644 --- a/resources/vue/components/ContentModules.vue +++ b/resources/vue/components/ContentModules.vue @@ -39,7 +39,9 @@ :range-type="rangeType" ></component> - <MountingPortal mount-to="#tool-view-switch .sidebar-widget-content .widget-list" name="sidebar-switch"> + <Teleport to="#tool-view-switch .sidebar-widget-content .widget-list" + name="sidebar-switch" + > <ul class="widget-list widget-links sidebar-views"> <li :class="{ active: view === 'tiles' }"> <a href="#" @click.prevent="changeView('tiles')"> @@ -52,9 +54,11 @@ </a> </li> </ul> - </MountingPortal> + </Teleport> - <MountingPortal mount-to="#tool-filter-category .sidebar-widget-content .widget-list" name="sidebar-filter"> + <Teleport to="#tool-filter-category .sidebar-widget-content .widget-list" + name="sidebar-filter" + > <ul class="widget-list widget-options"> <li> <a class="options-radio" @@ -79,7 +83,7 @@ </a> </li> </ul> - </MountingPortal> + </Teleport> </form> </template> <script> @@ -114,6 +118,10 @@ export default { 'setFilterCategory', ]), }, + beforeMount() { + document.querySelector('#tool-view-switch .sidebar-widget-content .widget-list').innerHTML = ''; + document.querySelector('#tool-filter-category .sidebar-widget-content .widget-list').innerHTML = ''; + } }; </script> <style lang="scss"> diff --git a/resources/vue/components/ContentModulesControl.vue b/resources/vue/components/ContentModulesControl.vue index 34f4125624c811ee1657b7587cae4a2eeaa3fc33..e41f200eb975d289636982e0406c568cbbbc3d46 100644 --- a/resources/vue/components/ContentModulesControl.vue +++ b/resources/vue/components/ContentModulesControl.vue @@ -15,7 +15,7 @@ @click.prevent="toggleModuleVisibility(module)"> <studip-icon :shape="module.visibility !== 'tutor' ? 'visibility-visible' : 'visibility-invisible'" class="text-bottom" - :title="$gettextInterpolate($gettext('Inhaltsmodul %{ name } für Teilnehmende unsichtbar bzw. sichtbar schalten'), { name: module.displayname}, true)"></studip-icon> + :title="$gettext('Inhaltsmodul %{ name } für Teilnehmende unsichtbar bzw. sichtbar schalten', { name: module.displayname}, true)"></studip-icon> </a> </div> </div> diff --git a/resources/vue/components/ContentModulesEditTiles.vue b/resources/vue/components/ContentModulesEditTiles.vue index c650f9eb633f3fffdd7dadef5a7b5840c9c8d05a..badfbc88f1bff8f337342a145e697c8f31233e2c 100644 --- a/resources/vue/components/ContentModulesEditTiles.vue +++ b/resources/vue/components/ContentModulesEditTiles.vue @@ -1,28 +1,31 @@ <template> <div class="content-modules-wrapper"> - <draggable v-model="sortedModules" handle=".dragarea"> - <transition-group - name="admin_contentmodules" - class="admin_contentmodules studip-grid" - tag="div" - role="listbox" - > + <draggable v-model="activeModules" + handle=".dragarea" + :component-data="{ + name:'admin_contentmodules', + type: 'transition-group', + tag: 'div', + }" + item-key="id" + class="admin_contentmodules studip-grid" + role="listbox" + > + <template #item="{element}"> <div - v-for="module in activeModules" - :key="module.id" role="option" class="studip-grid-element" - :class="getModuleCSSClasses(module, activated[module.id])" + :class="getModuleCSSClasses(element, activated[element.id])" v-cloak > <div> - <a class="upper_part dragarea" :href="getDescriptionURL(module)" data-dialog> + <a class="upper_part dragarea" :href="getDescriptionURL(element)" data-dialog> <div> - <img :src="module.icon" width="40" height="40" v-if="module.icon" /> + <img :src="element.icon" width="40" height="40" v-if="element.icon" /> </div> <div> - <h3>{{ module.displayname }}</h3> - {{ module.summary }} + <h3>{{ element.displayname }}</h3> + {{ element.summary }} </div> </a> <div class="down_part"> @@ -31,26 +34,24 @@ class="dragarea" tabindex="0" :aria-label=" - $gettextInterpolate( - $gettext( - 'Sortierelement für Werkzeug %{module}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.' - ), - { module: module.displayname }, + $gettext( + 'Sortierelement für Werkzeug %{module}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.', + { module: element.displayname }, true ) " - @keydown="keyboardHandler($event, module)" + @keydown="keyboardHandler($event, element)" v-if="filterCategory === null" - :ref="`draghandle-${module.id}`" + :ref="`draghandle-${element.id}`" > <span class="drag-handle"></span> </a> - <label v-if="!module.mandatory"> + <label v-if="!element.mandatory"> <input type="checkbox" - :checked="activated[module.id]" - @click="toggleModule(module)" - :ref="'checkbox_' + module.id" + :checked="activated[element.id]" + @click="toggleModule(element)" + :ref="'checkbox_' + element.id" /> {{ $gettext('Werkzeug ist aktiv') }} </label> @@ -61,38 +62,34 @@ href="#" class="toggle_visibility" role="checkbox" - v-if="showVisibilityToggle(module)" - :aria-checked="module.visibility !== 'tutor' ? 'true' : 'false'" - @click.prevent="toggleModuleVisibility(module)" + v-if="showVisibilityToggle(element)" + :aria-checked="element.visibility !== 'tutor' ? 'true' : 'false'" + @click.prevent="toggleModuleVisibility(element)" > <studip-icon :shape=" - module.visibility !== 'tutor' + element.visibility !== 'tutor' ? 'visibility-visible' : 'visibility-invisible' " class="text-bottom" :title=" - $gettextInterpolate( - $gettext( - 'Inhaltsmodul %{ name } für Teilnehmende unsichtbar bzw. sichtbar schalten' - ), - { name: module.displayname }, + $gettext( + 'Inhaltsmodul %{ name } für Teilnehmende unsichtbar bzw. sichtbar schalten', + { name: element.displayname }, true ) " ></studip-icon> </a> - <a :href="getRenameURL(module)" data-dialog="size=medium"> + <a :href="getRenameURL(element)" data-dialog="size=medium"> <studip-icon shape="edit" class="text-bottom" :title=" - $gettextInterpolate( - $gettext( - 'Umbenennen des Inhaltsmoduls %{ name }' - ), - { name: module.displayname }, + $gettext( + 'Umbenennen des Inhaltsmoduls %{ name }', + { name: element.displayname }, true ) " @@ -102,7 +99,7 @@ </div> </div> </div> - </transition-group> + </template> </draggable> <transition-group name="admin_contentmodules" @@ -164,15 +161,16 @@ export default { }, methods: { toggleModule(module) { - Vue.set(this.activated, module.id, !this.activated[module.id]); + this.activated[module.id] = !this.activated[module.id]; this.toggleModuleActivation(module); }, }, watch: { modules: { immediate: true, + deep: true, handler(current) { - current.forEach((module) => Vue.set(this.activated, module.id, module.active)); + current.forEach((module) => this.activated[module.id] = module.active); }, }, }, diff --git a/resources/vue/components/ContentmodulesEditTable.vue b/resources/vue/components/ContentmodulesEditTable.vue index f8d563897941f615579208c4808609df7649075d..992de76bea428f3e20d01973ab56f554a6d8bfa7 100644 --- a/resources/vue/components/ContentmodulesEditTable.vue +++ b/resources/vue/components/ContentmodulesEditTable.vue @@ -14,83 +14,87 @@ <th class="actions">{{ $gettext('Aktionen') }}</th> </tr> </thead> - <draggable v-model="sortedModules" handle=".dragarea" tag="tbody"> - <tr v-for="module in activeModules" :key="module.id" :class="getModuleCSSClasses(module)" v-cloak> - <td v-if="filterCategory === null"> - <a - class="dragarea" - tabindex="0" - :aria-label=" - $gettextInterpolate( + <draggable v-model="activeModules" + handle=".dragarea" + tag="tbody" + item-key="id" + > + <template #item="{element}"> + <tr :class="getModuleCSSClasses(element)" v-cloak> + <td v-if="filterCategory === null"> + <a + class="dragarea" + tabindex="0" + :aria-label=" $gettext( - 'Sortierelement für Module %{module}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.' - ), - { module: module.displayname }, - true - ) - " - @keydown="keyboardHandler($event, module)" - v-if="module.active" - :ref="`draghandle-${module.id}`" - > - <span class="drag-handle"></span> - </a> - </td> - <td> - <input - type="checkbox" - v-model="module.active" - @click="toggleModuleActivation(module)" - v-if="!module.mandatory" - :ref="'checkbox_' + module.id" - /> - </td> - <td> - <a - class="upper_part" - :class="{ dragrea: module.active }" - :href="getDescriptionURL(module)" - data-dialog - > - <img :src="module.icon" width="20" height="20" v-if="module.icon" class="text-bottom" /> - {{ module.displayname }} - </a> - </td> - <td class="actions"> - <a - href="#" - v-if="showVisibilityToggle(module)" - role="checkbox" - :aria-checked="module.visibility !== 'tutor' ? 'true' : 'false'" - @click.prevent="toggleModuleVisibility(module)" - > - <studip-icon - :shape="module.visibility !== 'tutor' ? 'visibility-visible' : 'visibility-invisible'" - class="text-bottom" - :title=" - $gettextInterpolate( - $gettext( - 'Inhaltsmodul %{ name } für Teilnehmende unsichtbar bzw. sichtbar schalten' - ), - { name: module.displayname }, + 'Sortierelement für Module %{module}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.', + { module: element.displayname }, true ) " - ></studip-icon> - </a> - <a :href="getRenameURL(module)" data-dialog="size=auto" v-if="module.active"> - <studip-icon - shape="edit" - class="text-bottom" - :title=" - $gettextInterpolate($gettext('Umbenennen des Inhaltsmoduls %{ name }'), { - name: module.displayname, - }, true) - " - ></studip-icon> - </a> - </td> - </tr> + @keydown="keyboardHandler($event, element)" + v-if="element.active" + :ref="`draghandle-${element.id}`" + > + <span class="drag-handle"></span> + </a> + </td> + <td> + <input + type="checkbox" + v-model="element.active" + @click="toggleModuleActivation(element)" + v-if="!element.mandatory" + :ref="'checkbox_' + element.id" + /> + </td> + <td> + <a + class="upper_part" + :class="{ dragrea: element.active }" + :href="getDescriptionURL(element)" + data-dialog + > + <img :src="element.icon" width="20" height="20" v-if="element.icon" class="text-bottom" /> + {{ element.displayname }} + </a> + </td> + <td class="actions"> + <a + href="#" + v-if="showVisibilityToggle(element)" + role="checkbox" + :aria-checked="element.visibility !== 'tutor' ? 'true' : 'false'" + @click.prevent="toggleModuleVisibility(element)" + > + <studip-icon + :shape="element.visibility !== 'tutor' ? 'visibility-visible' : 'visibility-invisible'" + class="text-bottom" + :title=" + $gettext( + 'Inhaltsmodul %{ name } für Teilnehmende unsichtbar bzw. sichtbar schalten', + { name: element.displayname }, + true + ) + " + ></studip-icon> + </a> + <a :href="getRenameURL(element)" data-dialog="size=auto" v-if="element.active"> + <studip-icon + shape="edit" + class="text-bottom" + :title=" + $gettext( + 'Umbenennen des Inhaltsmoduls %{ name }', + { name: element.displayname }, + true + ) + " + ></studip-icon> + </a> + </td> + </tr> + </template> </draggable> <tbody> <tr v-for="module in inactiveModules" :key="module.id" :class="getModuleCSSClasses(module)" v-cloak> diff --git a/resources/vue/components/Datepicker.vue b/resources/vue/components/Datepicker.vue index c1886a2997765228c1fabfe914985331810b7d88..eaedc83feffae9fae3c10469819c350c46162ba4 100644 --- a/resources/vue/components/Datepicker.vue +++ b/resources/vue/components/Datepicker.vue @@ -5,7 +5,6 @@ ref="visibleInput" class="visible_input" v-bind="$attrs" - v-on="$listeners" :placeholder="placeholder"> </span> </template> @@ -16,12 +15,13 @@ import RestrictedDatesHelper from '../../assets/javascripts/lib/RestrictedDatesH export default { name: 'Datepicker', inheritAttrs: false, + emits: ['update:modelValue'], props: { + modelValue: [Date, String, Number], name: { type: String, required: false }, - value: [Date, String, Number], mindate: [Date, Number, String], maxdate: [Date, Number, String], placeholder: String, @@ -69,14 +69,14 @@ export default { }, returnValue() { if (this.returnAs === 'unix') { - return this.convertInputToUnixTimestamp(this.value); + return this.convertInputToUnixTimestamp(this.modelValue); } if (this.returnAs === 'iso') { - return this.convertInputToNativeDate(this.value).toISOString(); + return this.convertInputToNativeDate(this.modelValue).toISOString(); } - return this.convertInputToNativeDate(this.value).toLocaleDateString(String.locale); + return this.convertInputToNativeDate(this.modelValue).toLocaleDateString(String.locale); } }, methods: { @@ -104,11 +104,11 @@ export default { }, setUnixTimestamp () { let date = this.input.datepicker('getDate'); - this.$emit('input', this.emitDate ? date : Math.floor(date.getTime() / 1000)); + this.$emit('update:modelValue', this.emitDate ? date : Math.floor(date.getTime() / 1000)); } }, mounted () { - let value = this.convertInputToUnixTimestamp(this.value); + let value = this.convertInputToUnixTimestamp(this.modelValue); if (Number.isInteger(value)) { let date = new Date(value * 1000); diff --git a/resources/vue/components/Datetimepicker.vue b/resources/vue/components/Datetimepicker.vue index 6b12ad78abc2896cf607f85601f1033058ddc4bd..204aacc62b10080fae1a6d567f24c4f2ecb7aa3f 100644 --- a/resources/vue/components/Datetimepicker.vue +++ b/resources/vue/components/Datetimepicker.vue @@ -1,25 +1,25 @@ <template> <span> - <input type="hidden" :name="name" :value="value"> - <input type="text" + <input type="hidden" :name="name" :value="modelValue"> + <input v-bind="$attrs" + type="text" ref="visibleInput" class="visible_input" - @change="setUnixTimestamp" - v-bind="$attrs" - v-on="$listeners"> + @change="setUnixTimestamp"> </span> </template> <script> export default { name: 'datetimepicker', + emits: ['update:modelValue'], inheritAttrs: false, props: { name: { type: String, required: false }, - value: { + modelValue: { required: false }, mindate: { @@ -35,14 +35,14 @@ export default { let date = formatted_date.match(/(\d+)/g); if (date) { date = new Date(`${date[2]}-${date[1]}-${date[0]} ${date[3]}:${date[4]}`); - this.$emit('input', Math.floor(date / 1000)); + this.$emit('update:modelValue', Math.floor(date / 1000)); } else { - this.$emit('input', null); + this.$emit('update:modelValue', null); } } }, mounted () { - let value = !isNaN(parseInt(this.value, 10)) ? parseInt(this.value, 10) : this.value; + let value = !isNaN(parseInt(this.modelValue, 10)) ? parseInt(this.modelValue, 10) : this.modelValue; if (Number.isInteger(value)) { let date = new Date(value * 1000); let formatted_date = @@ -59,10 +59,9 @@ export default { } else { this.$refs.visibleInput.value = value; } - let v = this; let params = { - onSelect () { - v.setUnixTimestamp(); + onSelect: () => { + this.setUnixTimestamp(); } }; if (this.mindate) { @@ -74,10 +73,10 @@ export default { $(this.$refs.visibleInput).datetimepicker(params); }, watch: { - mindat (new_data, old_data) { + mindat (new_data) { $(this.$refs.visibleInput).datetimepicker('option', 'minDate', new Date(new_data * 1000)); }, - maxdate (new_data, old_data) { + maxdate (new_data) { $(this.$refs.visibleInput).datetimepicker('option', 'maxDate', new Date(new_data * 1000)); } } diff --git a/resources/vue/components/EditableList.vue b/resources/vue/components/EditableList.vue index e7aa83865be61ec82a43e8b34a48777da38e3f62..057ffe3b72995315ace8094761d0d9cf840e18ef 100644 --- a/resources/vue/components/EditableList.vue +++ b/resources/vue/components/EditableList.vue @@ -12,7 +12,7 @@ <studip-icon v-if="item.icon" :shape="item.icon" role="info" class="text-bottom" alt=""></studip-icon> <input v-if="name" type="hidden" :name="name + '[]'" :value="item.value"> <span>{{item.name}}</span> - <button v-if="item.deletable" @click.prevent="deleteItem(item)" :title="$gettextInterpolate($gettext('%{ name } löschen'), {name: item.name}, true)" class="undecorated"> + <button v-if="item.deletable" @click.prevent="deleteItem(item)" :title="$gettext('%{ name } löschen', {name: item.name}, true)" class="undecorated"> <studip-icon shape="trash" class="text-bottom"></studip-icon> </button> </li> @@ -21,17 +21,17 @@ </div> <label v-if="selectable"> - <translate>Oder aus Liste auswählen:</translate> + {{ $gettext('Oder aus Liste auswählen:') }} <select @change="quickselect" @keydown="navigate_or_select"> - <option value=""><translate>Direkt auswählen ...</translate></option> + <option value="">{{ $gettext('Direkt auswählen ...') }}</option> <template v-for="(opt, idx) in selectable"> <optgroup v-if="opt.label && opt.options" :label="opt.label" :key="idx"> - <option v-for="(option, index) in opt.options" :disabled="isSelected(option.value)" :value="JSON.stringify({value: option.value, name: option.name})" :key="index"> + <option v-for="(option, index) in opt.options" :disabled="isSelected(option.value)" :value="JSON.stringify({value: option.value, name: option.name})" :key="`group-${index}`"> {{ option.name + (isSelected(option.value) ? ' ✓' : '') }} </option> </optgroup> - <option v-else :disabled="isSelected(opt.value)" @click="quicksearch" :value="JSON.stringify({value: opt.value, name: opt.name})" :key="idx"> - {{ opt.name + (isSelected(option.value) ? ' ✓' : '') }} + <option v-else :disabled="isSelected(opt.value)" @click="quicksearch" :value="JSON.stringify({value: opt.value, name: opt.name})" :key="`opt-${idx}`"> + {{ opt.name + (isSelected(opt.value) ? ' ✓' : '') }} </option> </template> </select> @@ -43,6 +43,7 @@ <script> export default { name: 'editable-list', + emits: ['input', 'items'], props: { name: { type: String, diff --git a/resources/vue/components/FileCacheConfig.vue b/resources/vue/components/FileCacheConfig.vue index 82569ba798653dee367bba853102a81f715b3332..3644c5c6949b78d361cc9e1b3cfcc75ff7c1b36a 100644 --- a/resources/vue/components/FileCacheConfig.vue +++ b/resources/vue/components/FileCacheConfig.vue @@ -1,7 +1,7 @@ <template> <label class="col-4"> <span class="required"> - <translate>Dateipfad</translate> + {{ $gettexdt('Dateipfad') }} </span> <input required type="text" name="path" v-model="thePath"> </label> @@ -10,6 +10,7 @@ <script> export default { name: 'FileCacheConfig', + emits: ['is-valid'], props: { path: { type: String, diff --git a/resources/vue/components/FilesTable.vue b/resources/vue/components/FilesTable.vue index 71db77ff8d2f22af5f4a6bf97bc530fffe10f4a6..e6480ef27a33fb860889278e22aa980adf47592e 100644 --- a/resources/vue/components/FilesTable.vue +++ b/resources/vue/components/FilesTable.vue @@ -46,7 +46,7 @@ data-sort="false" :aria-label="$gettext('Ordner und Dateien auswählen')"> <studip-proxy-checkbox - v-model="selectedIds" + v-model:selected="selectedIds" :total="allIds" :title="$gettext('Alle Ordner und Dateien auswählen')" ></studip-proxy-checkbox> @@ -132,7 +132,7 @@ > <a href="#" @click.prevent - :title="$gettextInterpolate($gettext('Nach %{ colName } sortieren'), {colName: name}, true)"> + :title="$gettext('Nach %{ colName } sortieren', {colName: name}, true)"> {{name}} </a> </th> @@ -149,7 +149,7 @@ <tbody v-else-if="displayedFolders.length + displayedFiles.length === 0"> <tr class="empty"> <td :colspan="numberOfColumns"> - <translate>Keine Ordner oder Dateien entsprechen Ihrem Filter.</translate> + {{ $gettext('Keine Ordner oder Dateien entsprechen Ihrem Filter.') }} </td> </tr> </tbody> @@ -162,22 +162,22 @@ <studip-proxied-checkbox name="ids[]" :value="folder.id" - v-model="selectedIds" + v-model:selected="selectedIds" :aria-label="getAriaLabelForFolder(folder)" ></studip-proxied-checkbox> </td> <td class="document-icon"> <a :href="folder.url" :id="`folder-${folder.id}`" - :title="$gettextInterpolate($gettext('Ordner %{foldername} öffnen'), - { foldername: folder.name}, true)"> + :title="$gettext('Ordner %{foldername} öffnen', { foldername: folder.name}, true)" + > <studip-icon :shape="folder.icon" :size="26" class="text-bottom" alt=""></studip-icon> </a> </td> <td :class="{'filter-match': valueMatchesFilter(folder.name)}"> <a :href="folder.url" - :title="$gettextInterpolate($gettext('Ordner %{foldername} öffnen'), - { foldername: folder.name}, true)"> + :title="$gettext('Ordner %{foldername} öffnen', { foldername: folder.name}, true)" + > <span v-html="highlightString(folder.name)"></span> </a> </td> @@ -202,7 +202,7 @@ class="responsive-hidden" v-html="folder.additionalColumns[index].html" :key="index"></td> - <td v-else class="responsive-hidden" :key="index"></td> + <td v-else class="responsive-hidden" :key="`empty-${index}`"></td> </template> <td class="actions" v-html="folder.actions"> </td> @@ -219,7 +219,7 @@ <studip-proxied-checkbox name="ids[]" :value="file.id" - v-model="selectedIds" + v-model:selected="selectedIds" :aria-label="getAriaLabelForFile(file)" ></studip-proxied-checkbox> </td> @@ -227,8 +227,8 @@ <a v-if="file.download_url" :href="file.download_url" target="_blank" rel="noopener noreferrer" - :title="$gettextInterpolate($gettext('Datei %{filename} herunterladen'), - { filename: file.name }, true)"> + :title="$gettext('Datei %{filename} herunterladen', { filename: file.name }, true)" + > <studip-icon :shape="file.icon" :size="24" class="text-bottom"></studip-icon> </a> <studip-icon v-else :shape="file.icon" :size="24"></studip-icon> @@ -237,15 +237,15 @@ v-if="file.download_url && file.mime_type.indexOf('image/') === 0" class="lightbox-image" data-lightbox="gallery" - :title="$gettextInterpolate($gettext('Datei %{filename} anzeigen'), - { filename: file.name }, true)"></a> + :title="$gettext('Datei %{filename} anzeigen', { filename: file.name }, true)" + ></a> </td> <td :class="{'filter-match': valueMatchesFilter(file.name)}"> <a :href="file.details_url" data-dialog :id="`file-${file.id}`" - :title="$gettextInterpolate($gettext('Details zur Datei %{filename} anzeigen'), - { filename: file.name }, true)"> + :title="$gettext('Details zur Datei %{filename} anzeigen', { filename: file.name }, true)" + > <span v-html="highlightString(file.name)"></span> <studip-icon v-if="file.isAccessible" shape="accessibility" @@ -283,7 +283,7 @@ class="responsive-hidden" v-html="file.additionalColumns[index].html" :key="index"></td> - <td v-else class="responsive-hidden" :key="index"></td> + <td v-else class="responsive-hidden" :key="`empty-${index}`"></td> </template> <td class="actions" v-html="file.actions"> </td> @@ -307,9 +307,9 @@ </tfoot> </table> - <MountingPortal v-if="allow_filter" mount-to="#table-view-filter .sidebar-widget-content div" name="sidebar-content-toggle"> + <Teleport v-if="allow_filter" to="#table-view-filter .sidebar-widget-content div" name="sidebar-content-toggle"> <input :placeholder="$gettext('Name oder Autor/in')" type="search" v-model="filter" :disabled="!hasData" /> - </MountingPortal> + </Teleport> </div> </template> <script> @@ -459,15 +459,15 @@ export default { return highlighted; }, getAriaLabelForFolder(folder) { - return this.$gettextInterpolate( - this.$gettext('Ordner %{name} auswählen'), - {name: folder.name} + return this.$gettext( + 'Ordner %{name} auswählen', + { name: folder.name } ); }, getAriaLabelForFile(file) { - return this.$gettextInterpolate( - this.$gettext('Datei %{name} auswählen'), - {name: file.name} + return this.$gettext( + 'Datei %{name} auswählen', + { name: file.name } ); }, getAriaSortString(column) { @@ -479,10 +479,9 @@ export default { if (column !== this.sortedBy) { return null; } - const template = this.sortDirection === 'asc' - ? this.$gettext('Es wird aufsteigend nach der Spalte %{ label } sortiert.') - : this.$gettext('Es wird absteigend nach der Spalte %{ label } sortiert.'); - return this.$gettextInterpolate(template, { label }); + return this.sortDirection === 'asc' + ? this.$gettext('Es wird aufsteigend nach der Spalte %{ label } sortiert.', { label }) + : this.$gettext('Es wird absteigend nach der Spalte %{ label } sortiert.', { label }); } }, computed: { @@ -535,23 +534,26 @@ export default { this.selectedIds = []; }, watch: { - selectedIds (current) { - const activated = current.length > 0; - if (this.$refs.buttons) { - this.$nextTick(() => { // needs to be wrapped since we check the dom - this.$refs.buttons.querySelectorAll('.multibuttons .button').forEach(element => { - let condition = element.dataset.activatesCondition; - if (!condition || !activated) { - element.disabled = !activated; - } else { - condition = condition.replace(/:has\((.*?)\)/g, ' $1'); - condition = condition.replace(':checkbox', 'input[type="checkbox"]'); + selectedIds: { + handler(current) { + const activated = current.length > 0; + if (this.$refs.buttons) { + this.$nextTick(() => { // needs to be wrapped since we check the dom + this.$refs.buttons.querySelectorAll('.multibuttons .button').forEach(element => { + let condition = element.dataset.activatesCondition; + if (!condition || !activated) { + element.disabled = !activated; + } else { + condition = condition.replace(/:has\((.*?)\)/g, ' $1'); + condition = condition.replace(':checkbox', 'input[type="checkbox"]'); - element.disabled = this.$el.querySelector(condition) === null; - } + element.disabled = this.$el.querySelector(condition) === null; + } + }); }); - }); - } + } + }, + deep: true, }, } } diff --git a/resources/vue/components/I18nTextarea.vue b/resources/vue/components/I18nTextarea.vue index 5071d38fc57b3e6986d8d781c2fb658380fd62f4..c2c8c4518bc7f914ee9f2a9c71ecb6886fb32199 100644 --- a/resources/vue/components/I18nTextarea.vue +++ b/resources/vue/components/I18nTextarea.vue @@ -10,12 +10,10 @@ v-model="currentText" :required="required && defaultLanguage === selectedLanguage.id" v-bind="$attrs" - v-on="$listeners" v-if="type === 'text'"> <textarea :name="nameOfInput(selectedLanguage.id)" ref="inputfield" v-bind="$attrs" - v-on="$listeners" v-model="currentText" :required="required && defaultLanguage === selectedLanguage.id" v-else-if="type === 'textarea'"></textarea> @@ -23,7 +21,6 @@ ref="inputfield" v-model="currentText" v-bind="$attrs" - v-on="$listeners" :required="required && defaultLanguage === selectedLanguage.id" v-else></studip-wysiwyg> </div> @@ -49,21 +46,18 @@ :name="name" v-model="currentText" v-bind="$attrs" - v-on="$listeners" :required="required" v-if="type === 'text'"> <textarea :name="name" ref="inputfield" v-model="currentText" v-bind="$attrs" - v-on="$listeners" :required="required" v-else-if="type === 'textarea'"></textarea> <studip-wysiwyg :name="name" ref="inputfield" v-model="currentText" v-bind="$attrs" - v-on="$listeners" :required="required" v-else></studip-wysiwyg> </div> @@ -76,6 +70,7 @@ export default { components: { StudipWysiwyg }, + emits: ['allinputs', 'input', 'selectlanguage'], props: { name: { type: String, diff --git a/resources/vue/components/MemcachedCacheConfig.vue b/resources/vue/components/MemcachedCacheConfig.vue index ba06c7c0625633fc6f153bf304957238a703ecb1..9c3ac0c84821e8236bbf45139457c81346387aa6 100644 --- a/resources/vue/components/MemcachedCacheConfig.vue +++ b/resources/vue/components/MemcachedCacheConfig.vue @@ -37,6 +37,7 @@ <script> export default { name: 'MemcachedCacheConfig', + emits: ['is-valid'], props: { servers: { type: Array, diff --git a/resources/vue/components/Multiselect.vue b/resources/vue/components/Multiselect.vue index e1f180347313544098308297efde518183bdd5c2..ee13e8cd7a44f62ca9cb5921e221213d908e39df 100644 --- a/resources/vue/components/Multiselect.vue +++ b/resources/vue/components/Multiselect.vue @@ -5,9 +5,10 @@ :options="transformed_options" :reduce="(option) => option.id" v-bind="$attrs" - v-on="$listeners" > - <div slot="no-options"><translate>Keine Auswahlmöglichkeiten</translate></div> + <template v-slot:no-options> + {{ $gettext('Keine Auswahlmöglichkeiten') }} + </template> </v-select> </template> @@ -19,12 +20,16 @@ export default { components: { vSelect, }, + emits: ['update:model-value'], inheritAttrs: false, props: { name: { type: String, required: false }, + modelValue: { + required: false, + }, value: { required: false }, @@ -56,7 +61,7 @@ export default { watch: { selected: { handler(newValue, oldValue) { - this.$emit('input', newValue); + this.$emit('update:model-value', newValue); }, deep: true } diff --git a/resources/vue/components/MyCourses.vue b/resources/vue/components/MyCourses.vue index 40480251c4b2867d43430721446c5a27dde9382d..1c244cb018350b9a581d751793d6b1b921e66cc3 100644 --- a/resources/vue/components/MyCourses.vue +++ b/resources/vue/components/MyCourses.vue @@ -21,18 +21,17 @@ </studip-message-box> <component v-else :is="displayComponent" :icon-size="iconSize"></component> - <MountingPortal mount-to="#tiled-courses-sidebar-switch .sidebar-widget-content .widget-list" name="sidebar-switch"> - <my-courses-sidebar-switch></my-courses-sidebar-switch> - </MountingPortal> + <Teleport to="#tiled-courses-sidebar-switch .sidebar-widget-content .widget-list" name="sidebar-switch"> + <MyCoursesSidebarSwitch /> + </Teleport> - <MountingPortal mount-to="#tiled-courses-new-contents-toggle .sidebar-widget-content .widget-list" name="sidebar-content-toggle"> - <my-courses-new-content-toggle></my-courses-new-content-toggle> - </MountingPortal> + <Teleport to="#tiled-courses-new-contents-toggle .sidebar-widget-content .widget-list" name="sidebar-content-toggle"> + <MyCoursesNewContentToggle /> + </Teleport> </div> </template> <script> -import { sprintf } from 'sprintf-js'; import MyCoursesTables from './MyCoursesTables.vue'; import MyCoursesTiles from './MyCoursesTiles.vue'; import MyCoursesMixin from '../mixins/MyCoursesMixin.js'; @@ -69,6 +68,10 @@ export default { isEmpty () { return this.groups.length === 0; } + }, + beforeMount() { + document.querySelector('#tiled-courses-sidebar-switch .widget-list').innerHTML = ''; + document.querySelector('#tiled-courses-new-contents-toggle .widget-list').innerHTML = ''; } } </script> diff --git a/resources/vue/components/MyCoursesColorPicker.vue b/resources/vue/components/MyCoursesColorPicker.vue index cfcb380ac81e4883221e0068831a60c7a50689ab..68eae5d481246505d9ec68188583630445e2368c 100644 --- a/resources/vue/components/MyCoursesColorPicker.vue +++ b/resources/vue/components/MyCoursesColorPicker.vue @@ -11,6 +11,7 @@ <script> export default { name: "my-courses-color-picker", + emits: ['color-picked'], props: { course: { type: Object, @@ -33,9 +34,9 @@ export default { return classes; }, getTitle (i, index) { - let title = this.$gettextInterpolate( - this.$gettext('Gruppe %{ group }'), - {group: i} + let title = this.$gettext( + 'Gruppe %{ group }', + { group: i } ); if (this.course.group === index) { title += ' (' + this.$gettext('ausgewählt') + ')'; diff --git a/resources/vue/components/MyCoursesTables.vue b/resources/vue/components/MyCoursesTables.vue index b8b0ceb0e9af044db7d0b769942a1aec37549aff..08d57da3c259adb49b507eddb5668435179d1c25 100644 --- a/resources/vue/components/MyCoursesTables.vue +++ b/resources/vue/components/MyCoursesTables.vue @@ -43,8 +43,8 @@ <tr v-for="course in getOrderedCourses(subgroup.ids)" :data-course-id="course.id" :class="getCourseClasses(course)" :key="course.id"> <td :class="`gruppe${course.group}`"> <span class="sr-only"> - {{ $gettextInterpolate( - $gettext('Diese Veranstaltung gehört zur Farbgruppe %{group}'), + {{ $gettext( + 'Diese Veranstaltung gehört zur Farbgruppe %{group}', course ) }} </span> diff --git a/resources/vue/components/MyCoursesTiles.vue b/resources/vue/components/MyCoursesTiles.vue index 12b2627258ab00e501846ba0d2add16a44bd3fcd..c530fd15f79d487e71bb71fa2443a762420d5afa 100644 --- a/resources/vue/components/MyCoursesTiles.vue +++ b/resources/vue/components/MyCoursesTiles.vue @@ -1,7 +1,7 @@ <template> <div class="my-courses my-courses--tiles"> - <template v-for="(group, index) in groups"> - <div class="group-label" :key="index">{{ group.name }}</div> + <template v-for="(group, index) in groups" :key="index"> + <div class="group-label">{{ group.name }}</div> <article class="studip" v-for="subgroup in group.data" :key="subgroup.id" :class="getGroupCssClasses(subgroup)"> <header v-if="subgroup.label"> <h1> @@ -9,12 +9,12 @@ </h1> </header> <section class="studip-grid"> - <template v-for="course in getOrderedCourses(subgroup.ids)"> - <div class="course-group-label" v-if="isParent(course)" :key="course.id"> + <template v-for="course in getOrderedCourses(subgroup.ids)" :key="course.id"> + <div class="course-group-label" v-if="isParent(course)"> {{ getCourseName(course, getConfig('sem_number')) }} </div> - <article class="studip-grid-element" :data-course-id="course.id" :class="getCourseCssClasses(course)" :key="course.id"> + <article class="studip-grid-element" :data-course-id="course.id" :class="getCourseCssClasses(course)"> <header class="tiles-grid-element-header"> <span class="tiles-grid-element-options"> <studip-action-menu :items="getActionMenuForCourse(course, true)" diff --git a/resources/vue/components/Quicksearch.vue b/resources/vue/components/Quicksearch.vue index 575b464b3305d6b44dd9cab4f143ea7aa1b6d5fb..94c1d518f480374eb5715b4d8901b87f558648a2 100644 --- a/resources/vue/components/Quicksearch.vue +++ b/resources/vue/components/Quicksearch.vue @@ -31,6 +31,7 @@ <script> export default { name: 'quicksearch', + emits: ['update:modelValue'], props: { searchtype: { type: String, @@ -40,7 +41,7 @@ export default { type: String, required: false }, - value: { + modelValue: { type: String, required: false, default: '' @@ -59,6 +60,10 @@ export default { type: String, required: false, default: '' + }, + keepValue: { + type: Boolean, + default: false } }, inheritAttrs: false, @@ -118,7 +123,11 @@ export default { } this.results = []; - this.$emit('input', this.returnValue, this.inputValue); + this.$emit('update:modelValue', this.returnValue, this.inputValue); + + if (!this.keepValue) { + this.inputValue = ''; + } }, selectUp () { if (this.selected > 0) { @@ -158,8 +167,8 @@ export default { }, created () { this.initialize( - this.value, - this.autocomplete ? this.value : this.needle + this.modelValue, + this.autocomplete ? this.modelValue : this.needle ); }, computed: { @@ -177,7 +186,7 @@ export default { this.search(needle); } if (this.autocomplete) { - this.$emit('input', this.inputValue, this.inputValue); + this.$emit('update:modelValue', this.inputValue, this.inputValue); } } } diff --git a/resources/vue/components/RangeInput.vue b/resources/vue/components/RangeInput.vue index 650c750d52af9cb2469039500b94af8f144594cc..f28b091f2300798bf7de0c0685f6b41b83772f9d 100644 --- a/resources/vue/components/RangeInput.vue +++ b/resources/vue/components/RangeInput.vue @@ -9,21 +9,23 @@ :aria-valuemax="max" :aria-valuenow="myValue" v-bind="$attrs" - v-on="$listeners" v-model="myValue"> - <output for="fader"><translate :translate-params="{myValue: myValue || '1', max: max}">%{myValue} von %{max}</translate></output> + <output for="fader"> + {{ $gettext('%{myValue} von %{max}', {myValue: myValue || '1', max: max}) }} + </output> </div> </template> <script> export default { name: 'range-input', + emits: ['update:modelValue'], props: { name: { type: String, required: true }, - value: { + modelValue: { required: false, default: 1 }, @@ -49,7 +51,7 @@ export default { }; }, mounted () { - this.myValue = this.value > this.min ? this.value : this.min; + this.myValue = this.modelValue > this.min ? this.modelValue : this.min; if (this.myValue > this.max) { this.myValue = this.max; } @@ -57,8 +59,8 @@ export default { inheritAttrs: false, watch: { myValue: { - handler(newValue, oldValue) { - this.$emit('input', newValue); + handler(newValue) { + this.$emit('update:modelValue', newValue); }, deep: true } diff --git a/resources/vue/components/RedisCacheConfig.vue b/resources/vue/components/RedisCacheConfig.vue index ad035b37f0393df8cf145f10c9f0787969af2491..8ad4b529e8eded19ebd2b534f8a1bd03b5a32dec 100644 --- a/resources/vue/components/RedisCacheConfig.vue +++ b/resources/vue/components/RedisCacheConfig.vue @@ -22,6 +22,7 @@ <script> export default { name: 'RedisCacheConfig', + emits: ['is-valid'], props: { hostname: { type: String, diff --git a/resources/vue/components/SearchWithFilter.vue b/resources/vue/components/SearchWithFilter.vue index 45ca4377fe2aa7f4bf014625ea20a36110818a97..3c45ea369249e5bf8858a8b66bc36d77c535a0fa 100644 --- a/resources/vue/components/SearchWithFilter.vue +++ b/resources/vue/components/SearchWithFilter.vue @@ -61,6 +61,7 @@ export default { required: true, }, }, + emits: ['search'], components: { StudipIcon, }, diff --git a/resources/vue/components/SidebarWidget.vue b/resources/vue/components/SidebarWidget.vue index 692f4f904b245bcf5968cd4e3643bcaab22ab72f..9de82251424fb9a8acc1704b9d04bd1a000ea83c 100644 --- a/resources/vue/components/SidebarWidget.vue +++ b/resources/vue/components/SidebarWidget.vue @@ -15,6 +15,7 @@ <script> export default { name: 'sidebar-widget', + emits: ['scroll'], props: { title: String, }, @@ -27,7 +28,7 @@ export default { this.handleDebouncedScroll = _.debounce(this.handleScroll, 100); this.$refs.scrollable.addEventListener('scroll', this.handleDebouncedScroll); }, - beforeDestroy() { + beforeUnmount() { this.$refs.scrollable.removeEventListener('scroll', this.handleDebouncedScroll); }, }; diff --git a/resources/vue/components/StudipActionMenu.vue b/resources/vue/components/StudipActionMenu.vue index 9bce949d3b7ca3d0b233c315bd964142b7e09b13..a301ac3fa856fd5043fa6d62e0c5fab39dcb3281 100644 --- a/resources/vue/components/StudipActionMenu.vue +++ b/resources/vue/components/StudipActionMenu.vue @@ -72,6 +72,8 @@ </template> <script> +import { $gettext } from '../../assets/javascripts/lib/gettext'; + export default { name: 'studip-action-menu', props: { @@ -86,7 +88,7 @@ export default { title: { type: String, default() { - return this.$gettext('Aktionen'); + return $gettext('Aktionen'); } } }, @@ -144,7 +146,7 @@ export default { return Number.parseInt(collapseAt) <= this.items.filter((item) => item.type !== 'separator').length; }, tooltip () { - return this.context ? this.$gettextInterpolate(this.$gettext('%{title} für %{context}'), {title: this.title, context: this.context}) : this.title; + return this.context ? this.$gettext('%{title} für %{context}', {title: this.title, context: this.context}) : this.title; } } } diff --git a/resources/vue/components/StudipDateTime.vue b/resources/vue/components/StudipDateTime.vue index dfdc0c3f16a13d545f5a5d629a362ce23d8cbbc0..61f498ba0445fc81a2360acfd5a8ef85ca084580 100644 --- a/resources/vue/components/StudipDateTime.vue +++ b/resources/vue/components/StudipDateTime.vue @@ -30,7 +30,7 @@ return date.toISOString(); }, title () { - return this.display_relative() ? this.formatted_date(true) : false; + return this.display_relative() ? this.formatted_date(true) : null; } }, methods: { diff --git a/resources/vue/components/StudipDialog.vue b/resources/vue/components/StudipDialog.vue index 5de97ebdfeadaf1f750957cc2684b7f1be44bf4a..0861d1995f9660e3a0eb5634e6058092749d990a 100644 --- a/resources/vue/components/StudipDialog.vue +++ b/resources/vue/components/StudipDialog.vue @@ -1,9 +1,9 @@ <template> - <MountingPortal mountTo="body" append> + <Teleport to="body"> <focus-trap v-model="trap"> <div class="studip-dialog" @keydown.esc="closeDialog"> <transition name="dialog-fade"> - <div class="studip-dialog-backdrop"> + <div class="studip-dialog-backdrop" v-if="true"> <vue-resizeable class="resizable" style="position: absolute" @@ -15,8 +15,8 @@ :top="top" :width="currentWidth" :height="currentHeight" - :min-width="minW | checkEmpty" - :min-height="minH | checkEmpty" + :min-width="minW" + :min-height="minH" @mount="initSize" @resize:move="resizeHandler" @resize:start="resizeHandler" @@ -103,12 +103,12 @@ </transition> </div> </focus-trap> - </MountingPortal> + </Teleport> </template> <script> import { FocusTrap } from 'focus-trap-vue'; -import VueResizeable from 'vrp-vue-resizable'; +import VueResizeable from 'vue-resizable'; let uuid = 0; const dialogPadding = 3; @@ -118,6 +118,7 @@ export default { FocusTrap, VueResizeable, }, + emits: ['close', 'confirm'], props: { height: { type: [String, Number], @@ -268,11 +269,6 @@ export default { } } }, - filters: { - checkEmpty(value) { - return typeof value !== "number" ? 0 : value; - } - }, mounted() { if (this.defaultFocus) { this.$nextTick() diff --git a/resources/vue/components/StudipFileChooser.vue b/resources/vue/components/StudipFileChooser.vue index deb8aabe9e734ae2c18183ab4ac74e5b39c94578..d7ba0a07561fd1fa57f932e4cc020f8699c08ed2 100644 --- a/resources/vue/components/StudipFileChooser.vue +++ b/resources/vue/components/StudipFileChooser.vue @@ -14,7 +14,7 @@ export default { components: { FileChooserDialog, }, - + emits: ['select'], props: { selectable: { type: String, @@ -76,17 +76,20 @@ export default { if (this.selectedId === '') { return this.$gettext('Kein Ordner ausgewählt'); } - return this.$gettextInterpolate(this.$gettext('Ordner "%{folderName}" ausgewählt'), { - folderName: this.folderById({ id: this.selectedId })?.attributes?.name ?? '-', - }); + return this.$gettext( + 'Ordner "%{folderName}" ausgewählt' + , + { folderName: this.folderById({ id: this.selectedId })?.attributes?.name ?? '-' } + ); } if (this.selectedId === '') { return this.$gettext('Keine Datei ausgewählt'); } - return this.$gettextInterpolate(this.$gettext('Datei "%{fileName}" ausgewählt'), { - fileName: this.fileById({ id: this.selectedId })?.attributes?.name ?? '-', - }); + return this.$gettext( + 'Datei "%{fileName}" ausgewählt', + { fileName: this.fileById({ id: this.selectedId })?.attributes?.name ?? '-' } + ); }, }, methods: { diff --git a/resources/vue/components/StudipFolderSize.vue b/resources/vue/components/StudipFolderSize.vue index 0c6e0bc6d1221871666154358bfed3e6ced228f4..75f2acb956e7ee99ff13869f93e6f8323988b5fe 100644 --- a/resources/vue/components/StudipFolderSize.vue +++ b/resources/vue/components/StudipFolderSize.vue @@ -14,9 +14,11 @@ export default { return ''; } - return this.$gettextInterpolate( - this.$ngettext('%{count} Objekt', '%{count} Objekte', this.object_count), - {count: this.object_count} + return this.$ngettext( + '%{count} Objekt', + '%{count} Objekte', + this.object_count, + { count: this.object_count } ); } } diff --git a/resources/vue/components/StudipIcon.vue b/resources/vue/components/StudipIcon.vue index b20aba01833d6a5c94ccab26ebd4d88b787e39b2..b64dfb0802da4eb31effd77a9de145be4fe3a8a5 100644 --- a/resources/vue/components/StudipIcon.vue +++ b/resources/vue/components/StudipIcon.vue @@ -1,29 +1,27 @@ <template> <input v-if="name" + v-bind="$attrs" type="image" :name="name" :src="url" :style="{ width: realSize + 'px', height: realSize + 'px' }" :role="ariaRole" :class="cssClass" - v-bind="$attrs" - v-on="$listeners" :alt="$attrs.alt ?? ''" /> <img v-else + v-bind="$attrs" :src="url" :style="{ width: realSize + 'px', height: realSize + 'px' }" :role="ariaRole" :class="cssClass" - v-bind="$attrs" - v-on="$listeners" :alt="$attrs.alt ?? ''" /> </template> <script lang="ts"> -import Vue from 'vue'; +import { defineComponent } from 'vue'; function getCSSVariableValue(property: string): Number { const value = getComputedStyle(document.body).getPropertyValue(property); @@ -33,7 +31,7 @@ function getCSSVariableValue(property: string): Number { const defaultIconSize: Number = getCSSVariableValue('--icon-size-default'); const inlineIconSize: Number = getCSSVariableValue('--icon-size-inline'); -export default Vue.extend({ +export default defineComponent({ name: 'studip-icon', props: { ariaRole: { @@ -49,7 +47,10 @@ export default Vue.extend({ required: false, default: 'clickable', }, - shape: String, + shape: { + type: String, + required: true, + }, size: { type: Number, required: false, diff --git a/resources/vue/components/StudipIdentImage.vue b/resources/vue/components/StudipIdentImage.vue index 8879d1171f1f1d61b564616f03e7da234f92d363..f8df91f0b3c187612e0c9fcf78267e218443c2e8 100644 --- a/resources/vue/components/StudipIdentImage.vue +++ b/resources/vue/components/StudipIdentImage.vue @@ -5,8 +5,9 @@ <script> export default { name: 'studip-ident-image', + emits: ['update:modelValue'], props: { - value: { + modelValue: { type: String, }, showCanvas: { @@ -109,7 +110,7 @@ export default { ctx.fill(); }); - this.$emit('input', canvas.toDataURL()); + this.$emit('update:modelValue', canvas.toDataURL()); }, createPointInEllipse(ctx) { const x = this.random(); diff --git a/resources/vue/components/StudipMessageBox.vue b/resources/vue/components/StudipMessageBox.vue index b2cf48605f29555f90dba440f5d0d26f52162020..ad557a55ac0f7037423f4e15d0bfe583043f8476 100644 --- a/resources/vue/components/StudipMessageBox.vue +++ b/resources/vue/components/StudipMessageBox.vue @@ -22,6 +22,7 @@ <script> export default { name: 'studip-message-box', + emits: ['close'], props: { type: { type: String, // exception, error, success, info, warning diff --git a/resources/vue/components/StudipMultiPersonSearch.vue b/resources/vue/components/StudipMultiPersonSearch.vue index 5218a76e8c4ec7d1424fbf6427b1f208b8bcd9a9..c87dd4f977138252adea9431c82046292b025bc8 100644 --- a/resources/vue/components/StudipMultiPersonSearch.vue +++ b/resources/vue/components/StudipMultiPersonSearch.vue @@ -18,6 +18,7 @@ <script> export default { name: 'studip-multi-person-search', + emits: ['update:model-value'], props: { name: String, withDetail: { @@ -42,7 +43,7 @@ export default { }, computed: { id() { - return this._uid; + return this._.uid; }, count_text_id() { return this.id + '_count'; @@ -71,9 +72,9 @@ export default { }); let selection_header = document.createElement('div'); selection_header.setAttribute('id', this.count_text_id); - selection_header.innerText = this.$gettextInterpolate( - this.$gettext('Sie haben %{ count } Personen ausgewählt'), - {count: this.count} + selection_header.innerText = this.$gettext( + 'Sie haben %{ count } Personen ausgewählt', + { count: this.count } ); $('#' + this.select_box_id).multiSelect({ @@ -108,9 +109,9 @@ export default { if (searchcount === 0) { view.append( '--', - view.$gettextInterpolate( - view.$gettext('Es wurden keine neuen Ergebnisse für "%{ needle }" gefunden.'), - {needle: view.searchTerm} + view.$gettext( + 'Es wurden keine neuen Ergebnisse für "%{ needle }" gefunden.', + { needle: view.searchTerm } ), true ); @@ -164,9 +165,9 @@ export default { updateCount(){ this.count = $('#' + this.select_box_id + ' option:enabled:selected').length; - $('#' + this.count_text_id).text(this.$gettextInterpolate( - this.$gettext('Sie haben %{ count } Personen ausgewählt'), - {count: this.count} + $('#' + this.count_text_id).text(this.$gettext( + 'Sie haben %{ count } Personen ausgewählt', + { count: this.count } )); }, @@ -192,7 +193,7 @@ export default { } else { return_value = user_ids; } - this.$emit('input', return_value); + this.$emit('update:model-value', return_value); } }, } diff --git a/resources/vue/components/StudipPagination.vue b/resources/vue/components/StudipPagination.vue index 8b82f989460b82149c1c4a20ba12925a607421ba..5e6893bbf61a3a80b186b2abc67149e1622ca720 100644 --- a/resources/vue/components/StudipPagination.vue +++ b/resources/vue/components/StudipPagination.vue @@ -10,18 +10,18 @@ {{ $gettext('zurück') }} </button> </li> - <template v-for="offset of offsets"> - <li :key="'end-dots-' + offset" class="divider" + <template v-for="offset of offsets" :key="offset"> + <li class="divider" v-if="offset === (total_offsets - 1) && currentOffset < (total_offsets - 1) - (range + 1)"> … </li> - <li :key="'offset-' + offset" :class="{'current': offset === currentOffset, 'no-divider': offset === 0}"> + <li :class="{'current': offset === currentOffset, 'no-divider': offset === 0}"> <button class="pagination--link" @click.prevent="goTo(offset)"> <span class="audible">{{ $gettext('Seite') }}</span> {{ offset + 1 }} </button> </li> - <li :key="'start-dots' + offset" class="divider" + <li class="divider" v-if="offset === 0 && currentOffset > range + 1"> … </li> @@ -39,6 +39,7 @@ <script> export default { name: 'studip-pagination', + emits: ['updateOffset'], props: { currentOffset: { type: Number, @@ -60,11 +61,10 @@ export default { }, computed: { pagination_id() { - return 'pagination-label-' + this._uid; + return 'pagination-label-' + this._.uid; }, total_offsets() { - let total = Math.ceil(this.totalItems / this.itemsPerPage); - return total; + return Math.ceil(this.totalItems / this.itemsPerPage); }, offsets() { let offsets = [0, this.currentOffset, (this.total_offsets - 1)]; diff --git a/resources/vue/components/StudipProgressIndicator.vue b/resources/vue/components/StudipProgressIndicator.vue index 62a33a8840fa4c476571da1d25bc903d126b150c..bdc8af426aba5d39c707fc0983196c00322cf57b 100644 --- a/resources/vue/components/StudipProgressIndicator.vue +++ b/resources/vue/components/StudipProgressIndicator.vue @@ -5,7 +5,7 @@ {{ description }} </p> <p v-else class="progress-indicator-description-default"> - <translate>Lade...</translate> + {{ $gettext('Lade...') }} </p> </div> </template> diff --git a/resources/vue/components/StudipProxiedCheckbox.vue b/resources/vue/components/StudipProxiedCheckbox.vue index 76d07852b8de1f11f03e3d282f45b025180e3bce..332815338be2a0967aa9d2089fd702595cb78126 100644 --- a/resources/vue/components/StudipProxiedCheckbox.vue +++ b/resources/vue/components/StudipProxiedCheckbox.vue @@ -1,11 +1,10 @@ <script> +import { h } from 'vue'; + let uuid = 0; export default { name: 'studip-proxied-checkbox', - model: { - prop: 'selected', - event: 'change', - }, + emits: ['update:selected'], props: { name: String, id: String, @@ -27,7 +26,7 @@ export default { selected.add(this.value); } - this.$emit('change', [...selected.values()]); + this.$emit('update:selected', [...selected.values()]); } }, computed: { @@ -38,23 +37,15 @@ export default { return this.selected.includes(this.value); }, }, - render (createElement) { - const checkbox = createElement('input', { - attrs: { - type: 'checkbox', - name: this.name, - id: this.proxiedId, - value: this.value, - }, - domProps: { - checked: this.checked, - }, - on: { - change: this.changeCollection, - } + render () { + return h('input', { + type: 'checkbox', + name: this.name, + id: this.proxiedId, + value: this.value, + checked: this.checked ? true : null, + onChange: this.changeCollection, }); - - return checkbox; } }; </script> diff --git a/resources/vue/components/StudipProxyCheckbox.vue b/resources/vue/components/StudipProxyCheckbox.vue index b9cd2187429f167dfb489032b8a4c1001e9fa8b9..e19351da3906c58a2e543f834e2c28b9ff9824fb 100644 --- a/resources/vue/components/StudipProxyCheckbox.vue +++ b/resources/vue/components/StudipProxyCheckbox.vue @@ -1,12 +1,12 @@ <script> +import { h } from 'vue'; + let uuid = 0; export default { name: 'studip-proxy-checkbox', - model: { - prop: 'selected', - event: 'change', - }, + emits: ['update:selected'], props: { + name: String, id: String, total: { type: Array, @@ -15,11 +15,11 @@ export default { selected: { type: Array, required: true, - } + }, }, methods: { changeProxy () { - this.$emit('change', this.checked ? [] : [...this.total] ); + this.$emit('update:selected', this.checked ? [] : [...this.total] ); } }, computed: { @@ -33,23 +33,15 @@ export default { return this.selected.length > 0 && this.selected.length !== this.total.length; } }, - render (createElement) { - const checkbox = createElement('input', { - attrs: { - type: 'checkbox', - name: this.name, - id: this.proxyId - }, - domProps: { - checked: this.checked, - indeterminate: this.indeterminate, - }, - on: { - change: this.changeProxy, - } + render () { + return h('input', { + type: 'checkbox', + name: this.name, + id: this.proxyId, + checked: this.checked ? true : null, + indeterminate: this.indeterminate ? true : null, + onChange: this.changeProxy, }); - - return checkbox; } }; </script> diff --git a/resources/vue/components/StudipSelect.vue b/resources/vue/components/StudipSelect.vue index 196a91bd5fd4338b417d7870657acf870a13faf2..2bb209f4af21d2e533ccbca77d749706bbce5817 100644 --- a/resources/vue/components/StudipSelect.vue +++ b/resources/vue/components/StudipSelect.vue @@ -1,13 +1,13 @@ <template> <v-select ref="select" - @change="updateValue" - v-bind="{...$props, ...$attrs}" - v-on="$listeners" - :calculate-position="withPopper" - class="studip-v-select" - append-to-body + v-bind="{...$props, ...$attrs}" + :model-value="modelValue" + @update:modelValue="value => $emit('update:modelValue', value)" + :calculate-position="withPopper" + class="studip-v-select" + append-to-body > - <template v-for="(index, name) in $scopedSlots" v-slot:[name]="data"> + <template v-for="(index, name) in $slots" v-slot:[name]="data"> <slot :name="name" v-bind="data"></slot> </template> </v-select> @@ -17,13 +17,16 @@ import vSelect from 'vue-select'; import { createPopper } from '@popperjs/core' import 'vue-select/dist/vue-select.css' + export default { name: 'studip-select', + emits: ['update:modelValue'], inheritAttrs: false, components: { vSelect, }, props: { + modelValue: [String, Number, Object, Array], maxHeight: { type: String, default: '12em' @@ -31,7 +34,8 @@ export default { }, methods: { updateValue(val) { - this.$emit('input', val) + console.log('Updating value', val); + this.$emit('update:modelValue', val) }, withPopper(dropdownList, component, { width }) { if (component.$el?.offsetParent.classList.contains('studip-dialog-content')) { diff --git a/resources/vue/components/StudipSquareButton.vue b/resources/vue/components/StudipSquareButton.vue index fe89e8d6315d850d70134d6d515eea468321351b..42434dd02ebadd28e5a5125f256998b0e9c377ce 100644 --- a/resources/vue/components/StudipSquareButton.vue +++ b/resources/vue/components/StudipSquareButton.vue @@ -8,6 +8,7 @@ <script> export default { name: 'studip-square-button', + emits: ['click'], props: { icon: { type: String, diff --git a/resources/vue/components/StudipUserFilter.vue b/resources/vue/components/StudipUserFilter.vue index 20ca16201f7775a0731c31e2e0b67db23667ab4c..ea48383b88c8c7b9817276895dbd3b5a3d4837d3 100644 --- a/resources/vue/components/StudipUserFilter.vue +++ b/resources/vue/components/StudipUserFilter.vue @@ -61,6 +61,7 @@ <script> export default { name: 'StudipUserFilter', + emits: ['close', 'submit'], props: { filter: { type: Array, diff --git a/resources/vue/components/StudipWizardDialog.vue b/resources/vue/components/StudipWizardDialog.vue index 073c25f9fd391ef25816b5125338c92698ba8b16..5c60a27fac77d72c9831bcd9a647536bde3625f1 100644 --- a/resources/vue/components/StudipWizardDialog.vue +++ b/resources/vue/components/StudipWizardDialog.vue @@ -19,7 +19,7 @@ <p class="wizard-description"> {{ activeSlot.description }} </p> - <p v-if="requirements.length > 0" class="wizard-requirements"> + <div v-if="requirements.length > 0" class="wizard-requirements"> <span>{{ $gettext('Bitte geben Sie die folgenden Informationen an:') }}</span> <ul> <li v-for="(requirement, index) in requirements" :key="requirement.slot.name + '_' + index"> @@ -32,7 +32,7 @@ </button> </li> </ul> - </p> + </div> </div> <div class="wizard-content-wrapper"> <h2> @@ -102,6 +102,7 @@ import StudipDialog from './StudipDialog.vue' import StudipIcon from './StudipIcon.vue'; export default { name: 'studip-wizard-dialog', + emits: ['close', 'confirm'], components: { StudipDialog, StudipIcon diff --git a/resources/vue/components/StudipWysiwyg.vue b/resources/vue/components/StudipWysiwyg.vue index 3b36cc8b11192795e3705527e18d9a87078d09ff..c7de9c7f6e55f37d5c1845ab41f54113998a29be 100644 --- a/resources/vue/components/StudipWysiwyg.vue +++ b/resources/vue/components/StudipWysiwyg.vue @@ -1,30 +1,18 @@ -<template> - <ckeditor - :editor="editor" - :config="editorConfig" - @ready="onReady" - v-model="currentText" - @input="onInput" - /> -</template> - <script> import { ClassicEditor, BalloonEditor } from '../../assets/javascripts/chunks/wysiwyg.js'; +import {h, resolveComponent} from "vue"; export default { name: 'studip-wysiwyg', - model: { - prop: 'text', - event: 'input', - }, + emits: ['update:modelValue'], props: { - text: { + modelValue: { type: String, required: true, }, editorType: { type: String, - validator: function (value) { + validator(value) { return ['classic', 'balloon'].includes(value); }, default: 'classic', @@ -54,7 +42,7 @@ export default { methods: { onReady(editor) { this.createdEditor = editor; - this.currentText = this.text; + this.currentText = this.modelValue; if (this.shouldFocus) { this.focus(); @@ -64,7 +52,7 @@ export default { }, onInput(value) { this.currentText = value; - this.$emit('input', value); + this.$emit('update:modelValue', value); }, focus() { if (this.createdEditor) { @@ -77,5 +65,14 @@ export default { created() { STUDIP.loadChunk('mathjax'); }, + render() { + return h(resolveComponent('ckeditor'), { + editor: this.editor, + config: this.editorConfig, + modelValue: this.modelValue, + onInput: this.onInput, + onReady: this.onReady, + }) + } }; </script> diff --git a/resources/vue/components/SystemNotification.vue b/resources/vue/components/SystemNotification.vue index 82324a155d602ea3cd74025f549be70f417f9afa..d8c9384587b65c5eb8bdc03985014a05a667125f 100644 --- a/resources/vue/components/SystemNotification.vue +++ b/resources/vue/components/SystemNotification.vue @@ -59,6 +59,7 @@ <script> export default { name: 'SystemNotification', + emits: ['destroyMe'], props: { allowClosing: { type: Boolean, @@ -174,7 +175,7 @@ export default { }, timing); } }, - destroyed() { + unmounted() { this.globalOff('disrupt-system-notifications', this.disruptTimeout); this.globalOff('resume-system-notifications', this.initTimeout); } diff --git a/resources/vue/components/Timepicker.vue b/resources/vue/components/Timepicker.vue index d3a1ec6b9cc28dffdb011ceaf28b781942b5074a..0bef84e4157c73d1bc8140c5b70b7fc2380d0612 100644 --- a/resources/vue/components/Timepicker.vue +++ b/resources/vue/components/Timepicker.vue @@ -12,13 +12,14 @@ <script> export default { name: 'Timepicker', + emits: ['update:modelValue'], inheritAttrs: false, props: { name: { type: String, required: false }, - value: String, + modelValue: String, mintime: String, maxtime: String, placeholder: String, @@ -26,10 +27,10 @@ export default { computed: { timeValue: { get() { - return this.value; + return this.modelValue; }, set(value) { - this.$emit('input', value); + this.$emit('update:modelValue', value); } } } diff --git a/resources/vue/components/WikiEditor.vue b/resources/vue/components/WikiEditor.vue index 3fad25b017b6cb5461e0ee189cb4da967a26f5c5..8fc2e41292f8d993d4cc33d38c23372fe8ba8be5 100644 --- a/resources/vue/components/WikiEditor.vue +++ b/resources/vue/components/WikiEditor.vue @@ -46,7 +46,7 @@ @click.prevent="delegateEditMode(user.user_id)" class="button" > - {{ $gettextInterpolate($gettext('Schreibmodus an %{name} übergeben'), { name: user.fullname }, true) }} + {{ $gettext('Schreibmodus an %{name} übergeben', { name: user.fullname }, true) }} </button> </footer> </form> @@ -75,7 +75,6 @@ </div> <wiki-editor-online-users :users="onlineUsers"></wiki-editor-online-users> - </div> </template> <script> @@ -84,6 +83,7 @@ import StudipDateTime from "./StudipDateTime.vue"; import JSUpdater from "@/assets/javascripts/lib/jsupdater"; import ContentBar from "./ContentBar.vue"; import ContentBarBreadcrumbs from "./ContentBarBreadcrumbs.vue"; +import {markRaw} from "vue"; export default { name: 'wiki-editor', @@ -227,7 +227,7 @@ export default { this.focusEditor(); } - this.editor = editor; + this.editor = markRaw(editor); }); JSUpdater.register( diff --git a/resources/vue/components/WikiEditorOnlineUsers.vue b/resources/vue/components/WikiEditorOnlineUsers.vue index 71c7c1c9929662ec9a54fe38407f6c55ca97aee7..7bee689b83f834a7bcf4e01cd1d4048224117a86 100644 --- a/resources/vue/components/WikiEditorOnlineUsers.vue +++ b/resources/vue/components/WikiEditorOnlineUsers.vue @@ -1,5 +1,5 @@ <template> - <MountingPortal mountTo="#sidebar" append name="wiki_online_editing_users"> + <Teleport to="#sidebar" append name="wiki_online_editing_users"> <SidebarWidget :title="$gettext('Anwesende Personen')"> <template #content> <ol class="clean"> @@ -17,7 +17,7 @@ </ol> </template> </SidebarWidget> - </MountingPortal> + </Teleport> </template> <script> import SidebarWidget from "./SidebarWidget.vue"; diff --git a/resources/vue/components/admission/AdmissionRuleConfig.vue b/resources/vue/components/admission/AdmissionRuleConfig.vue index b9691a832ba056196277af78556c85991eeea8a4..921a6c2914c13cbd951e4ac955e336480106433b 100644 --- a/resources/vue/components/admission/AdmissionRuleConfig.vue +++ b/resources/vue/components/admission/AdmissionRuleConfig.vue @@ -28,8 +28,11 @@ </template> <script> +import {shallowRef} from "vue"; + export default { name: 'AdmissionRuleConfig', + emits: ['cancel', 'submit'], props: { type: { type: String, @@ -75,9 +78,8 @@ export default { }, created() { const file = STUDIP.Admission.availableRules[this.type]; - let components = {}; import(`@/vue/components/admission/${file}`).then((module) => { - this.component = module.default; + this.component = shallowRef(module.default); this.props = { id: this.theRule?.id, ruleData: this.theRule, diff --git a/resources/vue/components/admission/AdmissionRuleTypeSelector.vue b/resources/vue/components/admission/AdmissionRuleTypeSelector.vue index 498497aa5a184bb712a015cfab7e796778bea808..e8bbe8c9fe69adee5f770494dbf07ff6ff122c36 100644 --- a/resources/vue/components/admission/AdmissionRuleTypeSelector.vue +++ b/resources/vue/components/admission/AdmissionRuleTypeSelector.vue @@ -70,6 +70,7 @@ import StudipDialog from '../StudipDialog.vue'; export default { name: 'AdmissionRuleTypeSelector', + emits: ['close', 'configureRule'], components: { StudipProgressIndicator, StudipDialog }, props: { assignedRuleTypes: { diff --git a/resources/vue/components/admission/ConfigureCourseSet.vue b/resources/vue/components/admission/ConfigureCourseSet.vue index f23f17250e0f7df9bf140d8f6bb3e7c4e766c6f1..190c149de53564ffac1e0ab0a6a8a2ffa03adde9 100644 --- a/resources/vue/components/admission/ConfigureCourseSet.vue +++ b/resources/vue/components/admission/ConfigureCourseSet.vue @@ -44,7 +44,6 @@ <quicksearch v-if="instituteSearch" :searchtype="instituteSearch" name="institute" - :key="NaN" id="isearch" @input="addInstitute" :aria-label="$gettext('Geben Sie einen Suchbegriff mit mehr als 3 Zeichen ein, um nach Einrichtungen zu suchen')" @@ -79,14 +78,14 @@ </td> <td class="actions"> <button v-if="myInstitutes?.length !== 1" - :title="$gettextInterpolate( - $gettext('Zuordnung der Einrichtung %{name} entfernen'), + :title="$gettext( + 'Zuordnung der Einrichtung %{name} entfernen', { name: institute.name } - )" - :aria-label="$gettextInterpolate( - $gettext('Zuordnung der Einrichtung %{name} entfernen'), + )" + :aria-label="$gettext( + 'Zuordnung der Einrichtung %{name} entfernen', { name: institute.name } - )" + )" class="as-link delete-assignment" tabindex="0" @click.prevent="removeInstitute(index)"> @@ -139,8 +138,10 @@ <table v-if="availableCourses?.length > 0" class="default"> <caption> - {{ $gettextInterpolate($gettext('Veranstaltungen im %{semester}'), - { semester: allSemesters[selectedSemester].name }) }} + {{ $gettext( + 'Veranstaltungen im %{semester}', + { semester: allSemesters[selectedSemester].name } + ) }} </caption> <colgroup> <col style="width: 15px"> @@ -160,8 +161,10 @@ <input type="checkbox" :value="course.id" v-model="checkedCourses" - :title="$gettextInterpolate($gettext('Veranstaltung %{coursename} dem Anmeldeset zuordnen'), - { coursename: course.attributes.title })"> + :title="$gettext( + 'Veranstaltung %{coursename} dem Anmeldeset zuordnen', + { coursename: course.attributes.title } + )"> <template v-if="course.attributes['course-number']"> {{ course.attributes['course-number'] }} </template> @@ -195,12 +198,14 @@ {{ course.attributes.title }} </td> <td class="actions"> - <button :title="$gettextInterpolate( - $gettext('Zuordnung der Veranstaltung %{name} entfernen'), - { name: course.attributes.title })" - :aria-label="$gettextInterpolate( - $gettext('Zuordnung der Veranstaltung %{name} entfernen'), - { name: course.attributes.title })" + <button :title="$gettext( + 'Zuordnung der Veranstaltung %{name} entfernen', + { name: course.attributes.title } + )" + :aria-label="$gettext( + 'Zuordnung der Veranstaltung %{name} entfernen', + { name: course.attributes.title } + )" class="as-link delete-assignment" tabindex="0" @click.prevent="removeCourse(index)"> @@ -218,9 +223,10 @@ <button v-if="numApplicants > 0" class="button" @click.prevent="getApplicants"> - {{ $gettextInterpolate( - $gettext('Liste der Anmeldungen (%{number} Personen)'), - { number: numApplicants }) }} + {{ $gettext( + 'Liste der Anmeldungen (%{number} Personen)', + { number: numApplicants } + ) }} </button> <button v-if="numApplicants > 0" class="button" @@ -244,27 +250,27 @@ > <td v-html="rule.attributes.ruletext"></td> <td class="actions"> - <button :title="$gettextInterpolate( - $gettext('Regel %{name} bearbeiten'), + <button :title="$gettext( + 'Regel %{name} bearbeiten', { name: rule.attributes.name } - )" - :aria-label="$gettextInterpolate( - $gettext('Regel %{name} bearbeiten'), + )" + :aria-label="$gettext( + 'Regel %{name} bearbeiten', { name: rule.attributes.name } - )" + )" class="as-link edit-assignment" tabindex="0" @click.prevent="configureRule(rule.attributes.type, rule, index)"> <studip-icon shape="edit" :size="16"></studip-icon> </button> - <button :title="$gettextInterpolate( - $gettext('Regel %{name} entfernen'), + <button :title="$gettext( + 'Regel %{name} entfernen', { name: rule.attributes.name } - )" - :aria-label="$gettextInterpolate( - $gettext('Regel %{name} entfernen'), + )" + :aria-label="$gettext( + 'Regel %{name} entfernen', { name: rule.attributes.name } - )" + )" class="as-link delete-assignment" tabindex="0" data-confirm="$gettext('Soll die Regel wirklich entfernt werden?')" @@ -630,12 +636,9 @@ export default { && (rule?.length > 0 ? rule[0].attributes.payload['distribution-time'] > 0 : false); }, userListText(factor, count) { - return this.$gettextInterpolate( - factor < 1 - ? this.$gettext('%{number} Personen werden nachrangig eingetragen') - : this.$gettext('%{number} Personen werden bevorzugt'), - { number: count } - ); + return factor < 1 + ? this.$gettext('%{number} Personen werden nachrangig eingetragen', { number: count }) + : this.$gettext('%{number} Personen werden bevorzugt', { number: count }); }, openUserListUsers() { STUDIP.Dialog.fromURL( diff --git a/resources/vue/components/blubber/Comment.vue b/resources/vue/components/blubber/Comment.vue index 2d4c897933a72f74ad07422ddc3974d22b78c63a..a91648d46d707e96f3a3235c750bcd9d31efa165 100644 --- a/resources/vue/components/blubber/Comment.vue +++ b/resources/vue/components/blubber/Comment.vue @@ -52,6 +52,7 @@ <script> export default { name: 'BlubberComment', + emits: ['answer-comment', 'change-comment', 'edit-comment', 'remove-comment'], data: () => ({ localText: '', commentWidth: 0, diff --git a/resources/vue/components/blubber/CommunityPage.vue b/resources/vue/components/blubber/CommunityPage.vue index 8831978d45b8c70950f092d38b9eca37ce83871b..bd937e08e1a173c471518c68e7a55ea2d25b6f66 100644 --- a/resources/vue/components/blubber/CommunityPage.vue +++ b/resources/vue/components/blubber/CommunityPage.vue @@ -1,21 +1,19 @@ <template> - <div> - <BlubberPanel :threadId="threadId" :search="search" v-if="threadId" /> + <BlubberPanel :threadId="threadId" :search="search" v-if="threadId" /> - <MountingPortal mountTo="#blubber-search-widget" name="sidebar-blubber-search"> - <BlubberSearchWidget :search="search" /> - </MountingPortal> - <MountingPortal mountTo="#blubber-threads-widget" name="sidebar-blubber-threads"> - <BlubberThreadsWidget - :hasMoreThreads="hasMoreThreads" - :threadId="threadId" - :threads="threads" - @load-more-threads="onLoadMoreThreads" - @select-thread="onSelectThread" - class="blubber_threads_widget" - /> - </MountingPortal> - </div> + <Teleport to="#blubber-search-widget" name="sidebar-blubber-search"> + <BlubberSearchWidget :search="search" /> + </Teleport> + <Teleport to="#blubber-threads-widget" name="sidebar-blubber-threads"> + <BlubberThreadsWidget + :hasMoreThreads="hasMoreThreads" + :threadId="threadId" + :threads="threads" + @load-more-threads="onLoadMoreThreads" + @select-thread="onSelectThread" + class="blubber_threads_widget" + /> + </Teleport> </template> <script> @@ -82,7 +80,7 @@ export default { } }); }, - beforeDestroy() { + beforeUnmount() { this.globalOff('studip:select-blubber-thread', this.handleSelectBlubberThread); }, }; diff --git a/resources/vue/components/blubber/Composer.vue b/resources/vue/components/blubber/Composer.vue index 72a5d1c4c56c0b83fe55eb7f647c872219dc6e6c..4132a10293130e390c29eed1f30147f3a9a965ab 100644 --- a/resources/vue/components/blubber/Composer.vue +++ b/resources/vue/components/blubber/Composer.vue @@ -27,10 +27,7 @@ <script> export default { name: 'blubber-composer', - model: { - prop: 'text', - event: 'change', - }, + emits: ['update:modelValue', 'add-posting', 'pick-files', 'edit-previous'], props: { placeholder: { type: String, @@ -40,7 +37,7 @@ export default { type: Number, default: 0, }, - text: { + modelValue: { type: String, default: '', }, @@ -109,11 +106,11 @@ export default { }, saveCommentToSession() { this.resizeTextarea(); - this.$emit('change', this.localText); + this.$emit('update:modelValue', this.localText); }, }, mounted() { - this.localText = this.text; + this.localText = this.modelValue; this.$nextTick(() => { this.resizeTextarea(); }); diff --git a/resources/vue/components/blubber/Panel.vue b/resources/vue/components/blubber/Panel.vue index f70d1f637a2fd7cf565828b51f6709b551a24cb7..d38b5232a44852caa9b391c11f6ef9527833fec4 100644 --- a/resources/vue/components/blubber/Panel.vue +++ b/resources/vue/components/blubber/Panel.vue @@ -5,7 +5,7 @@ v-if="!doneFetching" /> - <div class="blubber_panel" v-else-if="thread"> + <template v-else-if="thread"> <div id="blubber_stream_container"> <BlubberThread ref="thread" @@ -24,7 +24,7 @@ ></BlubberThread> </div> <BlubberSideInfo :thread="thread" /> - </div> + </template> </template> <script> diff --git a/resources/vue/components/blubber/Thread.vue b/resources/vue/components/blubber/Thread.vue index 676ff35e6b649161be1406e780bd9f5ffcd5dd4f..e7a4c4188fa1cea80a0d9c5d53c022150c82ecbd 100644 --- a/resources/vue/components/blubber/Thread.vue +++ b/resources/vue/components/blubber/Thread.vue @@ -67,6 +67,15 @@ export default { BlubberComposer, ThreadSubscriber, }, + emits: [ + 'add-posting', + 'change-comment', + 'load-newer', + 'load-older', + 'pick-files', + 'remove-comment', + 'subscribe-thread', + ], props: { comments: { type: Array, @@ -218,7 +227,7 @@ export default { } }); }, - beforeDestroy() { + beforeUnmount() { this.$refs.scrollable.removeEventListener('scroll', this.handleDebouncedScroll); }, beforeUpdate() { diff --git a/resources/vue/components/blubber/ThreadSubscriber.vue b/resources/vue/components/blubber/ThreadSubscriber.vue index c259a7ad5393de26b62d46ab594469a59cbcebe6..28ad7e00059a7fc81defaf5a119e3e6850e68188 100644 --- a/resources/vue/components/blubber/ThreadSubscriber.vue +++ b/resources/vue/components/blubber/ThreadSubscriber.vue @@ -14,9 +14,10 @@ </div> </template> <script lang="ts"> -import Vue from 'vue'; +import { defineComponent } from 'vue'; -export default Vue.extend({ +export default defineComponent({ + emits: ['subscribe-thread'], props: { followed: { type: Boolean, diff --git a/resources/vue/components/blubber/ThreadsWidget.vue b/resources/vue/components/blubber/ThreadsWidget.vue index c19efb437e433dfee9247294f13af214c7624dfe..4eed89f54d3ad3124f8b89bb5660d3cb5744b221 100644 --- a/resources/vue/components/blubber/ThreadsWidget.vue +++ b/resources/vue/components/blubber/ThreadsWidget.vue @@ -43,6 +43,7 @@ import SidebarWidget from '../SidebarWidget.vue'; export default { + emits: ['load-more-threads', 'select-thread'], props: { hasMoreThreads: { type: Boolean, diff --git a/resources/vue/components/courseware/ActivitiesApp.vue b/resources/vue/components/courseware/ActivitiesApp.vue index 10c605655afe20d877d8e40c7bebd494bbd67437..af23647da0978efa085ca48bb15cf45ab6c92a4a 100644 --- a/resources/vue/components/courseware/ActivitiesApp.vue +++ b/resources/vue/components/courseware/ActivitiesApp.vue @@ -1,12 +1,12 @@ <template> <div class="cw-activities-wrapper"> <courseware-activities /> - <MountingPortal mountTo="#courseware-activities-widget-filter-type" name="sidebar-filter-type"> + <Teleport to="#courseware-activities-widget-filter-type" name="sidebar-filter-type"> <courseware-activities-widget-filter-type /> - </MountingPortal> - <MountingPortal mountTo="#courseware-activities-widget-filter-unit" name="sidebar-filter-unit"> + </Teleport> + <Teleport to="#courseware-activities-widget-filter-unit" name="sidebar-filter-unit"> <courseware-activities-widget-filter-unit /> - </MountingPortal> + </Teleport> </div> </template> diff --git a/resources/vue/components/courseware/AdminApp.vue b/resources/vue/components/courseware/AdminApp.vue index 4f2df7bbbcabfe2ff5aabbde5dd47bde4d4e3ae3..b0df1e16b3da7ecbbd69b76740ce04b0182adaa8 100644 --- a/resources/vue/components/courseware/AdminApp.vue +++ b/resources/vue/components/courseware/AdminApp.vue @@ -1,12 +1,12 @@ <template> <div class="cw-admin"> <courseware-admin-templates v-if="templatesView" /> - <MountingPortal mountTo="#courseware-admin-view-widget" name="sidebar-views"> + <Teleport to="#courseware-admin-view-widget" name="sidebar-views"> <courseware-admin-view-widget /> - </MountingPortal> - <MountingPortal mountTo="#courseware-admin-action-widget" name="sidebar-views"> + </Teleport> + <Teleport to="#courseware-admin-action-widget" name="sidebar-views"> <courseware-admin-action-widget /> - </MountingPortal> + </Teleport> </div> </template> diff --git a/resources/vue/components/courseware/CommentsApp.vue b/resources/vue/components/courseware/CommentsApp.vue index 417423b28a0f04ca040ae1363357b8685a3f45bc..52829ab81865fc7ab9180164c3bf3a07fed7c696 100644 --- a/resources/vue/components/courseware/CommentsApp.vue +++ b/resources/vue/components/courseware/CommentsApp.vue @@ -2,15 +2,15 @@ <div class="cw-comments-overview-wrapper"> <courseware-block-comments-overview v-if="showBlocks"/> <courseware-structural-element-comments-overview v-if="showElements"/> - <MountingPortal mountTo="#courseware-comments-overview-widget-filter-type" name="sidebar-views"> + <Teleport to="#courseware-comments-overview-widget-filter-type" name="sidebar-views"> <courseware-comments-overview-widget-filter-type /> - </MountingPortal> - <MountingPortal mountTo="#courseware-comments-overview-widget-filter-created" name="sidebar-views"> + </Teleport> + <Teleport to="#courseware-comments-overview-widget-filter-created" name="sidebar-views"> <courseware-comments-overview-widget-filter-created /> - </MountingPortal> - <MountingPortal mountTo="#courseware-comments-overview-widget-filter-unit" name="sidebar-views"> + </Teleport> + <Teleport to="#courseware-comments-overview-widget-filter-unit" name="sidebar-views"> <courseware-comments-overview-widget-filter-unit /> - </MountingPortal> + </Teleport> </div> </template> diff --git a/resources/vue/components/courseware/ContentBookmarkApp.vue b/resources/vue/components/courseware/ContentBookmarkApp.vue index b0c9fbc51d2998ed6e7a29f2535d117ae9702c65..faf4db6b4065c3d74e7d7544a7a17407383c75eb 100644 --- a/resources/vue/components/courseware/ContentBookmarkApp.vue +++ b/resources/vue/components/courseware/ContentBookmarkApp.vue @@ -1,9 +1,9 @@ <template> <div class="cw-content-bookmark"> <courseware-content-bookmarks /> - <MountingPortal mountTo="#courseware-content-bookmark-filter-widget" name="sidebar-views"> + <Teleport to="#courseware-content-bookmark-filter-widget" name="sidebar-views"> <courseware-content-bookmark-filter-widget /> - </MountingPortal> + </Teleport> </div> </template> diff --git a/resources/vue/components/courseware/CoursewareAdminTemplates.vue b/resources/vue/components/courseware/CoursewareAdminTemplates.vue index a0b17e6a60c583bef4f5247dfaba98519cf3942a..b82c8446d5c1ec8dc4f7fde06dddbf7b50f15b79 100644 --- a/resources/vue/components/courseware/CoursewareAdminTemplates.vue +++ b/resources/vue/components/courseware/CoursewareAdminTemplates.vue @@ -2,13 +2,13 @@ <div class="cw-admin-templates"> <table class="default"> <caption> - <translate>Vorlagen</translate> + {{ $gettext('Vorlagen') }} </caption> <thead> <tr> - <th><translate>Art des Lernmaterials</translate></th> - <th><translate>Name</translate></th> - <th class="actions"><translate>Aktionen</translate></th> + <th>{{ $gettext('Art des Lernmaterials') }}</th> + <th>{{ $gettext('Name') }}</th> + <th class="actions">{{ $gettext('Aktionen') }}</th> </tr> </thead> <tbody> @@ -40,27 +40,27 @@ <template v-slot:dialogContent> <form class="default" @submit.prevent=""> <label> - <translate>Name der neuen Vorlage</translate> + {{ $gettext('Name der neuen Vorlage') }}} <input v-model="newTemplateName" type="text" /> </label> <label> - <translate>Art des Lernmaterials</translate> + {{ $gettext('Art des Lernmaterials') }} <select v-model="newElementPurpose"> - <option value="content"><translate>Inhalt</translate></option> - <option value="template"><translate>Aufgabenvorlage</translate></option> - <option value="oer"><translate>OER-Material</translate></option> - <option value="portfolio"><translate>ePortfolio</translate></option> - <option value="draft"><translate>Entwurf</translate></option> - <option value="other"><translate>Sonstiges</translate></option> + <option value="content">{{ $gettext('Inhalt') }}</option> + <option value="template">{{ $gettext('Aufgabenvorlage') }}</option> + <option value="oer">{{ $gettext('OER-Material') }}</option> + <option value="portfolio">{{ $gettext('ePortfolio') }}</option> + <option value="draft">{{ $gettext('Entwurf') }}</option> + <option value="other">{{ $gettext('Sonstiges') }}</option> </select> </label> <label> - <translate>Vorlage</translate><br> + {{ $gettext('Vorlage') }}<br> <button class="button" @click.prevent="chooseFile" > - <translate>Vorlage-Archiv auswählen</translate> + {{ $gettext('Vorlage-Archiv auswählen') }} </button> <div v-if="importZip" class="cw-import-zip"> <header>{{ importZip.name }}</header> @@ -84,18 +84,18 @@ <template v-slot:dialogContent> <form class="default" @submit.prevent=""> <label> - <translate>Name der neuen Vorlage</translate> + {{ $gettext('Name der neuen Vorlage') }} <input v-model="currentTemplate.attributes.name" type="text" /> </label> <label> - <translate>Art des Lernmaterials</translate> + {{ $gettext('Art des Lernmaterials') }} <select v-model="currentTemplate.attributes.purpose"> - <option value="content"><translate>Inhalt</translate></option> - <option value="template"><translate>Aufgabenvorlage</translate></option> - <option value="oer"><translate>OER-Material</translate></option> - <option value="portfolio"><translate>ePortfolio</translate></option> - <option value="draft"><translate>Entwurf</translate></option> - <option value="other"><translate>Sonstiges</translate></option> + <option value="content">{{ $gettext('Inhalt') }}</option> + <option value="template">{{ $gettext('Aufgabenvorlage') }}</option> + <option value="oer">{{ $gettext('OER-Material') }}</option> + <option value="portfolio">{{ $gettext('ePortfolio') }}</option> + <option value="draft">{{ $gettext('Entwurf') }}</option> + <option value="other">{{ $gettext('Sonstiges') }}</option> </select> </label> </form> @@ -235,4 +235,4 @@ export default { } } -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/CoursewareBlockCommentsOverview.vue b/resources/vue/components/courseware/CoursewareBlockCommentsOverview.vue index d3fd69c376002214aadb5d25e791ecbcab184bf3..6d108d41cb94a91cd28d17bacf46af1d4319285c 100644 --- a/resources/vue/components/courseware/CoursewareBlockCommentsOverview.vue +++ b/resources/vue/components/courseware/CoursewareBlockCommentsOverview.vue @@ -47,21 +47,25 @@ <a href="#" @click.prevent="enableCommentsDialog(block)"> - {{ $gettextInterpolate( - $ngettext('%{length} Kommentar', '%{length} Kommentare', block.comments.length), - {length: block.comments.length} + {{ $ngettext( + '%{length} Kommentar', + '%{length} Kommentare', + block.comments.length, + { length: block.comments.length } ) }} </a> </td> <td class="responsive-hidden"> - <a + <a v-if="block.element.attributes['can-edit']" href="#" @click.prevent="enableFeedbackDialog(block)" > - {{ $gettextInterpolate( - $ngettext('%{length} Anmerkung', '%{length} Anmerkungen', block.feedbacks.length), - {length: block.feedbacks.length} + {{ $ngettext( + '%{length} Anmerkung', + '%{length} Anmerkungen', + block.feedbacks.length, + { length: block.feedbacks.length } ) }} </a> <template v-else> diff --git a/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue b/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue index d157f5b42b96b68e94cddfb7bdb5675c2b92c2a1..99b8fc6ae78e9fdf12adcaddedd6e4d4aef8bd4f 100644 --- a/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue +++ b/resources/vue/components/courseware/CoursewareCommentsOverviewDialog.vue @@ -12,7 +12,7 @@ </h2> <courseware-block-comments v-if="isBlock && isComment" - :block="item" + :block="item" /> <courseware-structural-element-comments v-if="isStructuralElement && isComment" @@ -20,7 +20,7 @@ /> <courseware-block-feedback v-if="isBlock && isFeedback" - :block="item" + :block="item" /> <courseware-structural-element-feedback v-if="isStructuralElement && isFeedback" @@ -44,6 +44,7 @@ export default { CoursewareStructuralElementComments, CoursewareStructuralElementFeedback }, + emits: ['close'], props: { itemType: String, item: Object, diff --git a/resources/vue/components/courseware/CoursewareContentLinks.vue b/resources/vue/components/courseware/CoursewareContentLinks.vue index 7260fd6401014ca4bfab05e345de8d6c8012a50d..407543940dfd7e4bc8a4e7a8ee62ea5c24a14ce9 100644 --- a/resources/vue/components/courseware/CoursewareContentLinks.vue +++ b/resources/vue/components/courseware/CoursewareContentLinks.vue @@ -2,15 +2,15 @@ <div> <table class="default"> <caption> - <translate>Öffentlich verlinkte Seiten</translate> + {{ $gettext('Öffentlich verlinkte Seiten') }} </caption> <thead> <tr> - <th><translate>Seite</translate></th> - <th><translate>Link</translate></th> - <th><translate>Passwort</translate></th> - <th><translate>Ablaufdatum</translate></th> - <th class="actions"><translate>Aktionen</translate></th> + <th>{{ $gettext('Seite') }}</th> + <th>{{ $gettext('Link') }}</th> + <th>{{ $gettext('Passwort') }}</th> + <th>{{ $gettext('Ablaufdatum') }}</th> + <th class="actions">{{ $gettext('Aktionen') }}</th> </tr> </thead> <tbody> @@ -56,11 +56,11 @@ <template v-slot:dialogContent> <form class="default" @submit.prevent=""> <label> - <translate>Passwort</translate> + {{ $gettext('Passwort') }} <input type="text" v-model="currentLink.attributes.password" /> </label> <label> - <translate>Ablaufdatum</translate> + {{ $gettext('Ablaufdatum') }} <input v-model="currentLink.attributes['expire-date']" type="date" class="size-l" /> </label> </form> @@ -83,7 +83,7 @@ export default { data() { return { menuItems: [ - { id: 1, label: this.$gettext('Link in Zwischenablage kopieren'), icon: 'clipboard', emit: 'copyLinkToClipboard'}, + { id: 1, label: this.$gettext('Link in Zwischenablage kopieren'), icon: 'clipboard', emit: 'copyLinkToClipboard'}, { id: 2, label: this.$gettext('Link bearbeiten'), icon: 'edit', emit: 'editLink' }, { id: 3, label: this.$gettext('Link löschen'), icon: 'trash', emit: 'deleteLink' } ], @@ -162,7 +162,7 @@ export default { if (!date) { return '-'; } - return new Date(date).toLocaleDateString(navigator.language, { + return new Date(date).toLocaleDateString(navigator.language, { year: 'numeric', month: '2-digit', day: '2-digit' diff --git a/resources/vue/components/courseware/CoursewareContentPermissions.vue b/resources/vue/components/courseware/CoursewareContentPermissions.vue index 841fc8ffd8a5228859208afeaf22f1abf6591736..56c52d6d2af18ac4fc108ca4f4833c84848734ed 100644 --- a/resources/vue/components/courseware/CoursewareContentPermissions.vue +++ b/resources/vue/components/courseware/CoursewareContentPermissions.vue @@ -42,7 +42,7 @@ <td class="perm"> <input class="right" - :title="$gettextInterpolate($gettext('Leserechte für %{ userName }'), { userName: user_perm.username }, true)" + :title="$gettext('Leserechte für %{ userName }', { userName: user_perm.username }, true)" type="radio" :name="`${user_perm.id}_right`" value="read" @@ -53,7 +53,7 @@ <td class="perm"> <input class="right" - :title="$gettextInterpolate($gettext('Lese- und Schreibrechte für %{ userName }'), { userName: user_perm.username }, true)" + :title="$gettext('Lese- und Schreibrechte für %{ userName }', { userName: user_perm.username }, true)" type="radio" :name="`${user_perm.id}_right`" value="write" @@ -75,7 +75,7 @@ <td class="actions"> <button class="cw-permission-delete" - :title="$gettextInterpolate($gettext('Entfernen der Rechte von %{ userName }'), { userName: user_perm.username }, true)" + :title="$gettext('Entfernen der Rechte von %{ userName }', { userName: user_perm.username }, true)" @click.prevent="confirmDeleteUserPerm(index)" > </button> @@ -141,6 +141,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-content-permissions', + emits: ['updateContentApproval'], props: { element: Object, }, @@ -188,13 +189,13 @@ export default { getExpiryTitle(userName, date) { if (date) { - return this.$gettextInterpolate( - this.$gettext('Die Berechtigungen für %{ userName } laufen am folgendem Datum ab: %{ dateStr }'), + return this.$this.$gettext( + 'Die Berechtigungen für %{ userName } laufen am folgendem Datum ab: %{ dateStr }', { userName: userName, dateStr: new Date(date).toLocaleDateString() } ); } else { - return this.$gettextInterpolate( - this.$gettext('Das Ablaufdatum der Berechtigungen für %{ userName }'), + return this.$this.$gettext( + 'Das Ablaufdatum der Berechtigungen für %{ userName }', { userName: userName } ); } diff --git a/resources/vue/components/courseware/CoursewareContentShared.vue b/resources/vue/components/courseware/CoursewareContentShared.vue index 0bdc4b5cfd2228596a3cae3af521f18c3a3a1f58..993a08bc3a945f15b12953810f95f3c185cf0ae8 100644 --- a/resources/vue/components/courseware/CoursewareContentShared.vue +++ b/resources/vue/components/courseware/CoursewareContentShared.vue @@ -73,7 +73,7 @@ <studip-dialog v-if="showClearReleases" :title="$gettext('Löschen der Freigabe')" - :question="$gettextInterpolate($gettext('Möchten Sie die Freigabe für %{ pageTitle} wirklich löschen?'), {pageTitle: this.selectedElement.attributes.title})" + :question="$gettext('Möchten Sie die Freigabe für %{ pageTitle} wirklich löschen?', { pageTitle: this.selectedElement.attributes.title })" height="220" @confirm="clearReleases" @close="closeClearReleases" diff --git a/resources/vue/components/courseware/CoursewareStructuralElementCommentsOverview.vue b/resources/vue/components/courseware/CoursewareStructuralElementCommentsOverview.vue index f9b6f1a4f89b8b379a97857305859a058fd2e4c3..e0b264c211baa4d9bc26f03d475107905f262321 100644 --- a/resources/vue/components/courseware/CoursewareStructuralElementCommentsOverview.vue +++ b/resources/vue/components/courseware/CoursewareStructuralElementCommentsOverview.vue @@ -47,9 +47,11 @@ :title="$gettext('Kommentare anzeigen')" @click.prevent="enableCommentsDialog(element)" > - {{ $gettextInterpolate( - $ngettext('%{length} Kommentar', '%{length} Kommentare', element.comments.length), - {length: element.comments.length} + {{ $ngettext( + '%{length} Kommentar', + '%{length} Kommentare', + element.comments.length, + { length: element.comments.length } ) }} </a> </td> @@ -60,8 +62,10 @@ :title="$gettext('Anmerkungen anzeigen')" @click.prevent="enableFeedbackDialog(element)" > - {{ $gettextInterpolate( - $ngettext('%{length} Anmerkung', '%{length} Anmerkungen', element.feedbacks.length), + {{ $ngettext( + '%{length} Anmerkung', + '%{length} Anmerkungen', + element.feedbacks.length, {length: element.feedbacks.length} ) }} </a> diff --git a/resources/vue/components/courseware/IndexApp.vue b/resources/vue/components/courseware/IndexApp.vue index 2b1ad72a5e6db79a62d6117e014bafd03728138e..62fbf6759dda80bd62c4653e8c202f53c13a6de4 100644 --- a/resources/vue/components/courseware/IndexApp.vue +++ b/resources/vue/components/courseware/IndexApp.vue @@ -7,11 +7,11 @@ :canVisit="canVisit" :structural-element="selected" :ordered-structural-elements="orderedStructuralElements" - @select="selectStructuralElement" + @select-element="selectStructuralElement" ></courseware-structural-element> - <MountingPortal mountTo="#courseware-search-widget" name="sidebar-search"> + <Teleport to="#courseware-search-widget" name="sidebar-search"> <courseware-search-widget v-if="selected !== null"></courseware-search-widget> - </MountingPortal> + </Teleport> </div> <studip-progress-indicator v-if="structureLoadingState === 'loading'" @@ -128,12 +128,15 @@ export default { this.selectStructuralElement(selectedId); window.scrollTo({ top: 0 }); }, - async structuralElements(newElements, oldElements) { - // compute order of structural elements once more - await this.buildStructure(); + structuralElements: { + async handler(newElements, oldElements) { + // compute order of structural elements once more + await this.buildStructure(); - // throw away stale cache - this.invalidateStructureCache(); + // throw away stale cache + this.invalidateStructureCache(); + }, + deep: true }, }, }; diff --git a/resources/vue/components/courseware/PublicApp.vue b/resources/vue/components/courseware/PublicApp.vue index 0a082f0dc196e78a90429dba8460b5e76adbae12..ffaf83457d50ef8664ff6720c29cf3780e6ace91 100644 --- a/resources/vue/components/courseware/PublicApp.vue +++ b/resources/vue/components/courseware/PublicApp.vue @@ -25,11 +25,11 @@ /> <form v-if="!isAuthenticated" class="default" @submit.prevent=""> <label> - <translate>Passwort</translate> + {{ $gettext('Passwort') }} <input type="password" v-model="password"> </label> <button class="button" @click="submitPassword"> - <translate>Absenden</translate> + {{ $gettext('Absenden') }} </button> </form> </div> diff --git a/resources/vue/components/courseware/ShelfApp.vue b/resources/vue/components/courseware/ShelfApp.vue index 173be71bce4430e7a93f342d314a92d8fd3a9d5e..98e6f2a7c7d69ebdb301ea216a33d7c8a568bebe 100644 --- a/resources/vue/components/courseware/ShelfApp.vue +++ b/resources/vue/components/courseware/ShelfApp.vue @@ -9,9 +9,9 @@ <courseware-shelf-dialog-copy v-if="showUnitCopyDialog" /> <courseware-shelf-dialog-import v-if="showUnitImportDialog" /> <courseware-shelf-dialog-topics v-if="showUnitTopicsDialog" /> - <MountingPortal v-if="userIsTeacher || !inCourseContext" mountTo="#courseware-action-widget" name="sidebar-actions"> + <Teleport v-if="userIsTeacher || !inCourseContext" to="#courseware-action-widget" name="sidebar-actions"> <courseware-shelf-action-widget></courseware-shelf-action-widget> - </MountingPortal> + </Teleport> <courseware-companion-overlay /> </div> </template> diff --git a/resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue b/resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue index c0d5d0882efcdafa4279337654ce25664cda2f7c..564a8542cbeccdfa2f91dc1fb1fce259cbda6ee0 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBeforeAfterBlock.vue @@ -10,7 +10,7 @@ @closeEdit="initCurrentData" > <template #content> - <TwentyTwenty v-if="!isEmpty" :before="currentBeforeUrl" :after="currentAfterUrl" /> + <ImageCompare v-if="!isEmpty" :image1="currentBeforeUrl" :image2="currentAfterUrl" /> <courseware-companion-box v-if="isEmpty && canEdit" :msgCompanion="$gettext('Bitte wählen Sie ein Vorher- und ein Nachher-Bild aus.')" @@ -19,7 +19,7 @@ </template> <template v-if="canEdit" #edit> <courseware-tabs> - <courseware-tab :index="0" :name="$gettext('Vorher')" :selected="true"> + <courseware-tab :name="$gettext('Vorher')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Quelle') }} @@ -34,12 +34,19 @@ </label> <label v-if="currentBeforeSource === 'studip'"> {{ $gettext('Bilddatei') }} - <studip-file-chooser v-model="currentBeforeFileId" selectable="file" :courseId="context.id" :userId="userId" :isImage="true" :excludedCourseFolderTypes="excludedCourseFolderTypes"/> + <studip-file-chooser + v-model="currentBeforeFileId" + selectable="file" + :courseId="context.id" + :userId="userId" + :isImage="true" + :excludedCourseFolderTypes="excludedCourseFolderTypes" + /> </label> </form> </courseware-tab> - <courseware-tab :index="1" :name="$gettext('Nachher')"> - <form class="default" @submit.prevent=""> + <courseware-tab :name="$gettext('Nachher')"> + <form class="default" @submit.prevent="onSubmit"> <label> {{ $gettext('Quelle') }} <select v-model="currentAfterSource"> @@ -53,7 +60,13 @@ </label> <label v-if="currentAfterSource === 'studip'"> {{ $gettext('Bilddatei') }} - <studip-file-chooser v-model="currentAfterFileId" selectable="file" :courseId="context.id" :userId="userId" :isImage="true"/> + <studip-file-chooser + v-model="currentAfterFileId" + selectable="file" + :courseId="context.id" + :userId="userId" + :isImage="true" + /> </label> </form> </courseware-tab> @@ -67,15 +80,14 @@ <script> import BlockComponents from './block-components.js'; import blockMixin from '@/vue/mixins/courseware/block.js'; -import TwentyTwenty from 'vue-twentytwenty'; -import 'vue-twentytwenty/dist/vue-twentytwenty.css'; import { mapActions, mapGetters } from 'vuex'; +import ImageCompare from './ImageCompare.vue'; export default { name: 'courseware-before-after-block', mixins: [blockMixin], components: Object.assign(BlockComponents, { - TwentyTwenty, + ImageCompare, }), props: { block: Object, @@ -154,12 +166,12 @@ export default { } this.currentBeforeFile = this.beforeFile; - this.currentAfterFile = this.afterFile; + this.currentAfterFile = this.afterFile; }); this.loadImages(); } - + this.initCurrentData(); }, methods: { @@ -260,25 +272,7 @@ export default { if (newId) { this.currentAfterFile = this.fileRefById({ id: newId }); } - } - } + }, + }, }; </script> -<style scoped lang="scss"> -.cw-block-before-after { - .twentytwenty-container { - width: 100% !important; - z-index: 19; - .twentytwenty-handle { - z-index: 18; - } - .twentytwenty-overlay { - z-index: 17; - } - img { - width: 100%; - z-index: 16; - } - } -} -</style> diff --git a/resources/vue/components/courseware/blocks/CoursewareBlockActions.vue b/resources/vue/components/courseware/blocks/CoursewareBlockActions.vue index eea76fefd257faf5c71578333d5c5ee3024868da..468809074f87b74b2c323ec160d902ed2a27a1ab 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBlockActions.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBlockActions.vue @@ -26,6 +26,17 @@ export default { components: { StudipActionMenu, }, + emits: [ + 'activateComments', + 'copyToClipboard', + 'deactivateComments', + 'deleteBlock', + 'editBlock', + 'removeLock', + 'showExportOptions', + 'showFeedback', + 'showInfo', + ], props: { canEdit: Boolean, deleteOnly: { @@ -98,9 +109,9 @@ export default { if (!this.blocked || this.blockedByThisUser) { menuItems.push({ id: 9, - label: this.$gettext('Block löschen'), + label: this.$gettext('Block löschen'), icon: 'trash', - emit: 'deleteBlock' + emit: 'deleteBlock' }); } menuItems.push({ diff --git a/resources/vue/components/courseware/blocks/CoursewareBlockComments.vue b/resources/vue/components/courseware/blocks/CoursewareBlockComments.vue index 9b1cc44623c30ead5d09986d92ab2c063db85b76..dc03f2ad00e58cc3aa30f72f1d2354c01b2e490e 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBlockComments.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBlockComments.vue @@ -12,7 +12,7 @@ </div> <div class="cw-block-comment-create"> <textarea v-model="createComment" :placeholder="placeHolder" spellcheck="true"></textarea> - <button class="button" @click="postComment"><translate>Senden</translate></button> + <button class="button" @click="postComment">{{ $gettext('Senden') }}</button> </div> </div> </section> @@ -24,6 +24,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-block-comments', + emits: ['hasComments'], components: { CoursewareTalkBubble, }, diff --git a/resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue b/resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue index e29e15a14079f391dfb3d54883e7ec35239489d7..59cf406e246f81423ec0380024e0ec31a01c0e0c 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBlockDiscussion.vue @@ -88,13 +88,12 @@ export default { return ((this.canEdit || this.userIsTeacher) && this.hasFeedback) || this.displayFeedback; }, callToActionTitleFeedback() { - return this.$gettextInterpolate( - this.$ngettext( - '%{length} Anmerkung (Nur für Nutzende mit Schreibrechten sichtbar)', - '%{length} Anmerkungen (Nur für Nutzende mit Schreibrechten sichtbar)', - this.feedbackCounter - ), - { length: this.feedbackCounter }); + return this.$ngettext( + '%{length} Anmerkung (Nur für Nutzende mit Schreibrechten sichtbar)', + '%{length} Anmerkungen (Nur für Nutzende mit Schreibrechten sichtbar)', + this.feedbackCounter, + { length: this.feedbackCounter } + ); }, comments() { const { id, type } = this.block; @@ -105,13 +104,12 @@ export default { return this.comments?.length ?? 0; }, callToActionTitleComments() { - return this.$gettextInterpolate( - this.$ngettext( - '%{length} Kommentar', - '%{length} Kommentare', - this.commentsCounter - ), - { length: this.commentsCounter }); + return this.$ngettext( + '%{length} Kommentar', + '%{length} Kommentare', + this.commentsCounter, + { length: this.commentsCounter } + ); }, }, }; diff --git a/resources/vue/components/courseware/blocks/CoursewareBlockEdit.vue b/resources/vue/components/courseware/blocks/CoursewareBlockEdit.vue index 82d1abcbf1358aa73471e7f721543b7781796316..1c8b08c1a0fe6598dc5244cab7c7f039266478fc 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBlockEdit.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBlockEdit.vue @@ -18,6 +18,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-block-edit', + emits: ['close', 'store'], props: { block: Object, preview: Boolean @@ -31,7 +32,7 @@ export default { beforeMount() { this.originalBlock = this.block; }, - beforeDestroy() { + beforeUnmount() { if (this.exitHandler) { this.$emit('store'); } diff --git a/resources/vue/components/courseware/blocks/CoursewareBlockExportOptions.vue b/resources/vue/components/courseware/blocks/CoursewareBlockExportOptions.vue index 71f6adca9eb78a836b76b6ef5ee7a5d8eb5462f3..aeb66a5c6c284dd440e643431a6eeb7deb2cb9aa 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBlockExportOptions.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBlockExportOptions.vue @@ -1,8 +1,8 @@ <template> <section class="cw-block-export-options"> - <header><translate>Export Optionen</translate></header> + <header>{{ $gettext('Export Optionen') }}</header> <div class="cw-block-features-content"> - <button class="button" @click="$emit('close')"><translate>Schließen</translate></button> + <button class="button" @click="$emit('close')">{{ $gettext('Schließen') }}</button> </div> </section> </template> @@ -10,7 +10,7 @@ <script> export default { name: 'courseware-block-export-options', - components: {}, + emits: ['close'], props: { block: Object, }, diff --git a/resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue b/resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue index 705328ecac94dda902caaf06b839acc787ea67eb..e955899629e6788daf1268db0c4104deac2239da 100644 --- a/resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue +++ b/resources/vue/components/courseware/blocks/CoursewareBlockInfo.vue @@ -3,26 +3,28 @@ <header>{{ $gettext('Informationen') }}</header> <div class="cw-block-features-content cw-block-info-content"> <table class="cw-block-info-table"> - <tr> - <td>{{ $gettext('Blockbeschreibung') }}</td> - <td><slot name="info" /></td> - </tr> - <tr> - <td>{{ $gettext('Block wurde erstellt von') }}</td> - <td>{{ owner }}</td> - </tr> - <tr> - <td>{{ $gettext('Block wurde erstellt am') }}:</td> - <td><iso-date :date="block.attributes.mkdate" /></td> - </tr> - <tr> - <td>{{ $gettext('Zuletzt bearbeitet von') }}:</td> - <td>{{ editor }}</td> - </tr> - <tr> - <td>{{ $gettext('Zuletzt bearbeitet am') }}:</td> - <td><iso-date :date="block.attributes.chdate" /></td> - </tr> + <tbody> + <tr> + <td>{{ $gettext('Blockbeschreibung') }}</td> + <td><slot name="info" /></td> + </tr> + <tr> + <td>{{ $gettext('Block wurde erstellt von') }}</td> + <td>{{ owner }}</td> + </tr> + <tr> + <td>{{ $gettext('Block wurde erstellt am') }}:</td> + <td><iso-date :date="block.attributes.mkdate" /></td> + </tr> + <tr> + <td>{{ $gettext('Zuletzt bearbeitet von') }}:</td> + <td>{{ editor }}</td> + </tr> + <tr> + <td>{{ $gettext('Zuletzt bearbeitet am') }}:</td> + <td><iso-date :date="block.attributes.chdate" /></td> + </tr> + </tbody> </table> <button class="button" @click="$emit('close')">{{ $gettext('Schließen') }}</button> </div> @@ -36,6 +38,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-block-info', components: { IsoDate }, + emits: ['close'], props: { block: Object, }, diff --git a/resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue b/resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue index 21a52006940df26b983009c3a72c11b4431310cd..49c9cfc1f0f5ae0d3b6b7c3a7a73f3ba6460f7ce 100644 --- a/resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareCanvasBlock.vue @@ -106,9 +106,7 @@ <template v-if="canEdit" #edit> <courseware-tabs> <courseware-tab - :index="0" :name="$gettext('Grunddaten')" - :selected="true" > <form class="default" @submit.prevent=""> <label> @@ -136,7 +134,6 @@ </form> </courseware-tab> <courseware-tab - :index="1" :name="$gettext('Einstellungen')" > <form class="default" @submit.prevent=""> diff --git a/resources/vue/components/courseware/blocks/CoursewareChartBlock.vue b/resources/vue/components/courseware/blocks/CoursewareChartBlock.vue index fa85a4119e3d3bcae7363bef4f933208574bf0c0..33ef473c97c0a055470a391113cb1e298a08c63a 100644 --- a/resources/vue/components/courseware/blocks/CoursewareChartBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareChartBlock.vue @@ -27,7 +27,7 @@ :clearable="false" @option:selected="buildChart" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #selected-option="{name}"> @@ -68,7 +68,7 @@ v-model="item.color" @option:selected="buildChart" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -95,7 +95,7 @@ </button> </form> </courseware-tab> - </courseware-tabs> + </courseware-tabs> </template> <template #info> <p>{{ $gettext('Informationen zum Diagramm-Block') }}</p> diff --git a/resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue index 6bac6ff6e66b470f20b62ed03a6df282135b3a4c..b788a5217c5ae51d98ec81e817261f9d4e217b98 100644 --- a/resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareDefaultBlock.vue @@ -7,7 +7,7 @@ <span>{{ blockTitle }}</span> <studip-icon v-if="blockedByAnotherUser" shape="lock-locked" /> <span v-if="blockedByAnotherUser" class="cw-default-block-blocker-warning"> - {{ $gettextInterpolate($gettext('Wird im Moment von %{ userName } bearbeitet'), { userName: this.blockingUserName }) }} + {{ $gettext('Wird im Moment von %{ userName } bearbeitet', { userName: this.blockingUserName }) }} </span> <studip-icon v-if="!block.attributes.visible" shape="visibility-invisible" /> <span v-if="!block.attributes.visible" class="cw-default-block-invisible-info"> @@ -101,6 +101,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-default-block', mixins: [blockMixin], + emits: ['closeEdit', 'showEdit', 'storeEdit'], components: { CoursewareBlockActions, CoursewareBlockDiscussion, @@ -109,7 +110,7 @@ export default { CoursewareBlockInfo, StudipDialog, StudipIcon, - + }, props: { block: Object, @@ -275,9 +276,9 @@ export default { if (this.blockedByAnotherUser) { this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext('Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.', + { blockingUserName: this.blockingUserName } ) }); this.displayFeature(false); @@ -307,9 +308,9 @@ export default { this.showDeleteDialog = true; } else { this.companionInfo({ - info: this.$gettextInterpolate( - this.$gettext('Löschen nicht möglich, da %{blockingUserName} den Block bearbeitet.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Löschen nicht möglich, da %{blockingUserName} den Block bearbeitet.', + { blockingUserName: this.blockingUserName } ) }); } @@ -329,9 +330,9 @@ export default { await this.loadBlock({ id: this.block.id, options: { include: 'edit-blocker' } }); if (this.blockedByAnotherUser) { this.companionInfo({ - info: this.$gettextInterpolate( - this.$gettext('Löschen nicht möglich, da %{blockingUserName} die Bearbeitung übernommen hat.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Löschen nicht möglich, da %{blockingUserName} die Bearbeitung übernommen hat.', + { blockingUserName: this.blockingUserName } ) }); return false; @@ -419,4 +420,4 @@ export default { } } }; -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue b/resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue index ff01d78a2638252e0206f149c6ba250880f4c48c..0207acab4d0dc54caddb84df9664996bf2da1fa8 100644 --- a/resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareDownloadBlock.vue @@ -43,7 +43,7 @@ </template> <template v-if="canEdit" #edit> <courseware-tabs> - <courseware-tab :index="0" :name="$gettext('Datei')" :selected="true"> + <courseware-tab :name="$gettext('Datei')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Überschrift') }} @@ -55,7 +55,7 @@ </label> </form> </courseware-tab> - <courseware-tab :index="1" :name="$gettext('Infobox')"> + <courseware-tab :name="$gettext('Infobox')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Infobox vor Download') }} @@ -67,7 +67,7 @@ </label> </form> </courseware-tab> - <courseware-tab :index="2" :name="$gettext('Fortschritt')"> + <courseware-tab :name="$gettext('Fortschritt')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Fortschritt erst beim Herunterladen') }} diff --git a/resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue b/resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue index 9ace7bf4774857c575d5ea5f6abbb71e873739a9..de1f833830ed399acc51d23a2fd41af409478fe4 100644 --- a/resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareEmbedBlock.vue @@ -165,7 +165,7 @@ export default { this.recalculateContentHeight(data); }); }, - destroyed() { + unmounted() { window.removeEventListener('resize', this.calcContentHeight); }, methods: { @@ -185,7 +185,7 @@ export default { } }, recalculateContentHeight(data) { - if (this.$parent._uid === data.uid) { + if (this.$parent._.uid === data.uid) { if (this.oembedData) { this.calcContentHeight(); } diff --git a/resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue b/resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue index 9d64859f4830dfc4d79ee405cc831e4107fee788..239556c2fd2805f7893ce9d5997811352ed8f1b2 100644 --- a/resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareFolderBlock.vue @@ -104,7 +104,7 @@ }} </div> <fieldset class="select_terms_of_use"> - <template v-for="term in termsOfUse"> + <template v-for="term in termsOfUse" :key="term.id"> <input type="radio" name="content_terms_of_use_id" @@ -113,9 +113,8 @@ :id="'content_terms_of_use-' + term.id" :checked="selectedTerm === term.id" :aria-description="term.description" - :key="term.id + '_input'" /> - <label @click="selectedTerm = term.id" :key="term.id + 'label'"> + <label @click="selectedTerm = term.id"> <div class="icon"> <studip-icon :shape="term.attributes.icon" :size="32" /> </div> @@ -125,7 +124,7 @@ <studip-icon shape="arr_1down" :size="24" class="arrow" /> <studip-icon shape="check-circle" :size="24" class="check" /> </label> - <div class="terms_of_use_description" :key="term.id + '_description'"> + <div class="terms_of_use_description"> <div class="description"> {{ term.attributes.description }} </div> diff --git a/resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue b/resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue index 1d078329bf3a194e23a6f46b58eb9413ac467f4c..9a32689998b0813629e60daae75dbd531561460a 100644 --- a/resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareGalleryBlock.vue @@ -75,7 +75,7 @@ </template> <template v-if="canEdit" #edit> <courseware-tabs> - <courseware-tab :index="0" :name="$gettext('Einstellungen')" :selected="true"> + <courseware-tab :name="$gettext('Einstellungen')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Layout') }} @@ -104,7 +104,7 @@ </label> </form> </courseware-tab> - <courseware-tab :index="1" :name="$gettext('Beschreibung')"> + <courseware-tab :name="$gettext('Beschreibung')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Dateinamen anzeigen') }} @@ -136,7 +136,7 @@ </label> </form> </courseware-tab> - <courseware-tab v-if="currentLayout === 'carousel'" :index="2" :name="$gettext('Autoplay')"> + <courseware-tab v-if="currentLayout === 'carousel'" :name="$gettext('Autoplay')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Autoplay') }} diff --git a/resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue b/resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue index c9c2ce0ac7fa0f66b94040efaf471944d5b657ee..3d992f68ac775a8c26d49cf353e5afeedb8fdb03 100644 --- a/resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareHeadlineBlock.vue @@ -49,9 +49,7 @@ <template v-if="canEdit" #edit> <courseware-tabs> <courseware-tab - :index="0" :name="$gettext('Layout')" - :selected="true" > <form class="default" @submit.prevent=""> <label> @@ -77,7 +75,6 @@ </form> </courseware-tab> <courseware-tab - :index="1" :name="$gettext('Inhalt')" > <form class="default" @submit.prevent=""> @@ -102,7 +99,7 @@ :clearable="false" v-model="currentTextColor" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -125,7 +122,7 @@ :clearable="false" v-model="currentTextBackgroundColor" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -143,7 +140,7 @@ <label> {{ $gettext('Icon') }} <studip-select :clearable="false" :options="icons" v-model="currentIcon"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -166,7 +163,7 @@ :clearable="false" v-model="currentIconColor" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -184,7 +181,6 @@ </form> </courseware-tab> <courseware-tab - :index="2" :name="$gettext('Hintergrund')" > <form class="default" @submit.prevent=""> @@ -206,7 +202,7 @@ v-model="currentBackgroundColor" :clearable="false" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -634,4 +630,4 @@ export default { </script> <style scoped lang="scss"> @import "../../../../assets/stylesheets/scss/courseware/blocks/headline.scss"; -</style> \ No newline at end of file +</style> diff --git a/resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue b/resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue index 4ff7e45b8e02d8ef1b69cac0f8f37ce51266e3d7..49ea664e4b4a1fcdfbb8396f2035667fe92a974d 100644 --- a/resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareIframeBlock.vue @@ -31,7 +31,7 @@ </template> <template v-if="canEdit" #edit> <courseware-tabs> - <courseware-tab :index="0" :name="$gettext('Grunddaten')" :selected="true"> + <courseware-tab :name="$gettext('Grunddaten')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Titel') }} @@ -47,7 +47,7 @@ </label> </form> </courseware-tab> - <courseware-tab :index="1" :name="$gettext('Nutzerspezifische ID')"> + <courseware-tab :name="$gettext('Nutzerspezifische ID')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Nutzerspezifische ID übergeben') }} @@ -67,7 +67,7 @@ </label> </form> </courseware-tab> - <courseware-tab :index="2" :name="$gettext('Creative Commons')"> + <courseware-tab :name="$gettext('Creative Commons')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Creative Commons Lizenz') }} diff --git a/resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue b/resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue index 4f52d4b57d739f39e64dbc7586e5a26ffdd499b0..4fd312870a07020df4822df2b882c0b78e66dc50 100644 --- a/resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareImageMapBlock.vue @@ -111,7 +111,7 @@ v-model="shape.data.color" @input="drawScreen" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> @@ -139,7 +139,7 @@ v-model="shape.data.textcolor" @input="drawScreen" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> @@ -263,7 +263,7 @@ <script> import BlockComponents from './block-components.js'; import blockMixin from '@/vue/mixins/courseware/block.js'; -import VueResizeable from 'vrp-vue-resizable'; +import VueResizeable from 'vue-resizable'; import { mapActions, mapGetters } from 'vuex'; export default { diff --git a/resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue b/resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue index 0931182927a89bbec379dc7d0bbda72689954379..55bf2a9e71156f3e6c3ef3229562e87916c30a9d 100644 --- a/resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareKeyPointBlock.vue @@ -39,7 +39,7 @@ :reduce="(option) => option.icon" v-model="currentColor" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> <template #no-options> @@ -58,7 +58,7 @@ <label class="col-2"> {{ $gettext('Icon') }} <studip-select :options="icons" :clearable="false" v-model="currentIcon"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> <template #no-options> @@ -115,7 +115,7 @@ export default { }, colors() { let colors = this.mixinColors.filter( - (color) => (color.icon && color.class !== 'white' && color.class !== 'studip-lightblue') + (color) => (color.icon && color.class !== 'white' && color.class !== 'studip-lightblue') || color.class === 'royal-purple' || color.class === 'apple-green' || color.class === 'pumpkin' || color.class === 'verdigris' || color.class === 'mulberry' ); diff --git a/resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue b/resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue index 626a1a020313db5bc2072396f17a8760e0050c16..91965015964c4d459f1ec8cb6a787460c0efa477 100644 --- a/resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareLtiBlock.vue @@ -28,7 +28,7 @@ </template> <template v-if="canEdit" #edit> <courseware-tabs> - <courseware-tab :index="0" :name="$gettext('Grunddaten')" :selected="true"> + <courseware-tab :name="$gettext('Grunddaten')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Titel') }} @@ -110,7 +110,7 @@ </div> </form> </courseware-tab> - <courseware-tab :index="1" :name="$gettext('Zusätzliche Einstellungen')"> + <courseware-tab :name="$gettext('Zusätzliche Einstellungen')"> <form class="default" @submit.prevent=""> <label> {{ $gettext('Höhe') }} diff --git a/resources/vue/components/courseware/blocks/CoursewarePDFTableOfContent.vue b/resources/vue/components/courseware/blocks/CoursewarePDFTableOfContent.vue index 989e2edabfa90e3a17c53e24681c8c8033ba399a..2a258a2394c75bbd201c1359af92f3805f80842d 100644 --- a/resources/vue/components/courseware/blocks/CoursewarePDFTableOfContent.vue +++ b/resources/vue/components/courseware/blocks/CoursewarePDFTableOfContent.vue @@ -15,6 +15,7 @@ <script> export default { name: 'courseware-pdf-toc-item', + emits: ['tocPageNav'], props: { item: { type: Object, diff --git a/resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue b/resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue index 2f09edeadb2fc0c8acfef0c787bcf9bfc21e5029..4330f13acd489bdb978e7ddacb2ff95273c35bcd 100644 --- a/resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareTableOfContentsBlock.vue @@ -37,15 +37,12 @@ {{ child.attributes.payload.description }} </template> <template #footer> - {{ - $gettextInterpolate( - $ngettext( - '%{length} Seite', - '%{length} Seiten', - countChildChildren(child) - ), - { length: countChildChildren(child) }) - }} + {{ $ngettext( + '%{length} Seite', + '%{length} Seiten', + countChildChildren(child), + { length: countChildChildren(child) } + ) }} </template> </courseware-tile> </router-link> diff --git a/resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue b/resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue index 4e93e70afbe8956552f9f33d876e3d2ff8407dda..1f305f8f0668ce1994ca574b87708058ffb15b6c 100644 --- a/resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareTimelineBlock.vue @@ -74,7 +74,7 @@ <input type="text" v-model="item.title" /> </label> <label class="col-4"> - + {{ $gettext('Beschreibung') }} <textarea v-model="item.description" /> </label> @@ -88,7 +88,7 @@ :reduce="option => option.class" v-model="item.color" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span> </template> <template #no-options> @@ -105,7 +105,7 @@ <label class="col-2"> {{ $gettext('Icon') }} <studip-select :options="icons" :clearable="false" v-model="item.icon"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" size="10"/></span> </template> <template #no-options> @@ -304,4 +304,4 @@ export default { </script> <style scoped lang="scss"> @import '../../../../assets/stylesheets/scss/courseware/blocks/timeline.scss'; -</style> \ No newline at end of file +</style> diff --git a/resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue b/resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue index 7febfbc0a6160c3321c73c0eb79b76aee2496846..147c07f00d45642624cd5cefdbf053e990902ca9 100644 --- a/resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue +++ b/resources/vue/components/courseware/blocks/CoursewareVideoBlock.vue @@ -23,9 +23,7 @@ <template v-if="canEdit" #edit> <courseware-tabs> <courseware-tab - :index="0" :name="$gettext('Grunddaten')" - :selected="true" > <form class="default" @submit.prevent=""> <label> @@ -58,7 +56,6 @@ </form> </courseware-tab> <courseware-tab - :index="1" :name="$gettext('Video Einstellungen')" > <form class="default" @submit.prevent=""> diff --git a/resources/vue/components/courseware/blocks/ImageCompare.vue b/resources/vue/components/courseware/blocks/ImageCompare.vue new file mode 100644 index 0000000000000000000000000000000000000000..40ad6e40f0be0f81c7a6c9a4a4264772ced2b3a2 --- /dev/null +++ b/resources/vue/components/courseware/blocks/ImageCompare.vue @@ -0,0 +1,156 @@ +<template> + <div class="image-comparator" :style="{ height: imageHeight + 'px' }" ref="comparator"> + <div class="images"> + <!-- Erstes Bild, linke Seite --> + <img + :src="image1" + class="image" + :style="{ clipPath: 'inset(0 ' + (100 - sliderValue) + '% 0 0)' }" + @load="setImageHeight" + /> + + <!-- Zweites Bild, rechte Seite --> + <img :src="image2" class="image" :style="{ clipPath: 'inset(0 0 0 ' + sliderValue + '%)' }" /> + </div> + + <!-- Slider zur Steuerung des Vergleichs --> + <div class="slider-container" @mousedown="startDragging" @touchstart="startDragging"> + <div class="thumb" :class="{ dragging: isDragging}" :style="{ left: `${sliderValue}%`, height: imageHeight + 'px' }"> + <StudipIcon class="arrow-left" shape="arr_1left" :size="32" role="info_alt" draggable="false" /> + <StudipIcon class="arrow-right" shape="arr_1right" :size="32" role="info_alt" draggable="false" /> + </div> + </div> + </div> +</template> + +<script> +export default { + name: 'ImageComparator', + data() { + return { + sliderValue: 50, // Anfangswert für den Slider (zeigt 50% von beiden Bildern) + imageHeight: 0, // Höhe der Komponente + isDragging: false, // Dragging-Zustand + }; + }, + props: { + image1: { + type: String, + required: true, + }, + image2: { + type: String, + required: true, + }, + }, + computed: {}, + methods: { + setImageHeight(event) { + const img = event.target; + const ratio = img.naturalHeight / img.naturalWidth; + this.imageHeight = this.$refs.comparator.clientWidth * ratio; + }, + startDragging(event) { + this.isDragging = true; + this.updateSliderValue(event); + window.addEventListener('mousemove', this.updateSliderValue); + window.addEventListener('touchmove', this.updateSliderValue); + window.addEventListener('mouseup', this.stopDragging); + window.addEventListener('touchend', this.stopDragging); + }, + stopDragging() { + this.isDragging = false; + window.removeEventListener('mousemove', this.updateSliderValue); + window.removeEventListener('touchmove', this.updateSliderValue); + window.removeEventListener('mouseup', this.stopDragging); + window.removeEventListener('touchend', this.stopDragging); + }, + updateSliderValue(event) { + if (!this.isDragging) return; + + const rect = this.$el.getBoundingClientRect(); + const x = event.clientX - rect.left; // Position innerhalb des Containers + const width = rect.width; + const newValue = Math.min(Math.max((x / width) * 100, 0), 100); // Wert zwischen 0 und 100 + this.sliderValue = newValue; // Sliderwert aktualisieren + }, + }, +}; +</script> + +<style lang="scss"> +.image-comparator { + position: relative; + width: 100%; + margin: 0 auto; + overflow: hidden; + + img { + -webkit-touch-callout: none; /* iOS Safari */ + -webkit-user-select: none; /* Safari */ + -khtml-user-select: none; /* Konqueror HTML */ + -moz-user-select: none; /* Old versions of Firefox */ + -ms-user-select: none; /* Internet Explorer/Edge */ + user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ + } + + .images { + position: relative; + display: flex; + width: 100%; + height: 100%; + overflow: hidden; + + .image { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: auto; + object-fit: cover; + } + } +} + +.slider-container { + position: absolute; + top: 0; + left: 0; + right: 0; + transform: translateY(-50%); + display: flex; + align-items: center; + + .thumb { + position: absolute; + top: 0; + width: 4px; + background: rgba(0, 0, 0, 0.2); + cursor: grab; + + &.dragging { + cursor: grabbing; + } + + .arrow-left, + .arrow-right { + position: absolute; + top: 50%; + background-color: rgba(0, 0, 0, 0.2); + padding: 8px 0px; + } + + .arrow-left { + left: -32px; + border-top-left-radius: 8px; + border-bottom-left-radius: 8px; + } + + .arrow-right { + right: -32px; + border-top-right-radius: 8px; + border-bottom-right-radius: 8px; + } + } +} +</style> diff --git a/resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue b/resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue index b43c811b6d0441de6b8f4dfac447f839ce2afc78..7f7c86d1e7504304fefa72e9cc7b2f047957cd03 100644 --- a/resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue +++ b/resources/vue/components/courseware/containers/CoursewareAccordionContainer.vue @@ -41,39 +41,42 @@ :msgCompanion="$gettext('Dieses Fach enthält keine Blöcke.')"> </courseware-companion-box> <draggable + v-bind="dragOptions" v-if="canEdit" class="cw-container-accordion-block-list cw-container-accordion-sort-mode" :class="[section.blocks.length === 0 ? 'cw-container-accordion-sort-mode-empty' : '']" tag="ol" role="listbox" v-model="section.blocks" - v-bind="dragOptions" handle=".cw-sortable-handle" group="blocks" @start="isDragging = true" @end="dropBlock" :containerId="container.id" :sectionId="index" + item-key="id" > - <li v-for="block in section.blocks" :key="block.id" class="cw-block-item cw-block-item-sortable"> - <span - :class="{ 'cw-sortable-handle-dragging': isDragging }" - class="cw-sortable-handle" - tabindex="0" - role="button" - aria-describedby="operation" - :ref="'sortableHandle' + block.id" - @keydown="keyHandler($event, block.id, index)" - ></span> - <component - :is="component(block)" - :block="block" - :canEdit="canEdit" - :isTeacher="isTeacher" - :class="{ 'cw-block-item-selected': keyboardSelected === block.id}" - :blockId="block.id" - /> - </li> + <template #item="{element, index}"> + <li class="cw-block-item cw-block-item-sortable"> + <span + :class="{ 'cw-sortable-handle-dragging': isDragging }" + class="cw-sortable-handle" + tabindex="0" + role="button" + aria-describedby="operation" + :ref="'sortableHandle' + element.id" + @keydown="keyHandler($event, element.id, index)" + ></span> + <component + :is="component(element)" + :block="element" + :canEdit="canEdit" + :isTeacher="isTeacher" + :class="{ 'cw-block-item-selected': keyboardSelected === element.id}" + :blockId="element.id" + /> + </li> + </template> </draggable> </template> <div v-else class="progress-wrapper"> @@ -104,7 +107,7 @@ <label> {{ $gettext('Symbol')}} <studip-select :options="icons" v-model="section.icon"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -147,6 +150,7 @@ export default { components: Object.assign(ContainerComponents, { CoursewareCollapsibleBox, }), + emits: ['blockAdded'], props: { container: Object, canEdit: Boolean, @@ -324,11 +328,14 @@ export default { this.keyboardSelected = blockId; const block = this.blockById({id: blockId}); const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.') - , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.', + { + blockTitle: block.attributes.title, + pos: currentIndex + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); } break; } @@ -354,11 +361,14 @@ export default { if (currentIndex !== 0) { const newPos = currentIndex - 1; this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: newPos + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); } else if (sectionIndex !== 0) { const newSectionIndex = sectionIndex - 1; if (!this.sortInSlots.includes(newSectionIndex)) { @@ -373,11 +383,14 @@ export default { if (this.currentSections[sectionIndex].blocks.length - 1 > currentIndex) { const newPos = currentIndex + 1; this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: newPos + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); } else if (this.currentSections.length - 1 > sectionIndex) { const newSectionIndex = sectionIndex + 1; if (!this.sortInSlots.includes(newSectionIndex)) { @@ -389,22 +402,24 @@ export default { abortKeyboardSorting(blockId, sectionIndex) { const block = this.blockById({id: blockId}); this.keyboardSelected = null; - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block, Neuordnung abgebrochen.') - , {blockTitle: block.attributes.title} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block, Neuordnung abgebrochen.', + { blockTitle: block.attributes.title } + ); this.initCurrentData(); }, storeKeyboardSorting(blockId, sectionIndex) { const block = this.blockById({id: blockId}); const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId); this.keyboardSelected = null; - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: currentIndex + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); this.storeSort(); } }, @@ -418,7 +433,7 @@ export default { }, currentSections: { handler(newSections, oldSections) { - if (oldSections.length > 0 && + if (oldSections.length > 0 && newSections[oldSections.length -1].blocks.length > oldSections[oldSections.length - 1].blocks.length) { this.$emit('blockAdded'); this.$nextTick(() => { @@ -436,7 +451,7 @@ export default { currentContainer: { handler() { this.editDataValid = true; - this.currentContainer.attributes.payload.sections.forEach(section => { + this.currentContainer.attributes.payload.sections?.forEach(section => { if (!section.icon && !section.name) { this.editDataValid = false; } diff --git a/resources/vue/components/courseware/containers/CoursewareContainerActions.vue b/resources/vue/components/courseware/containers/CoursewareContainerActions.vue index 875ab1fce91b80be360e4f97b660bd2ebd0b51b0..ce7c5457709c4f8d146ccda6a5276cc4986ee73b 100644 --- a/resources/vue/components/courseware/containers/CoursewareContainerActions.vue +++ b/resources/vue/components/courseware/containers/CoursewareContainerActions.vue @@ -21,6 +21,13 @@ export default { canEdit: Boolean, container: Object, }, + emits: [ + 'changeContainer', + 'copyToClipboard', + 'deleteContainer', + 'editContainer', + 'removeLock', + ], computed: { ...mapGetters({ userId: 'userId', diff --git a/resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue b/resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue index 7f4a882e84feb29ef6ad30ae739c4a91ad744f0a..b2eb62487261a88ba84eaa169e85404fed2e69d4 100644 --- a/resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue +++ b/resources/vue/components/courseware/containers/CoursewareDefaultContainer.vue @@ -11,7 +11,7 @@ <span>{{ container.attributes.title }} ({{container.attributes.width}})</span> <studip-icon v-if="blockedByAnotherUser" shape="lock-locked" /> <span v-if="blockedByAnotherUser" class="cw-default-container-blocker-warning"> - {{ $gettextInterpolate($gettext('Wird im Moment von %{ userName } bearbeitet'), { userName: this.blockingUserName }) }} + {{ $gettext('Wird im Moment von %{ userName } bearbeitet', { userName: this.blockingUserName }) }} </span> </a> <courseware-container-actions @@ -144,6 +144,7 @@ export default { CoursewareContainerActions, StudipDialog, }, + emits: ['closeEdit', 'showEdit', 'storeContainer'], props: { containerClass: String, container: Object, @@ -263,9 +264,9 @@ export default { this.closeChange(); if (this.blockedByAnotherUser) { this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext('Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.', + { blockingUserName: this.blockingUserName } ) }); return; @@ -308,9 +309,9 @@ export default { } if (this.blockedByAnotherUser) { this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext('Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.', + { blockingUserName: this.blockingUserName } ) }); this.$emit('closeEdit'); @@ -331,9 +332,9 @@ export default { this.showDeleteDialog = true; } else { this.companionInfo({ - info: this.$gettextInterpolate( - this.$gettext('Löschen nicht möglich, da %{blockingUserName} den Abschnitt bearbeitet.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Löschen nicht möglich, da %{blockingUserName} den Abschnitt bearbeitet.', + { blockingUserName: this.blockingUserName } ) }); } @@ -350,9 +351,9 @@ export default { await this.loadContainer({ id: this.container.id, options: { include: 'edit-blocker' } }); if (this.blockedByAnotherUser) { this.companionInfo({ - info: this.$gettextInterpolate( - this.$gettext('Löschen nicht möglich, da %{blockingUserName} die Bearbeitung übernommen hat.'), - {blockingUserName: this.blockingUserName} + info: this.$gettext( + 'Löschen nicht möglich, da %{blockingUserName} die Bearbeitung übernommen hat.', + { blockingUserName: this.blockingUserName } ) }); return false; diff --git a/resources/vue/components/courseware/containers/CoursewareListContainer.vue b/resources/vue/components/courseware/containers/CoursewareListContainer.vue index 327b20eb9c6d8482a7eef8daf5c401fa63b44a5e..730a32939d6f4b1bea806313b93d2dff597d071a 100644 --- a/resources/vue/components/courseware/containers/CoursewareListContainer.vue +++ b/resources/vue/components/courseware/containers/CoursewareListContainer.vue @@ -25,11 +25,11 @@ </courseware-companion-box> <draggable v-if="canEdit" + v-bind="dragOptions" class="cw-container-list-block-list cw-container-list-sort-mode" tag="ol" role="listbox" v-model="blockList" - v-bind="dragOptions" handle=".cw-sortable-handle" group="blocks" @start="isDragging = true" @@ -37,30 +37,31 @@ ref="sortables" :containerId="container.id" sectionId="0" + item-key="id" > - <li - v-for="block in blockList" - :key="block.id" - class="cw-block-item cw-block-item-sortable" - > - <span - :class="{ 'cw-sortable-handle-dragging': isDragging }" - class="cw-sortable-handle" - tabindex="0" - role="button" - aria-describedby="operation" - :ref="'sortableHandle' + block.id" - @keydown="keyHandler($event, block.id)" - ></span> - <component - :is="component(block)" - :block="block" - :canEdit="canEdit" - :isTeacher="isTeacher" - :class="{ 'cw-block-item-selected': keyboardSelected === block.id}" - :blockId="block.id" - /> - </li> + <template #item="{element}"> + <li + class="cw-block-item cw-block-item-sortable" + > + <span + :class="{ 'cw-sortable-handle-dragging': isDragging }" + class="cw-sortable-handle" + tabindex="0" + role="button" + aria-describedby="operation" + :ref="'sortableHandle' + element.id" + @keydown="keyHandler($event, element.id)" + ></span> + <component + :is="component(element)" + :block="element" + :canEdit="canEdit" + :isTeacher="isTeacher" + :class="{ 'cw-block-item-selected': keyboardSelected === element.id}" + :blockId="element.id" + /> + </li> + </template> </draggable> </template> <div v-else class="progress-wrapper" :style="{ height: contentHeight + 'px' }"> @@ -197,11 +198,14 @@ export default { this.keyboardSelected = blockId; const block = this.blockById({id: blockId}); const index = this.blockList.findIndex(b => b.id === block.id); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.') - , {blockTitle: block.attributes.title, pos: index + 1, listLength: this.blockList.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.', + { + blockTitle: block.attributes.title, + pos: index + 1, + listLength: this.blockList.length + } + ); } break; } @@ -227,11 +231,14 @@ export default { const block = this.blockById({id: blockId}); const newPos = currentIndex - 1; this.blockList.splice(newPos, 0, this.blockList.splice(currentIndex, 1)[0]); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.blockList.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: newPos + 1, + listLength: this.blockList.length + } + ); } }, moveItemDown(blockId) { @@ -240,32 +247,37 @@ export default { const block = this.blockById({id: blockId}); const newPos = currentIndex + 1; this.blockList.splice(newPos, 0, this.blockList.splice(currentIndex, 1)[0]); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.blockList.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: newPos + 1, + listLength: this.blockList.length + } + ); } }, abortKeyboardSorting(blockId) { const block = this.blockById({id: blockId}); this.keyboardSelected = null; - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block, Neuordnung abgebrochen.') - , {blockTitle: block.attributes.title} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block, Neuordnung abgebrochen.', + { blockTitle: block.attributes.title } + ); this.initCurrentData(); }, storeKeyboardSorting(blockId) { const block = this.blockById({id: blockId}); const currentIndex = this.blockList.findIndex(block => block.id === blockId); this.keyboardSelected = null; - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.blockList.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: currentIndex + 1, + listLength: this.blockList.length + } + ); this.storeSort(); } }, @@ -273,17 +285,23 @@ export default { this.initCurrentData(); }, watch: { - blocks() { - this.initCurrentData(); + blocks: { + handler() { + this.initCurrentData(); + }, + deep: true }, - blockList() { - if (this.keyboardSelected) { - this.$nextTick(() => { - const selected = this.$refs['sortableHandle' + this.keyboardSelected][0]; - selected.focus(); - selected.scrollIntoView({behavior: "smooth", block: "center"}); - }); - } + blockList: { + handler() { + if (this.keyboardSelected) { + this.$nextTick(() => { + const selected = this.$refs['sortableHandle' + this.keyboardSelected][0]; + selected.focus(); + selected.scrollIntoView({behavior: "smooth", block: "center"}); + }); + } + }, + deep: true } } }; diff --git a/resources/vue/components/courseware/containers/CoursewareTabsContainer.vue b/resources/vue/components/courseware/containers/CoursewareTabsContainer.vue index e9c45ca4fe6c36ee40e696fcab3ce8a004e0727f..490ad3cc992bb006cff676c9430f203d070a7bc1 100644 --- a/resources/vue/components/courseware/containers/CoursewareTabsContainer.vue +++ b/resources/vue/components/courseware/containers/CoursewareTabsContainer.vue @@ -24,14 +24,12 @@ {{ $gettext('Drücken Sie die Leertaste, um neu anzuordnen.') }} </span> </template> - <courseware-tabs @selectTab="selectTabHandler"> + <courseware-tabs v-if="!processing" v-model="selectedTab"> <courseware-tab - v-for="(section, index) in currentSections" - :key="index" - :index="index" + v-for="(section, sectionIndex) in currentSections" + :key="sectionIndex" :name="section.name" :icon="section.icon" - :selected="sortInTab === index" > <ul v-if="!canEdit || currentElementisLink" class="cw-container-tabs-block-list"> <li v-for="block in section.blocks" :key="block.id" class="cw-block-item"> @@ -51,38 +49,41 @@ :msgCompanion="$gettext('Dieses Fach enthält keine Blöcke.')"> </courseware-companion-box> <draggable + v-bind="dragOptions" class="cw-container-tabs-block-list cw-container-tabs-sort-mode" :class="[section.blocks.length === 0 ? 'cw-container-tabs-sort-mode-empty' : '']" tag="ol" role="listbox" v-model="section.blocks" - v-bind="dragOptions" handle=".cw-sortable-handle" group="blocks" @start="isDragging = true" @end="dropBlock" :containerId="container.id" - :sectionId="index" + :sectionId="sectionIndex" + item-key="id" > - <li v-for="block in section.blocks" :key="block.id" class="cw-block-item cw-block-item-sortable"> - <span - :class="{ 'cw-sortable-handle-dragging': isDragging }" - class="cw-sortable-handle" - tabindex="0" - role="button" - aria-describedby="operation" - :ref="'sortableHandle' + block.id" - @keydown="keyHandler($event, block.id, index)" - ></span> - <component - :is="component(block)" - :block="block" - :canEdit="canEdit" - :isTeacher="isTeacher" - :class="{ 'cw-block-item-selected': keyboardSelected === block.id}" - :blockId="block.id" - /> - </li> + <template #item="{element}"> + <li class="cw-block-item cw-block-item-sortable"> + <span + :class="{ 'cw-sortable-handle-dragging': isDragging }" + class="cw-sortable-handle" + tabindex="0" + role="button" + aria-describedby="operation" + :ref="'sortableHandle' + element.id" + @keydown="keyHandler($event, element.id, sectionIndex)" + ></span> + <component + :is="component(element)" + :block="element" + :canEdit="canEdit" + :isTeacher="isTeacher" + :class="{ 'cw-block-item-selected': keyboardSelected === element.id}" + :blockId="element.id" + /> + </li> + </template> </draggable> </template> </template> @@ -103,7 +104,7 @@ <label> {{ $gettext('Symbol') }} <studip-select :options="icons" v-model="section.icon"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10"/></span> </template> <template #no-options> @@ -138,6 +139,7 @@ import CoursewareTabs from '../layouts/CoursewareTabs.vue'; import CoursewareTab from '../layouts/CoursewareTab.vue'; import containerMixin from '@/vue/mixins/courseware/container.js'; import contentIconsMixin from '@/vue/mixins/courseware/content-icons.js'; +import draggable from "vuedraggable"; import { mapGetters, mapActions } from 'vuex'; @@ -147,6 +149,7 @@ export default { components: Object.assign(ContainerComponents, { CoursewareTabs, CoursewareTab, + draggable }), props: { container: Object, @@ -172,7 +175,7 @@ export default { }, processing: false, keyboardSelected: null, - sortInTab: 0, + selectedTab: 0, assistiveLive: '', showDeleteDialog: false, currentSection: null, @@ -209,7 +212,6 @@ export default { }), initCurrentData() { this.currentContainer = _.cloneDeep(this.container); - let view = this; let sections = this.currentContainer.attributes.payload.sections; @@ -276,7 +278,8 @@ export default { this.closeDeleteDialog(); }, async storeContainer() { - const timeout = setTimeout(() => this.processing = true, 800); + this.processing = true; + await this.$nextTick(); this.currentContainer.attributes.payload.sections = this.currentContainer.attributes.payload.sections.filter(section => !section.locked); this.currentContainer.attributes.payload.sections.forEach(section => { section.blocks = section.blocks.map((block) => {return block.id;}); @@ -289,7 +292,6 @@ export default { await this.unlockObject({ id: this.container.id, type: 'courseware-containers' }); await this.loadContainer({id : this.container.id }); this.initCurrentData(); - clearTimeout(timeout); this.processing = false; }, async storeSort() { @@ -325,11 +327,14 @@ export default { this.keyboardSelected = blockId; const block = this.blockById({id: blockId}); const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.') - , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.', + { + blockTitle: block.attributes.title, + pos: currentIndex + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); } break; } @@ -355,14 +360,17 @@ export default { if (currentIndex !== 0) { const newPos = currentIndex - 1; this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: newPos + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); } else if (sectionIndex !== 0) { const newSectionIndex = sectionIndex - 1; - this.sortInTab = newSectionIndex; + this.selectedTab = newSectionIndex; this.currentSections[newSectionIndex].blocks.push(this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]); } }, @@ -372,47 +380,51 @@ export default { if (this.currentSections[sectionIndex].blocks.length - 1 > currentIndex) { const newPos = currentIndex + 1; this.currentSections[sectionIndex].blocks.splice(newPos, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]); - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: newPos + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: newPos + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); } else if (this.currentSections.length - 1 > sectionIndex) { const newSectionIndex = sectionIndex + 1; - this.sortInTab = newSectionIndex; + this.selectedTab = newSectionIndex; this.currentSections[newSectionIndex].blocks.splice(0, 0, this.currentSections[sectionIndex].blocks.splice(currentIndex, 1)[0]); } }, abortKeyboardSorting(blockId, sectionIndex) { const block = this.blockById({id: blockId}); this.keyboardSelected = null; - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block, Neuordnung abgebrochen.') - , {blockTitle: block.attributes.title} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block, Neuordnung abgebrochen.', + { blockTitle: block.attributes.title } + ); this.initCurrentData(); }, storeKeyboardSorting(blockId, sectionIndex) { const block = this.blockById({id: blockId}); const currentIndex = this.currentSections[sectionIndex].blocks.findIndex(block => block.id === blockId); this.keyboardSelected = null; - this.assistiveLive = - this.$gettextInterpolate( - this.$gettext('%{blockTitle} Block, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.') - , {blockTitle: block.attributes.title, pos: currentIndex + 1, listLength: this.currentSections[sectionIndex].blocks.length} - ); + this.assistiveLive = this.$gettext( + '%{blockTitle} Block, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.', + { + blockTitle: block.attributes.title, + pos: currentIndex + 1, + listLength: this.currentSections[sectionIndex].blocks.length + } + ); this.storeSort(); }, - selectTabHandler(event) { - const tabIndex = event.index; + selectTabHandler() { let container = _.cloneDeep(this.container); - container.activeSection = tabIndex; + container.activeSection = this.selectedTab; this.storeContainerRecord(container); if (this.blockAdder.container.id === this.container.id) { this.setAdderStorage({ container: this.container, - section: tabIndex + section: this.selectedTab }); } } @@ -445,6 +457,9 @@ export default { }); }, deep: true + }, + selectedTab() { + this.selectTabHandler(); } } }; diff --git a/resources/vue/components/courseware/layouts/CoursewareCallToActionBox.vue b/resources/vue/components/courseware/layouts/CoursewareCallToActionBox.vue index 601a339e1a569eb33bd8bcab955e1295ea193adb..ffe3953fad5b0c7b761898d48777b10a10a80a9e 100644 --- a/resources/vue/components/courseware/layouts/CoursewareCallToActionBox.vue +++ b/resources/vue/components/courseware/layouts/CoursewareCallToActionBox.vue @@ -19,6 +19,7 @@ export default { components: { StudipIcon }, + emits: ['click'], props: { iconShape: { type: String, @@ -67,4 +68,4 @@ export default { } } } -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue b/resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue index e79df40ffeaec2bbc19aa0900dca8da3d72e6ccf..7e41a92f16dcc4f3a16e5cf011e40934ecc9891f 100644 --- a/resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue +++ b/resources/vue/components/courseware/layouts/CoursewareCollapsibleBox.vue @@ -45,7 +45,7 @@ export default { methods: { updateCollapsible() { if (this.isOpen) { - STUDIP.eventBus.emit('courseware:update-collapsible', { 'uid': this._uid }); + STUDIP.eventBus.emit('courseware:update-collapsible', { 'uid': this._.uid }); } } }, diff --git a/resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue b/resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue index bfd0a93374357b2fa3ba59317175e2c3545319e4..0f214f0179b469ea56f7b5bd1ce337a9a9539ba6 100644 --- a/resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue +++ b/resources/vue/components/courseware/layouts/CoursewareCompanionOverlay.vue @@ -3,7 +3,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-companion-overlay', - render(createElement) { + render() { return null; }, computed: { diff --git a/resources/vue/components/courseware/layouts/CoursewareDateInput.vue b/resources/vue/components/courseware/layouts/CoursewareDateInput.vue index 57a5619fbee207cf40021b276591a274d0a80bc4..602431d6295d117d9eefdc6671e850dc922a7702 100644 --- a/resources/vue/components/courseware/layouts/CoursewareDateInput.vue +++ b/resources/vue/components/courseware/layouts/CoursewareDateInput.vue @@ -8,7 +8,8 @@ const toISO8601 = (date) => date.toISOString(); const pad = (what, length = 2) => `00000000${what}`.substr(-length); export default { - props: ['value'], + emits: ['update:model-value'], + props: ['model-value'], data: () => ({ date: new Date(), }), @@ -20,14 +21,14 @@ export default { methods: { onInput({ target }) { const newValue = toISO8601(target.valueAsDate); - if (newValue !== this.value) { - this.$emit('input', newValue); + if (newValue !== this.modelValue) { + this.$emit('update:model-value', newValue); } }, }, - beforeMount() { - if (this.value) { - this.date = fromISO8601(this.value); + created() { + if (this.model-value) { + this.date = fromISO8601(this.modelValue); } }, }; diff --git a/resources/vue/components/courseware/layouts/CoursewareFileChooser.vue b/resources/vue/components/courseware/layouts/CoursewareFileChooser.vue index 6571b3430e0de5618673c3661ea3f78dc52c4cb2..a9b2aa3dc858f7ce58e76c4cd4264c09af914e95 100644 --- a/resources/vue/components/courseware/layouts/CoursewareFileChooser.vue +++ b/resources/vue/components/courseware/layouts/CoursewareFileChooser.vue @@ -1,17 +1,17 @@ <template> <div class="cw-file-chooser"> - <span v-translate>Ordner-Filter</span> + <span>{{ $gettext('Ordner-Filter') }}</span> <courseware-folder-chooser allowUserFolders unchoose v-model="selectedFolderId" /> - <span v-translate>Datei</span> + <span>{{ $gettext('Datei') }}</span> <select v-model="currentValue" @change="selectFile"> <option v-show="canBeEmpty" value=""> - <translate>Keine Auswahl</translate> + {{ $gettext('Keine Auswahl') }} </option> <option v-for="(file, index) in files" :key="index" :value="file.id"> {{ file.name }} </option> <option v-show="files.length === 0" disabled> - <translate>Keine Dateien vorhanden</translate> + {{ $gettext('Keine Dateien vorhanden') }} </option> </select> </div> @@ -25,6 +25,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-file-chooser', components: { CoursewareFolderChooser }, + emits: ['selectFile'], props: { value: String, mimeType: { type: String, default: '' }, diff --git a/resources/vue/components/courseware/layouts/CoursewareFolderChooser.vue b/resources/vue/components/courseware/layouts/CoursewareFolderChooser.vue index e0716795d10626ecc834a8b95219b77c9812bb05..2c0a270468ad1da24d174687b6397aa1c610f81f 100644 --- a/resources/vue/components/courseware/layouts/CoursewareFolderChooser.vue +++ b/resources/vue/components/courseware/layouts/CoursewareFolderChooser.vue @@ -1,6 +1,6 @@ <template> <select v-model="currentValue" @change="changeSelection"> - <option v-if="unchoose" value=""><translate>kein Ordner ausgewählt</translate></option> + <option v-if="unchoose" value="">{{ $gettext('kein Ordner ausgewählt') }}</option> <optgroup v-if="this.context.type === 'courses'" :label="textOptGroupCourse"> <option v-for="folder in loadedCourseFolders" :key="folder.id" :value="folder.id"> {{ folder.attributes.name }} @@ -69,8 +69,9 @@ function filterCourseFolders(folders, { allowHomeworkFolders }) { } export default { name: 'courseware-folder-chooser', + emits: ['update:model-value'], props: { - value: String, + modelValue: String, allowUserFolders: { type: Boolean, default: false }, allowHomeworkFolders: { type: Boolean, default: false }, unchoose: { type: Boolean, default: false }, @@ -120,7 +121,7 @@ export default { }), changeSelection() { - this.$emit('input', this.currentValue); + this.$emit('update:model-value', this.currentValue); }, getCourseFolders() { @@ -151,7 +152,7 @@ export default { } }, async mounted() { - this.currentValue = this.value; + this.currentValue = this.modelValue; if (this.context.type !== 'users') { await this.getCourseFolders(); } @@ -159,8 +160,8 @@ export default { this.confirmSelectedFolder(); }, watch: { - value() { - this.currentValue = this.value; + modelValue() { + this.currentValue = this.modelValue; } }, }; diff --git a/resources/vue/components/courseware/layouts/CoursewareTab.vue b/resources/vue/components/courseware/layouts/CoursewareTab.vue index ae007074872456d532c2f0443b825135a7bbf425..5e1f20b9bff363c56c586ebdd24d452ee101ac6d 100644 --- a/resources/vue/components/courseware/layouts/CoursewareTab.vue +++ b/resources/vue/components/courseware/layouts/CoursewareTab.vue @@ -1,51 +1,35 @@ <template> - <div - v-if="isActive" - role="tabpanel" - class="cw-tab" - :id="id" - :aria-labelledby="selectorId" - > + <div v-if="isActive"> <slot></slot> </div> </template> <script> export default { - name: 'courseware-tab', + inject: ['addTab', 'activeTab'], props: { - name: {type: String, required: true }, - alias: {type: String, default: ''}, - selected: { type: Boolean, default: false }, - index: {type: Number, required: true }, - icon: {type: String, default: ''}, + name: { + type: String, + required: true, + }, + icon: { + type: String, + default: '', + }, }, data() { return { - isActive: false, + index: null, }; }, computed: { - selectorId() { - return '#' + this._uid + '-' + this.name.toLowerCase().replace(/ /g, '-'); + isActive() { + return this.activeTab() === this.index; }, - id() { - return this._uid + '-' + this.name.toLowerCase().replace(/ /g, '-') + '-tabpanel'; - } }, mounted() { - this.isActive = this.selected; - }, - updated () { - if (this.isActive) { - STUDIP.eventBus.emit('courseware:update-tab',{ 'uid': this._uid }); - } - + this.index = this.$parent.tabs.length; + this.addTab({ name: this.name, icon: this.icon}); }, - watch: { - selected(newValue) { - this.isActive = newValue; - } - } }; -</script> +</script> \ No newline at end of file diff --git a/resources/vue/components/courseware/layouts/CoursewareTabs.vue b/resources/vue/components/courseware/layouts/CoursewareTabs.vue index 5bdcc47cfb9580f7aed6077369d0692587fc245b..c29d88e64f1dbcc8fb0eee6ce46d41fa5cbba5b7 100644 --- a/resources/vue/components/courseware/layouts/CoursewareTabs.vue +++ b/resources/vue/components/courseware/layouts/CoursewareTabs.vue @@ -1,26 +1,25 @@ <template> - <div class="cw-tabs"> - <div role="tablist" class="cw-tabs-nav"> + <div class="tabs cw-tabs"> + <div class="tab-buttons cw-tabs-nav"> <button v-for="(tab, index) in tabs" :key="index" + :data-index="index" :class="[ - tab.isActive ? 'is-active' : '', + activeTab === index ? 'is-active' : '', tab.icon !== '' && tab.name !== '' ? 'cw-tabs-nav-icon-text-' + tab.icon : '', tab.icon !== '' && tab.name === '' ? 'cw-tabs-nav-icon-solo-' + tab.icon : '', ]" - :aria-selected="tab.isActive" - :aria-controls="tab.id" - :id="tab.selectorId" - :tabindex="tab.isActive ? 0 : -1" - @click="selectTab(tab.selectorId)" + :tabindex="activeTab === index ? 0 : -1" + :aria-selected="activeTab === index" + @click="selectTab(index)" @keydown="handleKeyEvent($event)" - :ref="tab.selectorId" + :ref="'tabnav' + index" > {{ tab.name }} </button> </div> - <div class="cw-tabs-content"> + <div class="tab-content cw-tabs-content"> <slot></slot> </div> </div> @@ -28,106 +27,78 @@ <script> export default { - name: 'courseware-tabs', + name: 'CoursewareTabs', + emits: ['update:modelValue'], props: { - setSelected: { type: Number, required: false, default: 0 }, + modelValue: { type: Number }, }, data() { return { + activeTab: 0, tabs: [], }; }, - created() { - this.tabs = this.$children.sort((a, b) => { - return a.index - b.index; - }); - }, methods: { - selectTab(selectorId) { - let view = this; - this.tabs.forEach((tab) => { - tab.isActive = false; - if (tab.selectorId === selectorId) { - tab.isActive = true; - view.$refs[selectorId][0].focus(); - view.$emit('selectTab', tab); - } - }); + selectTab(index) { + if (index >= this.tabs.length || index < 0) { + return; + } + this.activeTab = index; + this.$refs['tabnav' + index][0].focus(); }, - selectTabByIndex(selectedIndex) { - let view = this; - this.tabs.forEach((tab) => { - tab.isActive = false; - if (tab.index === selectedIndex) { - tab.isActive = true; - view.$refs[tab.selectorId][0].focus(); - view.$emit('selectTab', tab); - } - }); + addTab(tab) { + this.tabs.push(tab); }, handleKeyEvent(e) { - let tablist = e.target.parentElement; + const index = parseInt(e.target.dataset.index); switch (e.keyCode) { case 37: // left case 38: // up - if (tablist.firstChild.id !== e.target.id) { - this.selectTab(e.target.previousElementSibling.id); + if (index !== 0) { + this.selectTab(index - 1); } else { - this.selectTab(tablist.lastChild.id); + this.selectTab(this.tabs.length - 1); } break; case 39: // right case 40: // down - if (tablist.lastChild.id !== e.target.id) { - this.selectTab(e.target.nextElementSibling.id); + if (index !== this.tabs.length - 1) { + this.selectTab(index + 1); } else { - this.selectTab(tablist.firstChild.id); + this.selectTab(0); } break; case 36: //pos1 - this.selectTab(tablist.firstChild.id); + this.selectTab(0); break; case 35: //end - this.selectTab(tablist.lastChild.id); + this.selectTab(this.tabs.length - 1); break; } }, - getButtonById(id) { - return this.$refs[id][0]; - }, - getFirstTabButton() { - let selectorId = this.tabs[0].selectorId; - return this.$refs[selectorId][0]; - }, - getTabButtonByName(name) { - let selectorId = null; - this.tabs.forEach((tab) => { - if (tab.name === name) { - selectorId = tab.selectorId; - } - }); - if (selectorId) { - return this.$refs[selectorId][0]; - } - return null; - }, - getTabButtonByAlias(alias) { - let selectorId = null; - this.tabs.forEach((tab) => { - if (tab.alias === alias) { - selectorId = tab.selectorId; - } - }); - if (selectorId) { - return this.$refs[selectorId][0]; + }, + provide() { + return { + addTab: this.addTab, + activeTab: () => this.activeTab, + }; + }, + mounted() { + this.$nextTick(() => { + if (this.modelValue) { + this.selectTab(this.modelValue); } - return null; - }, + }); }, watch: { - setSelected(tab) { - this.selectTabByIndex(tab); + modelValue(newValue) { + this.selectTab(newValue); + }, + activeTab(newValue) { + if (this.modelValue !== newValue) { + this.$emit('update:modelValue', newValue); + } }, }, }; -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue b/resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue index 007a72ef6e3dd9891f79043b2b8d4bacc469313b..b3df5715c908ab9c51db26803662e0bc7077ef57 100644 --- a/resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue +++ b/resources/vue/components/courseware/layouts/CoursewareTalkBubble.vue @@ -34,6 +34,7 @@ import { mapGetters } from 'vuex'; export default { name: 'courseware-talk-bubble', components: { IsoDate }, + emits: ['delete'], props: { payload: Object, }, diff --git a/resources/vue/components/courseware/layouts/CoursewareTile.vue b/resources/vue/components/courseware/layouts/CoursewareTile.vue index d2f53c3535698707384e7bbccf0e403a408afdef..4298439e09d21db73bfd335557d54796fd356d7f 100644 --- a/resources/vue/components/courseware/layouts/CoursewareTile.vue +++ b/resources/vue/components/courseware/layouts/CoursewareTile.vue @@ -55,6 +55,7 @@ export default { components: { StudipIdentImage }, + emits: ['handle-keydown', 'showProgress'], props: { tag: { type: String, @@ -146,15 +147,15 @@ export default { previewImageStyle() { if (this.hasImage) { return { 'background-image': 'url(' + this.imageUrl + ')' }; - } + } return { 'background-image': 'url(' + this.identimage + ')' }; }, progressTitle() { if (this.userIsTeacher) { - return this.$gettextInterpolate(this.$gettext("Fortschritt aller Teilnehmenden: %{progress}%"), { progress: this.progress }); + return this.$gettext("Fortschritt aller Teilnehmenden: %{progress}%", { progress: this.progress }); } - return this.$gettextInterpolate(this.$gettext("Mein Fortschritt: %{progress}%"), { progress: this.progress }); + return this.$gettext("Mein Fortschritt: %{progress}%", { progress: this.progress }); }, hasDescriptionLink() { return this.descriptionLink !== ''; diff --git a/resources/vue/components/courseware/structural-element/CoursewareFeedbackPopup.vue b/resources/vue/components/courseware/structural-element/CoursewareFeedbackPopup.vue index 687ca3ca7bd2c14f7592a429e6fa835565292b3b..81e1e4a822adc5a4edabecfd3e30ba7b33e448d5 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareFeedbackPopup.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareFeedbackPopup.vue @@ -11,7 +11,7 @@ @confirm="submitEntry" > <template v-slot:dialogContent> - <h2>{{ $gettextInterpolate($gettext('Bewertung für %{title}'), { title: structuralElement.attributes.title }) }}</h2> + <h2>{{ $gettext('Bewertung für %{title}', { title: structuralElement.attributes.title }) }}</h2> <div class="feedback-entry-create"> <studip-five-stars-input v-model="rating" /> @@ -34,6 +34,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-feedback-popup', + emits: ['close', 'submit'], components: { StudipFiveStarsInput, }, diff --git a/resources/vue/components/courseware/structural-element/CoursewareRibbon.vue b/resources/vue/components/courseware/structural-element/CoursewareRibbon.vue index 3f6eaba4489d9f5736bd6ecea2136f980230e4b0..5a9e98a7ba83bf3efbc12048d718e7750fb697ac 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareRibbon.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareRibbon.vue @@ -31,14 +31,33 @@ <script lang="ts"> import ContentBar from '../../ContentBar.vue'; -import { mapActions, mapGetters, mapState } from 'vuex'; -import Vue from 'vue'; +import { mapActions, mapGetters } from 'vuex'; import CoursewareRibbonToolbar from './CoursewareRibbonToolbar.vue'; import { store } from '../../../../assets/javascripts/chunks/vue'; +import { defineComponent } from "vue"; -export default Vue.extend({ +export default defineComponent({ name: 'CoursewareRibbon', - components: { CoursewareRibbonToolbar, ContentBar }, + components: { + CoursewareRibbonToolbar, ContentBar + }, + emits: ['blockAdded'], + props: { + canEdit: Boolean, + showToolbarButton: { + default: true, + type: Boolean + }, + showModeSwitchButton: { + default: true, + type: Boolean + }, + buttonsClass: String, + isContentBar: { + type: Boolean, + default: false + } + }, data() { return { // This value is derived from stickyRibbonChange events emitted by @@ -81,13 +100,13 @@ export default Vue.extend({ }, }, methods: { - onStickyRibbonChange(value: boolean) { - this.stickyRibbon = value; - }, ...mapActions({ coursewareViewMode: 'coursewareViewMode', coursewareShowToolbar: 'coursewareShowToolbar', }), + onStickyRibbonChange(value: boolean) { + this.stickyRibbon = value; + }, activateToolbar() { this.coursewareShowToolbar(true); }, diff --git a/resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue b/resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue index fe99808e6406006045751341a6e18f678c246626..9af7a490b3f598f7c90d1ea22e984cdd3dd2b40d 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareRibbonToolbar.vue @@ -1,5 +1,5 @@ <template> - <focus-trap v-model="trap" :initial-focus="() => initialFocusElement" :clickOutsideDeactivates="true" :fallbackFocus ="() => fallbackFocusElement"> + <focus-trap v-model="trap" :clickOutsideDeactivates="false" :fallbackFocus ="() => fallbackFocusElement"> <div class="cw-ribbon-tools" :class="{ 'cw-ribbon-tools-consume': consumeMode }" @@ -12,7 +12,6 @@ > <courseware-tab :name="$gettext('Inhaltsverzeichnis')" - :selected="showContents" alias="contents" ref="contents" :index="0" @@ -53,6 +52,7 @@ import { store } from "../../../../assets/javascripts/chunks/vue"; export default { name: 'courseware-ribbon-toolbar', + emits: ['deactivate'], components: { CoursewareTabs, CoursewareTab, @@ -71,7 +71,6 @@ export default { showContents: true, showUnits: false, trap: false, - initialFocusElement: null }; }, computed: { @@ -113,7 +112,7 @@ export default { this.initialFocusElement = focusElement; this.trap = true; } - }, + } }, mounted() { this.$nextTick(() => { diff --git a/resources/vue/components/courseware/structural-element/CoursewareRootContent.vue b/resources/vue/components/courseware/structural-element/CoursewareRootContent.vue index ee820c4a1754a63878b61c7c671b5a5d0e163c85..bc6833822c24e5f4badbbfc8c2a8c6f22111c0ca 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareRootContent.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareRootContent.vue @@ -60,8 +60,10 @@ <template #footer> <p class="cw-root-content-toc-tile-footer"> {{ - $gettextInterpolate( - $ngettext('%{pages} Seite', '%{pages} Seiten', countChildChildren(child)), + $ngettext( + '%{pages} Seite', + '%{pages} Seiten', + countChildChildren(child), { pages: countChildChildren(child) } ) }} diff --git a/resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue b/resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue index 5d7547d4d9e42bc0ae2532b4b01fefb199aa624e..961fae3f51be23046052cc8b12f821aaa88e9740 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareSearchResults.vue @@ -5,7 +5,7 @@ <studip-icon shape="search" :size="24" /> </template> <template #breadcrumb-list> - <translate>Suchergebnisse</translate> + {{ $gettext('Suchergebnisse') }} </template> <template #menu> <button :title="$gettext('Suchergebnisse schließen')" @click="closeResults"> @@ -18,7 +18,7 @@ <section v-for="result in searchResults" :key="result['structural-element-id']"> <router-link :to="'/structural_element/' + result['structural-element-id']" - @click.native="closeResults" + @click="closeResults" > <div v-show="result.img !== null" class="search-result-img hidden-tiny-down"> <img :src="result.img" /> diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue index 271af3ec19a6275397bedbd2fe673a1158869d03..583717e0e72a79f53ca9e957535897bf79479c43 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElement.vue @@ -1,5 +1,5 @@ <template> - <focus-trap v-model="consumModeTrap"> + <focus-trap v-model:active="consumModeTrap"> <div> <div v-if="validContext" @@ -54,11 +54,10 @@ /> <span v-else - :title="$gettextInterpolate( - $gettext('Fortschritt: %{progress} %'),{ - progress: elementProgress, - }) - " + :title="$gettext( + 'Fortschritt: %{progress} %', + {progress: elementProgress} + )" > ({{ elementProgress }} %) </span> @@ -69,11 +68,12 @@ :size="16" :role="hasFeedbackAverage ? 'status-yellow' : 'inactive'" :title=" - hasFeedbackAverage - ?$gettextInterpolate($gettext('Seite wurde mit %{avg} Sternen bewertet'), { - avg: feedbackAverage, - }) - :$gettext('Seite wurde noch nicht bewertet') + hasFeedbackAverage + ? $gettext( + 'Seite wurde mit %{avg} Sternen bewertet', + { avg: feedbackAverage } + ) + : $gettext('Seite wurde noch nicht bewertet') " @click="menuAction('showFeedback')" /> @@ -142,10 +142,8 @@ <courseware-companion-box v-if="blockedByAnotherUser" :msgCompanion=" - $gettextInterpolate( - $gettext( - 'Die Einstellungen dieser Seite werden im Moment von %{blockingUserName} bearbeitet.' - ), + $gettext( + 'Die Einstellungen dieser Seite werden im Moment von %{blockingUserName} bearbeitet.', { blockingUserName: blockingUserName } ) " @@ -199,10 +197,8 @@ <div v-if="canEdit" class="cw-companion-box-wrapper"> <courseware-companion-box :msgCompanion=" - $gettextInterpolate( - $gettext( - 'Dieser Inhalt ist aus den persönlichen Lernmaterialien von %{ ownerName } verlinkt und kann nur dort bearbeitet werden.' - ), + $gettext( + 'Dieser Inhalt ist aus den persönlichen Lernmaterialien von %{ ownerName } verlinkt und kann nur dort bearbeitet werden.', { ownerName: ownerName } ) " @@ -227,42 +223,41 @@ {{ $gettext('Drücken Sie die Leertaste, um neu anzuordnen.') }} </span> <draggable + v-bind="dragOptions" class="cw-structural-element-list" tag="ol" role="listbox" v-model="containerList" - v-bind="dragOptions" handle=".cw-sortable-handle" @start="isDragging = true" @end="dropContainer" + item-key="id" > - <li - v-for="container in containerList" - :key="container.id" - class="cw-container-item-sortable" - > - <span - :class="{ 'cw-sortable-handle-dragging': isDragging }" - class="cw-sortable-handle" - tabindex="0" - role="option" - aria-describedby="operation" - :ref="'sortableHandle' + container.id" - @keydown="keyHandler($event, container.id)" - ></span> - <component - :is="containerComponent(container)" - :container="container" - :canEdit="canEdit" - :canAddElements="canAddElements" - :isTeacher="userIsTeacher" - class="cw-container-item" - ref="containers" - :class="{ - 'cw-container-item-selected': keyboardSelected === container.id, - }" - /> - </li> + <template #item="{element}"> + <li class="cw-container-item-sortable"> + <span + :class="{ 'cw-sortable-handle-dragging': isDragging }" + class="cw-sortable-handle" + tabindex="0" + role="option" + aria-describedby="operation" + :ref="'sortableHandle' + element.id" + @keydown="keyHandler($event, element.id)" + ></span> + <component + :is="containerComponent(element)" + :container="element" + :canEdit="canEdit" + :canAddElements="canAddElements" + :isTeacher="userIsTeacher" + class="cw-container-item" + ref="containers" + :class="{ + 'cw-container-item-selected': keyboardSelected === element.id, + }" + /> + </li> + </template> </draggable> </template> <studip-progress-indicator @@ -495,6 +490,8 @@ export default { mixins: [CoursewareExport, colorMixin, wizardMixin, containerMixin], + emits: ['select'], + data() { return { currentElement: '', @@ -621,8 +618,8 @@ export default { textDelete.title = this.$gettext('Seite unwiderruflich löschen'); textDelete.alert = this.$gettext('Möchten Sie die Seite wirklich löschen?'); if (this.structuralElementLoaded) { - textDelete.alert = this.$gettextInterpolate( - this.$gettext('Möchten Sie die Seite %{ pageTitle } und alle ihre Unterseiten wirklich löschen?'), + textDelete.alert = this.$gettext( + 'Möchten Sie die Seite %{ pageTitle } und alle ihre Unterseiten wirklich löschen?', { pageTitle: this.structuralElement.attributes.title } ); } @@ -681,11 +678,12 @@ export default { return null; } const element = this.structuralElementById({ id: parentId }); - if (element.relationships.parent.data === null && !this.showRootElement) { - return null; - } if (!element) { console.error(`CoursewareStructuralElement#ancestors: Could not find parent by ID: "${parentId}".`); + return null; + } + if (element.relationships.parent.data === null && !this.showRootElement) { + return null; } return element; @@ -1082,12 +1080,10 @@ export default { return true; }, callToActionTitleFeedback() { - return this.$gettextInterpolate( - this.$ngettext( - '%{length} Anmerkung zur Seite (Nur für Nutzende mit Schreibrechten sichtbar)', - '%{length} Anmerkungen zur Seite (Nur für Nutzende mit Schreibrechten sichtbar)', - this.feedbackCounter - ), + return this.$ngettext( + '%{length} Anmerkung zur Seite (Nur für Nutzende mit Schreibrechten sichtbar)', + '%{length} Anmerkungen zur Seite (Nur für Nutzende mit Schreibrechten sichtbar)', + this.feedbackCounter, { length: this.feedbackCounter } ); }, @@ -1103,8 +1099,10 @@ export default { return this.comments?.length ?? 0; }, callToActionTitleComments() { - return this.$gettextInterpolate( - this.$ngettext('%{length} Kommentar zur Seite', '%{length} Kommentare zur Seite', this.commentsCounter), + return this.$ngettext( + '%{length} Kommentar zur Seite', + '%{length} Kommentare zur Seite', + this.commentsCounter, { length: this.commentsCounter } ); }, @@ -1196,8 +1194,8 @@ export default { await this.loadStructuralElement(this.currentId); if (this.blockedByAnotherUser) { this.companionInfo({ - info: this.$gettextInterpolate( - this.$gettext('Löschen nicht möglich, da %{blockingUserName} die Seite bearbeitet.'), + info: this.$gettext( + 'Löschen nicht möglich, da %{blockingUserName} die Seite bearbeitet.', { blockingUserName: this.blockingUserName } ), }); @@ -1323,8 +1321,8 @@ export default { } if (this.blockedByAnotherUser) { this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext('Löschen nicht möglich, da %{blockingUserName} die Bearbeitung übernommen hat.'), + info: this.$gettext( + 'Löschen nicht möglich, da %{blockingUserName} die Bearbeitung übernommen hat.', { blockingUserName: this.blockingUserName } ), }); @@ -1394,10 +1392,8 @@ export default { this.keyboardSelected = containerId; const container = this.containerById({ id: containerId }); const index = this.containerList.findIndex((c) => c.id === container.id); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - '%{containerTitle} Abschnitt ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.' - ), + this.assistiveLive = this.$gettext( + '%{containerTitle} Abschnitt ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen.', { containerTitle: container.attributes.title, pos: index + 1, @@ -1429,10 +1425,8 @@ export default { const container = this.containerById({ id: containerId }); const newPos = currentIndex - 1; this.containerList.splice(newPos, 0, this.containerList.splice(currentIndex, 1)[0]); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - '%{containerTitle} Abschnitt. Aktuelle Position in der Liste: %{pos} von %{listLength}.' - ), + this.assistiveLive = this.$gettext( + '%{containerTitle} Abschnitt. Aktuelle Position in der Liste: %{pos} von %{listLength}.', { containerTitle: container.attributes.title, pos: newPos + 1, @@ -1447,10 +1441,8 @@ export default { const container = this.containerById({ id: containerId }); const newPos = currentIndex + 1; this.containerList.splice(newPos, 0, this.containerList.splice(currentIndex, 1)[0]); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - '%{containerTitle} Abschnitt. Aktuelle Position in der Liste: %{pos} von %{listLength}.' - ), + this.assistiveLive = this.$gettext( + '%{containerTitle} Abschnitt. Aktuelle Position in der Liste: %{pos} von %{listLength}.', { containerTitle: container.attributes.title, pos: newPos + 1, @@ -1462,8 +1454,8 @@ export default { abortKeyboardSorting(containerId) { const container = this.containerById({ id: containerId }); this.keyboardSelected = null; - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('%{containerTitle} Abschnitt, Neuordnung abgebrochen.'), + this.assistiveLive = this.$gettext( + '%{containerTitle} Abschnitt, Neuordnung abgebrochen.', { containerTitle: container.attributes.title } ); this.selectCurrent(); @@ -1472,10 +1464,8 @@ export default { const container = this.containerById({ id: containerId }); const currentIndex = this.containerList.findIndex((container) => container.id === containerId); this.keyboardSelected = null; - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - '%{containerTitle} Abschnitt, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.' - ), + this.assistiveLive = this.$gettext( + '%{containerTitle} Abschnitt, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.', { containerTitle: container.attributes.title, pos: currentIndex + 1, @@ -1653,18 +1643,24 @@ export default { }, deep: true, }, - containers() { - this.containerList = this.containers; - this.scrollToContainerHash(); - }, - containerList() { - if (this.keyboardSelected) { - this.$nextTick(() => { - const selected = this.$refs['sortableHandle' + this.keyboardSelected][0]; - selected.focus(); - selected.scrollIntoView({ behavior: 'smooth', block: 'center' }); - }); - } + containers: { + handler() { + this.containerList = this.containers; + this.scrollToContainerHash(); + }, + deep: true + }, + containerList: { + handler() { + if (this.keyboardSelected) { + this.$nextTick(() => { + const selected = this.$refs['sortableHandle' + this.keyboardSelected][0]; + selected.focus(); + selected.scrollIntoView({behavior: 'smooth', block: 'center'}); + }); + } + }, + deep: true }, consumeMode(newState) { this.consumModeTrap = newState; @@ -1693,7 +1689,7 @@ export default { window.addEventListener('scroll', this.handleDebouncedScroll); }, - beforeDestroy() { + beforeUnmount() { if (this.handleDebouncedScroll) { window.removeEventListener('scroll', this.handleDebouncedScroll); } diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue index e78377f4f20a70ed428b3fc6bae905cc4ca1c1e4..24a05f822f797bc1af0935c2579cefb5bd141022 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementComments.vue @@ -14,7 +14,7 @@ </div> <div class="cw-structural-element-comment-create"> <textarea v-model="createComment" :placeholder="placeHolder" spellcheck="true"></textarea> - <button class="button" @click="postComment"><translate>Senden</translate></button> + <button class="button" @click="postComment">{{ $gettext('Senden') }}</button> </div> </section> </template> @@ -25,6 +25,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-structural-element-comments', + emits: ['hasComments'], components: { CoursewareTalkBubble, }, @@ -142,4 +143,4 @@ export default { } } } -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue index bdbfa944cf68b951c57ee081353e7484e49d91d9..215e188f440503f357a68c21bc9d531e6a4ace49 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogAdd.vue @@ -83,7 +83,7 @@ <label> {{ $gettext('Farbe') }} <studip-select v-model="color" :options="colors" :reduce="(color) => color.class" label="class" name="color"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> <template #no-options> @@ -345,9 +345,10 @@ export default { await this.loadStructuralElementById({ id: newCreated.id }); const newElement = this.structuralElementById({ id: newCreated.id }); this.companionSuccess({ - info: this.$gettextInterpolate(this.$gettext('Die Seite %{ pageTitle } wurde erfolgreich angelegt.'), { - pageTitle: newElement.attributes.title, - }), + info: this.$gettext( + 'Die Seite %{ pageTitle } wurde erfolgreich angelegt.', + { pageTitle: newElement.attributes.title } + ), }); if (file && this.uploadFileError === '') { diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue index 8d0406cfc498295ef3861c7389d8bc5dc21d7faf..3eeba744882e7ddd6a56ed9c1ddeee1d88cab06c 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogCopy.vue @@ -73,7 +73,7 @@ :getOptionLabel="option => option.attributes.title" v-model="selectedRange" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> @@ -93,17 +93,16 @@ <template v-slot:unit> <form class="default" @submit.prevent=""> <fieldset v-if="units.length !== 0" class="radiobutton-set"> - <template v-for="unit in units"> + <template v-for="unit in units" :key="unit.id"> <input :id="'cw-element-copy-unit-' + unit.id" type="radio" v-model="selectedUnit" :checked="unit.id === selectedUnitId" :value="unit" - :key="'radio-' + unit.id" :aria-description="unit.element.attributes.title" /> - <label :key="'label-' + unit.id" :for="'cw-element-copy-unit-' + unit.id"> + <label :for="'cw-element-copy-unit-' + unit.id"> <div class="icon"><studip-icon shape="courseware" :size="32"/></div> <div class="text">{{ unit.element.attributes.title }}</div> <studip-icon shape="radiobutton-unchecked" :size="24" class="unchecked" /> @@ -148,7 +147,7 @@ :clearable="false" label="class" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> @@ -259,10 +258,10 @@ export default { }, selectedUnitId() { return this.selectedUnit?.id; - }, + }, selectedUnitRootId() { return this.selectedUnit?.relationships?.['structural-element']?.data?.id; - }, + }, selectedElementTitle() { return this.selectedElement?.attributes?.title; }, @@ -386,17 +385,17 @@ export default { }) .then( () => { view.companionSuccess({ - info: view.$gettextInterpolate( - view.$gettext('Die Seite %{ pageTitle } wurde erfolgreich kopiert.'), - {pageTitle: view.selectedElementTitle} + info: view.$gettext( + 'Die Seite %{ pageTitle } wurde erfolgreich kopiert.', + { pageTitle: view.selectedElementTitle } ) }); }) .catch(error => { view.companionError({ - info: view.$gettextInterpolate( - view.$gettext('Die Seite %{ pageTitle } konnte nicht kopiert werden.'), - {pageTitle: view.selectedElementTitle} + info: view.$gettext( + 'Die Seite %{ pageTitle } konnte nicht kopiert werden.', + { pageTitle: view.selectedElementTitle } ) }); }) @@ -427,7 +426,7 @@ export default { this.resetElementData(); this.wizardSlots[2].valid = false; } - + }, async selectedUnit(newUnit) { this.validateSelection(); @@ -438,7 +437,7 @@ export default { } else { this.wizardSlots[1].valid = false; } - + }, selectedRange(newRid) { this.validateSelection(); diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExport.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExport.vue index 0058845caa0e3bba7e030bd776f28d1a639a65bd..754a4c7027239f5fff1f903fd39a26057e9981bd 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExport.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExport.vue @@ -12,9 +12,10 @@ <template v-slot:dialogContent> <div v-show="!exportRunning"> {{ - $gettextInterpolate($gettext('Hiermit exportieren Sie die Seite "%{ pageTitle }" als ZIP-Datei.'), { - pageTitle: structuralElement.attributes.title, - }) + $gettext( + 'Hiermit exportieren Sie die Seite "%{ pageTitle }" als ZIP-Datei.', + { pageTitle: structuralElement.attributes.title } + ) }} <div class="cw-element-export"> <label> diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExportPdf.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExportPdf.vue index 7cb88d9bf709577839d45a9f0f3043dd7985630e..e486c1b5c83f22c3309d4a17c0dfc22580031ba8 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExportPdf.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogExportPdf.vue @@ -11,9 +11,10 @@ > <template v-slot:dialogContent> {{ - $gettextInterpolate($gettext('Hiermit exportieren Sie die Seite "%{ pageTitle }" als PDF-Datei.'), { - pageTitle: structuralElement.attributes.title, - }) + $gettext( + 'Hiermit exportieren Sie die Seite "%{ pageTitle }" als PDF-Datei.', + { pageTitle: structuralElement.attributes.title } + ) }} <div class="cw-element-export"> <label> diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogInfo.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogInfo.vue index fcc5a8796be8c0c0f4acea243d1bc6f40c0a8175..5fda85d1f4514326dae32dd810d623a19bb0eacc 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogInfo.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogInfo.vue @@ -6,30 +6,32 @@ > <template v-slot:dialogContent> <table class="cw-structural-element-info"> - <tr> - <td>{{ $gettext('Titel') }}:</td> - <td>{{ structuralElement.attributes.title }}</td> - </tr> - <tr> - <td>{{ $gettext('Beschreibung') }}:</td> - <td>{{ structuralElement.attributes.payload.description }}</td> - </tr> - <tr> - <td>{{ $gettext('Seite wurde erstellt von') }}:</td> - <td>{{ ownerName }}</td> - </tr> - <tr> - <td>{{ $gettext('Seite wurde erstellt am') }}:</td> - <td><iso-date :date="structuralElement.attributes.mkdate" /></td> - </tr> - <tr> - <td>{{ $gettext('Zuletzt bearbeitet von') }}:</td> - <td>{{ editorName }}</td> - </tr> - <tr> - <td>{{ $gettext('Zuletzt bearbeitet am') }}:</td> - <td><iso-date :date="structuralElement.attributes.chdate" /></td> - </tr> + <tbody> + <tr> + <td>{{ $gettext('Titel') }}:</td> + <td>{{ structuralElement.attributes.title }}</td> + </tr> + <tr> + <td>{{ $gettext('Beschreibung') }}:</td> + <td>{{ structuralElement.attributes.payload.description }}</td> + </tr> + <tr> + <td>{{ $gettext('Seite wurde erstellt von') }}:</td> + <td>{{ ownerName }}</td> + </tr> + <tr> + <td>{{ $gettext('Seite wurde erstellt am') }}:</td> + <td><iso-date :date="structuralElement.attributes.mkdate" /></td> + </tr> + <tr> + <td>{{ $gettext('Zuletzt bearbeitet von') }}:</td> + <td>{{ editorName }}</td> + </tr> + <tr> + <td>{{ $gettext('Zuletzt bearbeitet am') }}:</td> + <td><iso-date :date="structuralElement.attributes.chdate" /></td> + </tr> + </tbody> </table> </template> </studip-dialog> diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue index 2029d5681f81dfed83c58d8e83b6f1e148cafd2a..7d7e6ccf438426bc6bfe797674f1a8ab41230e19 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogLink.vue @@ -12,16 +12,15 @@ <template v-slot:unit> <form v-if="!loadingUnits" class="default" @submit.prevent=""> <fieldset v-if="hasUnits" class="radiobutton-set"> - <template v-for="unit in units"> + <template v-for="unit in units" :key="unit.id"> <input :id="'cw-element-link-unit-' + unit.id" type="radio" :checked="unit.id === selectedUnitId" :value="unit.id" - :key="'radio-' + unit.id" :aria-description="unit.element.attributes.title" /> - <label @click="selectedUnit = unit" :key="'label-' + unit.id" :for="'cw-element-link-unit-' + unit.id"> + <label @click="selectedUnit = unit" :for="'cw-element-link-unit-' + unit.id"> <div class="icon"><studip-icon shape="courseware" :size="32"/></div> <div class="text">{{ unit.element.attributes.title }}</div> <studip-icon shape="radiobutton-unchecked" :size="24" class="unchecked" /> @@ -35,7 +34,7 @@ :msgCompanion="$gettext('Es konnte leider kein Lernmaterial gefunden werden. Bitte erstellen Sie unter Arbeitsplatz/Courseware ein Lernmaterial.')" /> </form> - <studip-progress-indicator + <studip-progress-indicator v-else :description="$gettext('Lade Lernmaterialien…')" /> @@ -75,9 +74,9 @@ export default { data() { return { wizardSlots: [ - {id: 1, valid: false, name: 'unit', title: this.$gettext('Lernmaterial'), icon: 'courseware', + {id: 1, valid: false, name: 'unit', title: this.$gettext('Lernmaterial'), icon: 'courseware', description: this.$gettext('Wählen Sie das Lernmaterial aus, in dem sich der zu verknüpfende Lerninhalt befindet. Die Lerninhalte, die verknüpft werden können, müssen unter Arbeitsplatz/Courseware vorher erstellt werden.')}, - {id: 2, valid: false, name: 'element', title: this.$gettext('Seite'), icon: 'content2', + {id: 2, valid: false, name: 'element', title: this.$gettext('Seite'), icon: 'content2', description: this.$gettext('Wählen Sie die zu verknüpfende Seite aus. Um Unterseiten anzuzeigen, klicken Sie auf den Seitennamen. Mit einem weiteren Klick werden die Unterseiten wieder zugeklappt.')}, ], loadingUnits: false, selectedUnit: null, @@ -110,10 +109,10 @@ export default { }, selectedUnitId() { return this.selectedUnit?.id; - }, + }, selectedUnitRootId() { return this.selectedUnit?.relationships?.['structural-element']?.data?.id; - }, + }, selectedElementTitle() { return this.selectedElement?.attributes?.title; }, @@ -176,16 +175,16 @@ export default { }) .then( () => { view.companionSuccess({ - info: view.$gettextInterpolate( - view.$gettext('Die Seite %{ pageTitle } wurde erfolgreich verknüpft.'), + info: view.$gettext( + 'Die Seite %{ pageTitle } wurde erfolgreich verknüpft.', { pageTitle: view.selectedElementTitle } ) }); }) .catch( () => { view.companionError({ - info: view.$gettextInterpolate( - view.$gettext('Die Seite %{ pageTitle } konnte nicht verknüpft werden.'), + info: view.$gettext( + 'Die Seite %{ pageTitle } konnte nicht verknüpft werden.', { pageTitle: view.selectedElementTitle } ) }); diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogOerSuggest.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogOerSuggest.vue index 30a57d441289dd3e39e3f022d08330c87f163548..8f1ba0cb28f8189b5008ae7045d7f21cb2e35101 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogOerSuggest.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogOerSuggest.vue @@ -13,23 +13,23 @@ <template v-slot:dialogContent> <p> {{ - $gettextInterpolate( - $gettext( - 'Der folgende Lerninhalt wird %{ ownerName } zur Veröffentlichung im OER Campus vorgeschlagen:' - ), + $gettext( + 'Der folgende Lerninhalt wird %{ ownerName } zur Veröffentlichung im OER Campus vorgeschlagen:', { ownerName: ownerName } ) }} </p> <table class="cw-structural-element-info"> - <tr> - <td>{{ $gettext('Titel') }}:</td> - <td>{{ structuralElement.attributes.title }}</td> - </tr> - <tr> - <td>{{ $gettext('Beschreibung') }}:</td> - <td>{{ structuralElement.attributes.payload.description }}</td> - </tr> + <tbody> + <tr> + <td>{{ $gettext('Titel') }}:</td> + <td>{{ structuralElement.attributes.title }}</td> + </tr> + <tr> + <td>{{ $gettext('Beschreibung') }}:</td> + <td>{{ structuralElement.attributes.payload.description }}</td> + </tr> + </tbody> </table> <form class="default" @submit.prevent=""> <label> diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogPermissions.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogPermissions.vue index 930cd909ae54774b50a58c21705700f029047e3c..fbec044a02de884b1e71133f7a915a0608428f39 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogPermissions.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogPermissions.vue @@ -261,6 +261,7 @@ import axios from 'axios'; import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-structural-element-dialog-permissions', + emits: ['close', 'store'], components: { CoursewareCompanionBox, Datepicker, @@ -437,10 +438,8 @@ export default { await this.loadStructuralElement(this.structuralElement.id); if (this.blockedByAnotherUser) { this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext( - 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.' - ), + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.', { blockingUserName: this.blockingUserName } ), }); diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogSettings.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogSettings.vue index dd81d541a86804169406729b739db05759194d40..1481926e15ad65659b0069ac18facfd29dc01f54 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogSettings.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementDialogSettings.vue @@ -112,7 +112,9 @@ :alt="$gettext('Vorschaubild')" /> <label> - <button class="button" @click="deleteImage" v-translate>Bild löschen</button> + <button class="button" @click="deleteImage"> + {{ $gettext('Bild löschen') }} + </button> </label> </template> @@ -167,6 +169,7 @@ import StockImageSelector from '../../stock-images/SelectorDialog.vue'; import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-structural-element-dialog-settings', + emits: ['close', 'store'], mixins: [colorMixin, wizardMixin], components: { CoursewareContentPermissions, @@ -280,10 +283,8 @@ export default { await this.loadStructuralElement(this.currentElement.id); if (this.blockedByAnotherUser) { this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext( - 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.' - ), + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.', { blockingUserName: this.blockingUserName } ), }); diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue index 8d9f95863d98636ecb59d76af8a28708f6c333f9..a965e84957eed3a53c5701c1989e1884352e533c 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementFeedback.vue @@ -34,6 +34,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-structural-element-feedback', + emits: ['hasFeedback'], components: { CoursewareCompanionBox, CoursewareTalkBubble, diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue index eead7ab856f52686c9afdff102afbef0d102e00d..49650d0bfb02e56798d7be68ab8dff0c8daaf4c7 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementPermissions.vue @@ -2,16 +2,16 @@ <div class="cw-element-permissions"> <label> <input type="checkbox" class="default" v-model="userPermsReadAll" /> - <translate>Alle Teilnehmenden haben Leserechte</translate> + {{ $gettext('Alle Teilnehmenden haben Leserechte') }} </label> <label> <input type="checkbox" class="default" v-model="userPermsWriteAll" /> - <translate>Alle Teilnehmenden haben Schreibrechte</translate> + {{ $gettext('Alle Teilnehmenden haben Schreibrechte') }} </label> <table class="default" v-if="autor_members.length"> <caption> - <translate>Studierende</translate> + {{ $gettext('Studierende') }} </caption> <colgroup> <col style="width:1%" /> @@ -23,10 +23,10 @@ <thead> <tr> <th><input type="checkbox" v-model="bulkSelectAutorRead" @click="handleBulkSelectRead($event, 'autor')"/></th> - <th><translate>Lesen</translate></th> + <th>{{ $gettext('Lesen') }}</th> <th><input type="checkbox" v-model="bulkSelectAutorWrite" @click="handleBulkSelectWrite($event)"/></th> - <th><translate>Lesen und Schreiben</translate></th> - <th><translate>Name</translate></th> + <th>{{ $gettext('Lesen und Schreiben') }}</th> + <th>{{ $gettext('Name') }}</th> </tr> </thead> <tbody> @@ -71,7 +71,7 @@ <table class="default" v-if="user_members.length"> <caption> - <translate>Leser/-innen</translate> + {{ $gettext('Leser/-innen') }} </caption> <colgroup> <col style="width:1%" /> @@ -81,8 +81,8 @@ <thead> <tr> <th><input type="checkbox" v-model="bulkSelectUserRead" @click="handleBulkSelectRead($event, 'user')"/></th> - <th><translate>Lesen</translate></th> - <th><translate>Name</translate></th> + <th>{{ $gettext('Lesen') }}</th> + <th>{{ $gettext('Name') }}</th> </tr> </thead> <tbody> @@ -119,7 +119,7 @@ <table class="default" v-if="groups.length"> <caption> - <translate>Gruppen</translate> + {{ $gettext('Gruppen') }} </caption> <colgroup> <col style="width:20%" /> @@ -128,9 +128,9 @@ </colgroup> <thead> <tr> - <th><translate>Lesen</translate></th> - <th><translate>Lesen und Schreiben</translate></th> - <th><translate>Name</translate></th> + <th>{{ $gettext('Lesen') }}</th> + <th>{{ $gettext('Lesen und Schreiben') }}</th> + <th>{{ $gettext('Name') }}</th> </tr> </thead> <tbody> @@ -169,6 +169,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-structural-element-permissions', + emits: ['updateReadApproval', 'updateWriteApproval'], props: { element: Object, }, diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelector.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelector.vue index 0e8acda3bbcecc526859cc5a9638a977c4cd5e06..67c02e6dd71ab609b930b890c7587635f27f0f26 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelector.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelector.vue @@ -27,11 +27,13 @@ export default { CoursewareStructuralElementSelectorItem }, model: { - prop: 'element' + prop: 'modelValue', + event: 'update:modelValue' }, props: { - element: { - type: Object + modelValue: { + type: Object, + required: true }, rootId: { type: String, @@ -75,7 +77,7 @@ export default { .filter(Boolean); }, selectedId() { - return this.element?.id ?? ''; + return this.modelValue?.id ?? ''; }, targetElement() { return this.structuralElementById({ id: this.targetId }); @@ -116,7 +118,7 @@ export default { companionSuccess: 'companionSuccess', }), handleInput(id) { - this.$emit('input', this.structuralElementById({ id })); + this.$emit('update:modelValue', this.structuralElementById({ id })); this.focusedElementId = id; }, handleFocus(id) { diff --git a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelectorItem.vue b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelectorItem.vue index f6b3cf6a66ee2c3b1b79bfd37ec783b9f06bddaa..c268e5170d62d4b151f80cb169d4c3b261197b7e 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelectorItem.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareStructuralElementSelectorItem.vue @@ -14,7 +14,7 @@ <studip-icon v-if="selected" shape="radiobutton-checked" /> <studip-icon v-else shape="radiobutton-unchecked" /> </template> - <studip-icon v-else shape="decline" role="inactive" /> + <studip-icon v-else shape="decline" role="inactive" /> </span> <template v-if="hasChildren"> <a href="#" :aria-expanded="isOpen ? 'true' : 'false'" @click.prevent="toggleChildrenVisibility"> @@ -58,6 +58,7 @@ import { mapActions, mapGetters } from 'vuex' export default { name: 'courseware-structural-element-selector-item', + emits: ['focus', 'input', 'selectable'], props: { element: { type: Object @@ -75,7 +76,7 @@ export default { rootId: { type: String, required: true - }, + }, validateAncestors: { type: Boolean, default: false @@ -171,7 +172,7 @@ export default { return element.id; } else { return this.siblings[index].id; - } + } } else { return this.$parent.element.id; } @@ -229,7 +230,7 @@ export default { case 38: // arrow up event.preventDefault(); if (this.previousElementId !== null) { - this.$emit('focus', this.previousElementId); + this.$emit('focus', this.previousElementId); } break; case 39: // arrow right diff --git a/resources/vue/components/courseware/structural-element/CoursewareToolsContents.vue b/resources/vue/components/courseware/structural-element/CoursewareToolsContents.vue index 6426b7c83100d3d10a396c0b9b04452f745f0137..2842aced12d79154b5e959b2286fbf7fd251c319 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareToolsContents.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareToolsContents.vue @@ -82,36 +82,40 @@ export default { }; </script> <style scoped lang="scss"> -.cw-tools-contents-header { - display: flex; - flex-direction: row; - height: 100px; - margin-top: 8px; - .cw-tools-contents-header-image { - height: 100px; - width: 150px; - min-width: 150px; - background-size: 100% auto; - background-repeat: no-repeat; - background-position: center; - background-color: var(--content-color-20); - } +.cw-tools-contents { + padding: 0 5px; - .cw-tools-contents-header-details { - margin: 0 8px; - display: -webkit-box; - overflow: hidden; + .cw-tools-contents-header { + display: flex; + flex-direction: row; height: 100px; - -webkit-line-clamp: 5; - -webkit-box-orient: vertical; - header { - margin: 0 0 6px 0; - font-size: 16px; - line-height: 16px; + margin-top: 8px; + .cw-tools-contents-header-image { + height: 100px; + width: 150px; + min-width: 150px; + background-size: 100% auto; + background-repeat: no-repeat; + background-position: center; + background-color: var(--content-color-20); } - p { - margin: 0; - color: var(--black); + + .cw-tools-contents-header-details { + margin: 0 8px; + display: -webkit-box; + overflow: hidden; + height: 100px; + -webkit-line-clamp: 5; + -webkit-box-orient: vertical; + header { + margin: 0 0 6px 0; + font-size: 16px; + line-height: 16px; + } + p { + margin: 0; + color: var(--black); + } } } } diff --git a/resources/vue/components/courseware/structural-element/CoursewareTree.vue b/resources/vue/components/courseware/structural-element/CoursewareTree.vue index bd25c6b66900169db242632d07dd355993c27231..915f2e340cc009dc79e99dd48824063bd9920138 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareTree.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareTree.vue @@ -1,11 +1,9 @@ <template> <div class="cw-tree" ref="tree"> - <template> - <span aria-live="assertive" class="assistive-text">{{ assistiveLive }}</span> - <span id="operation" class="assistive-text"> - {{$gettext('Drücken Sie die Leertaste, um neu anzuordnen.')}} - </span> - </template> + <span aria-live="assertive" class="assistive-text">{{ assistiveLive }}</span> + <span id="operation" class="assistive-text"> + {{ $gettext('Drücken Sie die Leertaste, um neu anzuordnen.') }} + </span> <ol v-if="!processing" class="cw-tree-root-list" role="listbox"> <courseware-tree-item class="cw-tree-item" @@ -21,7 +19,7 @@ <courseware-tree-item-adder v-if="canEditRoot" :parentId="rootElement.id"/> </ol> <studip-progress-indicator - v-else + v-else :description="$gettext('Vorgang wird bearbeitet...')" /> </div> @@ -35,7 +33,7 @@ import StudipProgressIndicator from '../../StudipProgressIndicator.vue'; import { mapActions, mapGetters } from 'vuex'; export default { - components: { + components: { CoursewareTreeItem, CoursewareTreeItemAdder, StudipProgressIndicator @@ -55,7 +53,7 @@ export default { relatedStructuralElement: 'courseware-structural-elements/related', structuralElementById: 'courseware-structural-elements/byId', childrenById: 'courseware-structure/children', - viewMode: 'viewMode', + viewMode: 'viewMode', structuralElements: 'courseware-structural-elements/all', assistiveLive: 'assistiveLiveContents', }), @@ -188,9 +186,14 @@ export default { element.nestedChildren[newPos].sortArray = element.nestedChildren.map(c => {return {id: c.id, type: 'courseware-structural-elements'}}); element.nestedChildren[newPos].moveDirection = data.direction; - const assistiveLive = this.$gettextInterpolate( - this.$gettext('%{elementTitle} eine Ebene nach oben bewegt. Übergeordnete Seite: %{parentTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}'), - { elementTitle: data.element.attributes.title, parentTitle: element.attributes.title, pos: newPos + 1, listLength: element.nestedChildren[newPos].sortArray.length } + const assistiveLive = this.$gettext( + '%{elementTitle} eine Ebene nach oben bewegt. Übergeordnete Seite: %{parentTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}', + { + elementTitle: data.element.attributes.title, + parentTitle: element.attributes.title, + pos: newPos + 1, + listLength: element.nestedChildren[newPos].sortArray.length + } ); this.setAssistiveLiveContents(assistiveLive); } @@ -206,9 +209,13 @@ export default { element.nestedChildren[newPos].sortArray = element.nestedChildren.map(c => {return {id: c.id, type: 'courseware-structural-elements'}}); element.nestedChildren[newPos].moveDirection = data.direction; - const assistiveLive = this.$gettextInterpolate( - this.$gettext('%{elementTitle} bewegt. Aktuelle Position in der Liste: %{pos} von %{listLength}'), - { elementTitle: data.element.attributes.title, pos: newPos + 1, listLength: element.nestedChildren[newPos].sortArray.length } + const assistiveLive = this.$gettext( + '%{elementTitle} bewegt. Aktuelle Position in der Liste: %{pos} von %{listLength}', + { + elementTitle: data.element.attributes.title, + pos: newPos + 1, + listLength: element.nestedChildren[newPos].sortArray.length + } ); this.setAssistiveLiveContents(assistiveLive); } @@ -225,9 +232,14 @@ export default { element.nestedChildren[newParentIndex].nestedChildren[newPos].newParentId = parseInt(newParentId); element.nestedChildren[newParentIndex].nestedChildren[newPos].sortArray = element.nestedChildren[newParentIndex].nestedChildren.map(c => {return {id: c.id, type: 'courseware-structural-elements'}}); - const assistiveLive = this.$gettextInterpolate( - this.$gettext('%{elementTitle} eine Ebene nach unten bewegt. Übergeordnete Seite: %{parentTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}'), - { elementTitle: data.element.attributes.title, parentTitle: element.nestedChildren[newParentIndex].attributes.title, pos: newPos + 1, listLength: element.nestedChildren[newParentIndex].nestedChildren[newPos].sortArray.length } + const assistiveLive = this.$gettext( + '%{elementTitle} eine Ebene nach unten bewegt. Übergeordnete Seite: %{parentTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}', + { + elementTitle: data.element.attributes.title, + parentTitle: element.nestedChildren[newParentIndex].attributes.title, + pos: newPos + 1, + listLength: element.nestedChildren[newParentIndex].nestedChildren[newPos].sortArray.length + } ); this.setAssistiveLiveContents(assistiveLive); } diff --git a/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue index 6fe7da87d39c4e872eb5090d8fb1f63f21ffbff4..d9d7b3c26c8572b4fbc9db412cc15577fba6d18c 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareTreeItem.vue @@ -54,7 +54,7 @@ <span v-else class="cw-tree-item-sequential cw-tree-item-sequential-percentage" - :title="$gettextInterpolate($gettext('Fortschritt: %{progress}%'), { progress: itemProgress })" + :title="$gettext('Fortschritt: %{progress}%', { progress: itemProgress })" > {{ itemProgress }} % </span> @@ -79,35 +79,36 @@ </ol> <draggable v-if="canEdit" + v-bind="dragOptions" :class="{ 'cw-tree-chapter-list-empty': nestedChildren.length === 0 }" tag="ol" :component-data="draggableData" class="cw-tree-draggable-list" handle=".cw-sortable-handle" - v-bind="dragOptions" :elementId="element.id" :list="nestedChildren" :group="{ name: 'g1' }" @end="endDrag" + item-key="id" > - <courseware-tree-item - v-for="el in nestedChildren" - :key="el.id" - :element="el" - :currentElement="currentElement" - :depth="depth + 1" - :newPos="el.newPos" - :newParentId="el.newParentId" - :siblingCount="nestedChildren.length" - class="cw-tree-item" - :elementid="el.id" - @sort="sort" - @moveItemUp="moveItemUp" - @moveItemDown="moveItemDown" - @moveItemPrevLevel="moveItemPrevLevel" - @moveItemNextLevel="moveItemNextLevel" - @childrenUpdated="$emit('childrenUpdated')" - /> + <template #item="{element}"> + <courseware-tree-item + :element="element" + :currentElement="currentElement" + :depth="depth + 1" + :newPos="element.newPos" + :newParentId="element.newParentId" + :siblingCount="nestedChildren.length" + class="cw-tree-item" + :elementid="element.id" + @sort="sort" + @moveItemUp="moveItemUp" + @moveItemDown="moveItemDown" + @moveItemPrevLevel="moveItemPrevLevel" + @moveItemNextLevel="moveItemNextLevel" + @childrenUpdated="$emit('childrenUpdated')" + /> + </template> </draggable> <ol v-if="canEdit && isFirstLevel" class="cw-tree-adder-list"> <courseware-tree-item-adder :parentId="element.id" /> @@ -124,6 +125,14 @@ import { mapGetters, mapActions } from 'vuex'; export default { name: 'courseware-tree-item', + emits: [ + 'childrenUpdated', + 'moveItemDown', + 'moveItemNextLevel', + 'moveItemPrevLevel', + 'moveItemUp', + 'sort', + ], components: { CoursewareTreeItemAdder, CoursewareTreeItemUpdater, @@ -194,9 +203,10 @@ export default { return { attrs: { role: 'listbox', - ['aria-label']: this.$gettextInterpolate(this.$gettext('Unterseiten von %{elementName}'), { - elementName: this.element.attributes?.title, - }), + ['aria-label']: this.$gettext( + 'Unterseiten von %{elementName}', + { elementName: this.element.attributes?.title } + ), }, }; }, @@ -247,23 +257,28 @@ export default { break; case 'users': { const users = this.element.attributes['visible-approval'].length; - persons = this.$gettextInterpolate( - this.$ngettext('einen Studierenden', '%{count} Studierende', users), + persons = this.$ngettext( + 'einen Studierenden', + '%{count} Studierende', + users, { count: users } ); break; } case 'groups': { const groups = this.element.attributes['visible-approval'].length; - persons = this.$gettextInterpolate(this.$ngettext('eine Gruppe', '%{count} Gruppen', groups), { - count: groups, - }); + persons = this.$ngettext( + 'eine Gruppe', + '%{count} Gruppen', + groups, + { count: groups } + ); break; } } - return this.$gettextInterpolate( - this.$gettext('Diese Seite ist vom %{start} bis zum %{end} für %{persons} sichtbar'), + return this.$gettext( + 'Diese Seite ist vom %{start} bis zum %{end} für %{persons} sichtbar', { start: startDate, end: endDate, persons: persons } ); } @@ -291,21 +306,28 @@ export default { const count = writableApproval.length; switch (this.element.attributes?.['permission-type']) { case 'users': - persons = this.$gettextInterpolate(this.$ngettext('einem Studierendem', '%{count} Studierenden', count), { - count: count, - }); + persons = this.$ngettext( + 'einem Studierendem', + '%{count} Studierenden', + count, + { count: count } + ); break; case 'groups': - persons = this.$gettextInterpolate(this.$ngettext('einer Gruppe', '%{count} Gruppen', count), { - count: count, - }); + persons = + this.$ngettext( + 'einer Gruppe', + '%{count} Gruppen', + count, + { count: count } + ); break; } - return this.$gettextInterpolate( - this.$gettext('Diese Seite kann von %{persons} bearbeitet werden'), - { persons: persons } - ); + return this.$gettext( + 'Diese Seite kann von %{persons} bearbeitet werden', + { persons: persons } + ); }, hasNoReadApproval() { if (this.context.type === 'users' || this.element.attributes?.['visible-all']) { @@ -318,10 +340,10 @@ export default { case 'users': return this.autorMembersCount !== visibleApproval.length; case 'groups': - return this.statusGroupsCount !== visibleApproval.length; + return this.statusGroupsCount !== visibleApproval.length; } - return true; + return true; }, cantReadFlagTitle() { if (!this.hasNoReadApproval) { @@ -335,22 +357,29 @@ export default { return this.$gettext('Diese Seite kann von Studierenden nicht gesehen werden'); case 'users': count = this.autorMembersCount - visibleApproval.length; - persons = this.$gettextInterpolate(this.$ngettext('einem Studierendem', '%{count} Studierenden', count), { - count: count, - }); + persons = this.$ngettext( + 'einem Studierendem', + '%{count} Studierenden', + count, + { count: count } + ); break; case 'groups': count = this.statusGroupsCount - visibleApproval.length - persons = this.$gettextInterpolate(this.$ngettext('einer Gruppe', '%{count} Gruppen', count), { - count: count, - }); + persons = + this.$ngettext( + 'einer Gruppe', + '%{count} Gruppen', + count, + { count: count } + ); break; } - return this.$gettextInterpolate( - this.$gettext('Diese Seite kann von %{persons} nicht gesehen werden'), - { persons: persons } - ); + return this.$this.$gettext( + 'Diese Seite kann von %{persons} nicht gesehen werden', + { persons: persons } + ); }, hasPurposeClass() { return this.purposeClass !== ''; @@ -450,7 +479,7 @@ export default { newPos: e.newIndex, oldPos: e.oldIndex, oldParent: e.item._underlying_vm_.relationships.parent.data.id, - newParent: e.to.__vue__.$attrs.elementId, + newParent: e.to.__vnode.ctx.attrs.elementId, sortArray: sortArray, }; @@ -475,10 +504,8 @@ export default { this.storeKeyboardSorting(); } else { this.keyboardSelected = true; - const assistiveLive = this.$gettextInterpolate( - this.$gettext( - '%{elementTitle} ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen. Mit Pfeiltasten links und rechts kann die Position in der Hierarchie verändert werden.' - ), + const assistiveLive = this.$gettext( + '%{elementTitle} ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste zum Ablegen, die Escape-Taste zum Abbrechen. Mit Pfeiltasten links und rechts kann die Position in der Hierarchie verändert werden.', { elementTitle: this.element.attributes.title, pos: this.element.attributes.position + 1, @@ -537,9 +564,10 @@ export default { }, abortKeyboardSorting() { this.$emit('childrenUpdated'); - const assistiveLive = this.$gettextInterpolate(this.$gettext('%{elementTitle}. Neuordnung abgebrochen.'), { - elementTitle: this.element.attributes.title, - }); + const assistiveLive = this.$gettext( + '%{elementTitle}. Neuordnung abgebrochen.', + { elementTitle: this.element.attributes.title } + ); this.setAssistiveLiveContents(assistiveLive); this.$nextTick(() => { this.keyboardSelected = false; @@ -557,8 +585,8 @@ export default { this.keyboardSelected = false; if (data.newParent === undefined || data.newPos === undefined) { - const assistiveLive = this.$gettextInterpolate( - this.$gettext('%{elementTitle}. Neuordnung nicht möglich.'), + const assistiveLive = this.$gettext( + '%{elementTitle}. Neuordnung nicht möglich.', { elementTitle: this.element.attributes.title } ); this.setAssistiveLiveContents(assistiveLive); @@ -566,17 +594,21 @@ export default { } if (data.oldParent === data.newParent && data.oldPos === data.newPos) { - const assistiveLive = this.$gettextInterpolate( - this.$gettext('%{elementTitle}. Neuordnung abgebrochen.'), + const assistiveLive = this.$gettext( + '%{elementTitle}. Neuordnung abgebrochen.', { elementTitle: this.element.attributes.title } ); this.setAssistiveLiveContents(assistiveLive); return; } this.$emit('sort', data); - const assistiveLive = this.$gettextInterpolate( - this.$gettext('%{elementTitle}, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.'), - { elementTitle: this.element.attributes.title, pos: data.newPos + 1, listLength: this.siblingCount } + const assistiveLive = this.$gettext( + '%{elementTitle}, abgelegt. Entgültige Position in der Liste: %{pos} von %{listLength}.', + { + elementTitle: this.element.attributes.title, + pos: data.newPos + 1, + listLength: this.siblingCount + } ); this.setAssistiveLiveContents(assistiveLive); }, diff --git a/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue index 78690c9684156f719020a47e16d4fb3b317bab0a..006def158b85940afae430135643363c7265177b 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareTreeItemUpdater.vue @@ -11,6 +11,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-tree-item-adder', + emits: ['childrenUpdated', 'close'], props: { structuralElement: { type: Object, @@ -61,10 +62,8 @@ export default { await this.loadUser({ id: blockerData.id }); const blocker = this.userById({ id: blockerData.id }); this.companionWarning({ - info: this.$gettextInterpolate( - this.$gettext( - 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.' - ), + info: this.$gettext( + 'Ihre Änderungen konnten nicht gespeichert werden, da %{blockingUserName} die Bearbeitung übernommen hat.', { blockingUserName: blocker.attributes['formatted-name'] } ), }); diff --git a/resources/vue/components/courseware/structural-element/CoursewareTreeUnit.vue b/resources/vue/components/courseware/structural-element/CoursewareTreeUnit.vue index 9e5482a22a6ba6d5a4ffaa68d84b4add05874b53..167bb11dcf0b89b69804d903d9bf428560eed6d3 100644 --- a/resources/vue/components/courseware/structural-element/CoursewareTreeUnit.vue +++ b/resources/vue/components/courseware/structural-element/CoursewareTreeUnit.vue @@ -31,6 +31,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'CoursewareTreeUnit', mixins: [colorMixin], + emits: ['removeUnitLink'], components: { StudipIdentImage, }, diff --git a/resources/vue/components/courseware/tasks/AddFeedbackDialog.vue b/resources/vue/components/courseware/tasks/AddFeedbackDialog.vue index 2d7c28104e9f7bb9be195f6016bbad0ea44bb6bc..97c230bc3df135150860b7e7c356cdc08d8e52f6 100644 --- a/resources/vue/components/courseware/tasks/AddFeedbackDialog.vue +++ b/resources/vue/components/courseware/tasks/AddFeedbackDialog.vue @@ -23,6 +23,7 @@ <script> export default { props: ['content'], + emits: ['close', 'create'], data: () => ({ localContent: '', }), diff --git a/resources/vue/components/courseware/tasks/CoursewareDashboardTasks.vue b/resources/vue/components/courseware/tasks/CoursewareDashboardTasks.vue index cb3577ad5638f2b927e7519f2fcb78f746feb829..9bf7b6356577a004831d61cc2cc7c687a8984fa0 100644 --- a/resources/vue/components/courseware/tasks/CoursewareDashboardTasks.vue +++ b/resources/vue/components/courseware/tasks/CoursewareDashboardTasks.vue @@ -332,13 +332,17 @@ export default { if (attributes.visible) { this.companionSuccess({ - info: this.$gettextInterpolate(this.$gettext('"%{ title }" wurde freigegeben.'), - { title: taskTitle }), + info: this.$gettext( + '"%{ title }" wurde freigegeben.', + { title: taskTitle } + ), }); } else { this.companionSuccess({ - info: this.$gettextInterpolate(this.$gettext('Die Freigabe für %{ "title }" wurde zurückgenommen.'), - { title: taskTitle }), + info: this.$gettext( + 'Die Freigabe für %{ "title }" wurde zurückgenommen.', + { title: taskTitle } + ), }); } } diff --git a/resources/vue/components/courseware/tasks/CoursewareTasksDialogDistribute.vue b/resources/vue/components/courseware/tasks/CoursewareTasksDialogDistribute.vue index 7680167cd2e71ab3fa8fd32aa7d85479783aa202..525a9c123546f0962e1f698a8997914095b13229 100644 --- a/resources/vue/components/courseware/tasks/CoursewareTasksDialogDistribute.vue +++ b/resources/vue/components/courseware/tasks/CoursewareTasksDialogDistribute.vue @@ -12,19 +12,17 @@ <template v-slot:sourceunit> <form class="default" @submit.prevent=""> <fieldset v-if="sourceUnits.length !== 0" class="radiobutton-set"> - <template v-for="unit in sourceUnits"> + <template v-for="unit in sourceUnits" :key="'radio-' + unit.id"> <input :id="'cw-task-dist-source-unit' + unit.id" type="radio" v-model="selectedSourceUnit" :checked="unit.id === selectedSourceUnitId" :value="unit" - :key="'radio-' + unit.id" :aria-description="unit.element.attributes.title" /> <label @click="selectedSourceUnit = unit" - :key="'label-' + unit.id" :for="'cw-task-dist-source-unit' + unit.id" > <div class="icon"><studip-icon shape="courseware" :size="32" /></div> @@ -89,19 +87,17 @@ <template v-slot:targetunit> <form v-if="selectedTaskIsTask" class="default" @submit.prevent=""> <fieldset v-if="targetUnits.length !== 0" class="radiobutton-set"> - <template v-for="unit in targetUnits"> + <template v-for="unit in targetUnits" :key="'radio-' + unit.id"> <input :id="'cw-task-dist-target-unit' + unit.id" type="radio" v-model="selectedTargetUnit" :checked="unit.id === selectedTargetUnitId" :value="unit" - :key="'radio-' + unit.id" :aria-description="unit.element.attributes.title" /> <label @click="selectedTargetUnit = unit" - :key="'label-' + unit.id" :for="'cw-task-dist-target-unit' + unit.id" > <div class="icon"><studip-icon shape="courseware" :size="32" /></div> @@ -176,11 +172,11 @@ type="checkbox" v-model="selectedAutors" :value="user.user_id" - :aria-label=" - $gettextInterpolate($gettext('%{userName} auswählen'), { - userName: user.formattedname, - }, true) - " + :aria-label="$gettext( + '%{userName} auswählen', + { userName: user.formattedname }, + true + )" /> </td> <td>{{ user.formattedname }}</td> @@ -214,11 +210,11 @@ type="checkbox" v-model="selectedGroups" :value="group.id" - :aria-label=" - $gettextInterpolate($gettext('%{groupName} auswählen'), { - groupName: group.name, - }, true) - " + :aria-label="$gettext( + '%{groupName} auswählen', + { groupName: group.name }, + true + )" /> </td> <td>{{ group.name }}</td> @@ -253,6 +249,7 @@ const dateString = (date) => export default { name: 'courseware-tasks-dialog-distribute', + emits: ['newtask'], components: { CoursewareCompanionBox, CoursewareStructuralElementSelector, diff --git a/resources/vue/components/courseware/tasks/EditFeedbackDialog.vue b/resources/vue/components/courseware/tasks/EditFeedbackDialog.vue index a07356dfc68d186a676cbbb31fc78bbd711d13ca..b9f6d16a8bec185a5d92154fae7d9b7ec0522408 100644 --- a/resources/vue/components/courseware/tasks/EditFeedbackDialog.vue +++ b/resources/vue/components/courseware/tasks/EditFeedbackDialog.vue @@ -32,6 +32,7 @@ import CompanionBox from '../layouts/CoursewareCompanionBox.vue'; export default { props: ['content'], + emits: ['close', 'update'], components: { CompanionBox, }, diff --git a/resources/vue/components/courseware/tasks/PagesTaskGroupsIndex.vue b/resources/vue/components/courseware/tasks/PagesTaskGroupsIndex.vue index 5701580d4894e20790de9294ce407a6ceb0f6f43..f57fa8d5500dec29fc91c11701e33937b5879341 100644 --- a/resources/vue/components/courseware/tasks/PagesTaskGroupsIndex.vue +++ b/resources/vue/components/courseware/tasks/PagesTaskGroupsIndex.vue @@ -4,9 +4,9 @@ <CoursewareDashboardStudents v-if="userIsTeacher" /> <CoursewareDashboardTasks v-else /> </div> - <MountingPortal mountTo="#courseware-action-widget" name="sidebar-actions" v-if="userIsTeacher"> + <Teleport to="#courseware-action-widget" name="sidebar-actions" v-if="userIsTeacher"> <CoursewareTasksActionWidget /> - </MountingPortal> + </Teleport> <courseware-companion-overlay /> </div> </template> diff --git a/resources/vue/components/courseware/tasks/PagesTaskGroupsShow.vue b/resources/vue/components/courseware/tasks/PagesTaskGroupsShow.vue index cacd3abf10b334172ec3ce21339c56ea39036e6b..a0ec342e1ca7713cdf9f52f82a2f9639ecf19a0d 100644 --- a/resources/vue/components/courseware/tasks/PagesTaskGroupsShow.vue +++ b/resources/vue/components/courseware/tasks/PagesTaskGroupsShow.vue @@ -1,8 +1,8 @@ <template> <div class="cw-tasks-wrapper"> - <MountingPortal mountTo="#courseware-action-widget" name="sidebar-actions" v-if="userIsTeacher"> + <Teleport to="#courseware-action-widget" name="sidebar-actions" v-if="userIsTeacher"> <CoursewareTasksActionWidget :taskGroup="taskGroup" /> - </MountingPortal> + </Teleport> <div v-if="taskGroup" class="cw-tasks-list"> <ContentBar isContentBar> @@ -237,6 +237,3 @@ export default { }, }; </script> - -<style scoped> -</style> diff --git a/resources/vue/components/courseware/tasks/RenewalDialog.vue b/resources/vue/components/courseware/tasks/RenewalDialog.vue index f08719e22d2d13d17f059a13298545e0052334f5..a8dd83221afc5b7d319ff8967859a5f48e074af5 100644 --- a/resources/vue/components/courseware/tasks/RenewalDialog.vue +++ b/resources/vue/components/courseware/tasks/RenewalDialog.vue @@ -38,6 +38,7 @@ export default { components: { DateInput, }, + emits: ['close', 'update'], data: () => ({ date: null, state: null, diff --git a/resources/vue/components/courseware/tasks/TaskGroup.vue b/resources/vue/components/courseware/tasks/TaskGroup.vue index 541ce7b780ece045a81915efc053bd87d893e158..122cc7e53ece735caf153967f25200253966c211 100644 --- a/resources/vue/components/courseware/tasks/TaskGroup.vue +++ b/resources/vue/components/courseware/tasks/TaskGroup.vue @@ -43,15 +43,17 @@ import TaskItem from './TaskGroupTaskItem.vue'; export default { components: { CompanionBox, TaskItem }, + emits: ['add-feedback', 'edit-feedback', 'solve-renewal'], props: ['taskGroup', 'tasks'], computed: { ...mapGetters({ coursewareContext: 'context', }), actionMenuContext() { - return this.$gettextInterpolate(this.$gettext('Courseware-Aufgabe "%{ taskGroup }"'), { - taskGroup: this.taskGroup.attributes.title, - }); + return this.$gettext( + 'Courseware-Aufgabe "%{ taskGroup }"', + { taskGroup: this.taskGroup.attributes.title } + ); }, }, }; diff --git a/resources/vue/components/courseware/tasks/TaskGroupTaskItem.vue b/resources/vue/components/courseware/tasks/TaskGroupTaskItem.vue index b684f105b658596ab7c7aaab90f13936aaabfce0..eed19ccd2673ed91be80a43af0e4e0f36d0c03cc 100644 --- a/resources/vue/components/courseware/tasks/TaskGroupTaskItem.vue +++ b/resources/vue/components/courseware/tasks/TaskGroupTaskItem.vue @@ -56,11 +56,10 @@ <td class="responsive-hidden"> <span v-if="feedback" - :title=" - $gettextInterpolate($gettext('Feedback geschrieben am: %{ date }'), { - date: getReadableDate(feedback.attributes['chdate']), - }) - " + :title="$gettext( + 'Feedback geschrieben am: %{ date }', + { date: getReadableDate(feedback.attributes['chdate']) } + )" > <studip-icon shape="accept" role="status-green" /> {{ $gettext('Feedback gegeben') }} @@ -84,6 +83,7 @@ import { mapGetters } from 'vuex'; export default { mixins: [taskHelper], + emits: ['add-feedback', 'edit-feedback', 'solve-renewal'], props: ['task', 'taskGroup'], computed: { ...mapGetters({ diff --git a/resources/vue/components/courseware/tasks/TaskGroupsAddSolversDialog.vue b/resources/vue/components/courseware/tasks/TaskGroupsAddSolversDialog.vue index d7db6e19963619749770042803280394fcd9bee0..2e1fe62971c7946f8a41f1d65a33ae104cc2e9f2 100644 --- a/resources/vue/components/courseware/tasks/TaskGroupsAddSolversDialog.vue +++ b/resources/vue/components/courseware/tasks/TaskGroupsAddSolversDialog.vue @@ -41,11 +41,11 @@ v-model="selectedAutors" :disabled="isSolver(user.user_id)" :value="user.user_id" - :aria-label=" - $gettextInterpolate($gettext('%{userName} auswählen'), { - userName: user.formattedname, - }, true) - " + :aria-label="$gettext( + '%{userName} auswählen', + { userName: user.formattedname }, + true + )" /> </td> <td>{{ user.formattedname }}</td> @@ -74,11 +74,11 @@ v-model="selectedGroups" :disabled="isSolver(group.id)" :value="group.id" - :aria-label=" - $gettextInterpolate($gettext('%{groupName} auswählen'), { - groupName: group.name, - }, true) - " + :aria-label="$gettext( + '%{groupName} auswählen', + { groupName: group.name }, + true + )" /> </td> <td>{{ group.name }}</td> @@ -100,6 +100,7 @@ export default { components: { CoursewareCompanion, }, + emits: ['newtask'], data: () => ({ selectedAutors: [], selectedGroups: [], diff --git a/resources/vue/components/courseware/tasks/TaskGroupsModifyDeadlineDialog.vue b/resources/vue/components/courseware/tasks/TaskGroupsModifyDeadlineDialog.vue index 39198af5965358d45db02ae25cf5a9b4e44003a9..5f201e00ebe0e07aba2825cf9cee9346b8368a26 100644 --- a/resources/vue/components/courseware/tasks/TaskGroupsModifyDeadlineDialog.vue +++ b/resources/vue/components/courseware/tasks/TaskGroupsModifyDeadlineDialog.vue @@ -14,7 +14,7 @@ {{ $gettext('Aktuelle Bearbeitungszeit:') }} <StudipDate :date="startDate" /> - <StudipDate :date="endDate" /> - ({{ $gettextInterpolate($gettext('%{ count } Tage'), { count: oldDuration }) }}) + ({{ $gettext('%{ count } Tage', { count: oldDuration }) }}) </p> <div class="formpart"> <label class="studiprequired"> @@ -35,7 +35,7 @@ {{ $gettext('Verlängerte Bearbeitungszeit:') }} <StudipDate :date="startDate" /> - <StudipDate :date="newEndDate" /> - ({{ $gettextInterpolate($gettext('%{ count } Tage'), { count: newDuration }) }}) + ({{ $gettext('%{ count } Tage', { count: newDuration }) }}) </p> </form> </template> diff --git a/resources/vue/components/courseware/toolbar/CoursewareBlockadderItem.vue b/resources/vue/components/courseware/toolbar/CoursewareBlockadderItem.vue index dc9d9293e36ebf23ecbcf4c5a524d86cfdaa1395..a21d9721a408f551b5d0efd5d21a5ae074875abd 100644 --- a/resources/vue/components/courseware/toolbar/CoursewareBlockadderItem.vue +++ b/resources/vue/components/courseware/toolbar/CoursewareBlockadderItem.vue @@ -51,16 +51,16 @@ export default { }, favButtonTitle() { if (this.blockTypeIsFav) { - return this.$gettextInterpolate( - this.$gettext('%{ blockName } Block aus den Favoriten entfernen'), + return this.$gettext( + '%{ blockName } Block aus den Favoriten entfernen', { blockName: this.title } ); } - return this.$gettextInterpolate( - this.$gettext('%{ blockName } Block zu Favoriten hinzufügen'), + return this.$gettext( + '%{ blockName } Block zu Favoriten hinzufügen', { blockName: this.title } - ); + ); } }, methods: { @@ -80,9 +80,9 @@ export default { async addBlock() { if (!this.addInProgress) { this.addInProgress = true; - this.setAdderStorage({ - container: this.blockAdder.container, - section: this.blockAdder.section, + this.setAdderStorage({ + container: this.blockAdder.container, + section: this.blockAdder.section, type: this.type , position: false }); diff --git a/resources/vue/components/courseware/toolbar/CoursewareClipboardItem.vue b/resources/vue/components/courseware/toolbar/CoursewareClipboardItem.vue index 132362628a75b04c901036bdaa5345afde2ef606..3ef18daa5389b3f782a2230d6eb5b9ee564f390f 100644 --- a/resources/vue/components/courseware/toolbar/CoursewareClipboardItem.vue +++ b/resources/vue/components/courseware/toolbar/CoursewareClipboardItem.vue @@ -118,9 +118,9 @@ export default { return menuItems; }, srTitle() { - return this.isBlock ? - this.$gettextInterpolate(this.$gettext(`Block %{name} einfügen`), { name: this.name }) : - this.$gettextInterpolate(this.$gettext(`Abschnitt %{name} einfügen`), { name: this.name }); + return this.isBlock ? + this.$gettext(`Block %{name} einfügen`, { name: this.name }) : + this.$gettext(`Abschnitt %{name} einfügen`, { name: this.name }); } }, methods: { diff --git a/resources/vue/components/courseware/toolbar/CoursewareToolbar.vue b/resources/vue/components/courseware/toolbar/CoursewareToolbar.vue index bbf322c5991ef48f699626b8aec53543749c9a96..2b2047d624025e4ca2b9cd2148a7aad66e7381f2 100644 --- a/resources/vue/components/courseware/toolbar/CoursewareToolbar.vue +++ b/resources/vue/components/courseware/toolbar/CoursewareToolbar.vue @@ -195,7 +195,7 @@ export default { }); this.resetAdderStorage(); }, - beforeDestroy() { + beforeUnmount() { window.removeEventListener('scroll', this.updateToolbarTop); window.removeEventListener('resize', this.onResize); }, @@ -204,10 +204,13 @@ export default { consumeMode(newState) { this.setHideEditLayout(newState); }, - containers(newValue, oldValue) { - if (newValue) { - this.resetAdderStorage(); - } + containers: { + handler(newValue) { + if (newValue) { + this.resetAdderStorage(); + } + }, + deep: true, }, toolbarActive(newState, oldState) { let view = this; diff --git a/resources/vue/components/courseware/toolbar/CoursewareToolbarBlocks.vue b/resources/vue/components/courseware/toolbar/CoursewareToolbarBlocks.vue index 4a95f698dac3ed39f6cee312762c72f9a2c3f6b5..4d8aa1024f1ada6328716d7bf6457a972e7aaaf9 100644 --- a/resources/vue/components/courseware/toolbar/CoursewareToolbarBlocks.vue +++ b/resources/vue/components/courseware/toolbar/CoursewareToolbarBlocks.vue @@ -44,7 +44,7 @@ :reduce="(category) => category.type" v-model="currentFilterCategory" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> <template #no-options> @@ -73,16 +73,17 @@ @end="dropNewBlock($event)" ref="sortables" sectionId="0" + item-key="id" > - <courseware-blockadder-item - v-for="(block, index) in filteredBlockTypes" - :key="index" - :title="block.title" - :type="block.type" - :data-blocktype="block.type" - :description="block.description" - @blockAdded="$emit('blockAdded')" - /> + <template #item="{element}"> + <courseware-blockadder-item + :title="element.title" + :type="element.type" + :data-blocktype="element.type" + :description="element.description" + @blockAdded="$emit('blockAdded')" + /> + </template> </draggable> </div> <courseware-companion-box @@ -117,6 +118,7 @@ export default { required: true, }, }, + emits: ['blockAdded'], setup() { const { categories } = useBlockCategoryManager(); @@ -254,17 +256,18 @@ export default { this.isDragging = true; }, async dropNewBlock(e) { - const target = e.to.__vue__.$attrs; - const blockType = e.item.__vue__.$attrs['data-blocktype']; + // TODO: This seems way to hackish + const targetAttributes = e.to.__vnode.ctx.attrs; + const blockType = e.item.dataset.blocktype; // only execute if dropped in destined list - if (!target.containerId) { + if (!targetAttributes.containerId) { return; } // set chosen container and section and pass block data this.setAdderStorage({ - container: this.containerById({ id: target.containerId }), - section: target.sectionId, + container: this.containerById({ id: targetAttributes.containerId }), + section: targetAttributes.sectionId, type: blockType, position: e.newIndex, }); diff --git a/resources/vue/components/courseware/toolbar/CoursewareToolbarClipboard.vue b/resources/vue/components/courseware/toolbar/CoursewareToolbarClipboard.vue index c6f1e920ddcea3a591777f653275c24a36cfe40d..d11d4fcd93b99f83e0865eb245121265fbc87130 100644 --- a/resources/vue/components/courseware/toolbar/CoursewareToolbarClipboard.vue +++ b/resources/vue/components/courseware/toolbar/CoursewareToolbarClipboard.vue @@ -16,13 +16,14 @@ @end="dropClipboardBlock($event)" ref="clipboardSortables" sectionId="0" + item-key="id" > - <courseware-clipboard-item - v-for="(clipboard, index) in clipboardBlocks" - :key="index" - :clipboard="clipboard" - @inserted="$emit('blockAdded')" - /> + <template #item="{element}"> + <courseware-clipboard-item + :clipboard="element" + @inserted="$emit('blockAdded')" + /> + </template> </draggable> </div> <button class="button trash" @click="clearClipboard('courseware-blocks')"> @@ -50,12 +51,13 @@ :clone="cloneClipboardContainer" @end="dropNewContainer($event)" ref="clipboardContainerSortables" + item-key="id" > - <courseware-clipboard-item - v-for="(clipboard, index) in clipboardContainers" - :key="index" - :clipboard="clipboard" - /> + <template #item="{element}"> + <courseware-clipboard-item + :clipboard="element" + /> + </template> </draggable> </div> <button class="button trash" @click="clearClipboard('courseware-containers')"> @@ -101,6 +103,7 @@ export default { StudipDialog, draggable, }, + emits: ['blockAdded'], props: { toolbarContentHeight: { type: Number, @@ -185,7 +188,7 @@ export default { return original; }, async dropClipboardBlock(e) { - const target = e.to.__vue__.$attrs; + const target = e.to.__vnode.ctx.attrs; // only execute if dropped in destined list if (!target.containerId) { return; @@ -196,7 +199,7 @@ export default { section: target.sectionId, position: e.newIndex, }); - await this.insertItem(e.item.__vue__._data.currentClipboard); + await this.insertItem(e.item.__vnode.ctx.data.currentClipboard); this.resetAdderStorage(); }, cloneClipboardContainer(original) { @@ -222,7 +225,7 @@ export default { // if the container is from the clipboard, insert it via clipboard mixin, else add it via container mixin if (item.clipContainer) { - this.insertItem(e.item.__vue__._data.currentClipboard, e.newIndex); + this.insertItem(e.item.__vnode.ctx.data.currentClipboard, e.newIndex); } else { const data = { type: item.attributes['container-type'], diff --git a/resources/vue/components/courseware/toolbar/CoursewareToolbarContainers.vue b/resources/vue/components/courseware/toolbar/CoursewareToolbarContainers.vue index c5781b24e49164e23b734bcd7ea0bb356bf88b76..dda1d2d004915609e2cc268d6c90cd2a2282b66f 100644 --- a/resources/vue/components/courseware/toolbar/CoursewareToolbarContainers.vue +++ b/resources/vue/components/courseware/toolbar/CoursewareToolbarContainers.vue @@ -2,9 +2,8 @@ <div class="cw-toolbar-containers"> <div class="cw-container-style-selector" role="group" aria-labelledby="cw-containeradder-style"> <p class="sr-only" id="cw-containeradder-style">{{ $gettext('Abschnitt-Stil') }}</p> - <template v-for="style in containerStyles"> + <template v-for="style in containerStyles" :key="style.key + '-input'"> <input - :key="style.key + '-input'" type="radio" name="container-style" :id="'style-' + style.colspan" @@ -12,7 +11,6 @@ :value="style.colspan" /> <label - :key="style.key + '-label'" :for="'style-' + style.colspan" :class="[ selectedContainerStyle === style.colspan ? 'cw-container-style-selector-active' : '', @@ -36,18 +34,19 @@ @start="dragContainerStart($event)" @end="dropNewContainer($event)" ref="containerSortables" + item-key="type" > - <courseware-container-adder-item - v-for="container in containerTypes" - :key="container.type" - :title="container.title" - :type="container.type" - :colspan="selectedContainerStyle" - :description="container.description" - :firstSection="firstSection" - :secondSection="secondSection" - :newPosition="newContainerPosition" - ></courseware-container-adder-item> + <template #item="{element}"> + <courseware-container-adder-item + :title="element.title" + :type="element.type" + :colspan="selectedContainerStyle" + :description="element.description" + :firstSection="firstSection" + :secondSection="secondSection" + :newPosition="newContainerPosition" + ></courseware-container-adder-item> + </template> </draggable> </div> </template> @@ -87,8 +86,8 @@ export default { }, containers() { return this.relatedContainers({ - parent: this.structuralElementById({id: this.$route.params.id}), - relationship: 'containers' + parent: this.structuralElementById({id: this.$route.params.id}), + relationship: 'containers' }); }, newContainerPosition() { @@ -141,7 +140,7 @@ export default { // if the container is from the clipboard, insert it via clipboard mixin, else add it via container mixin if (item.clipContainer) { - this.insertItem(e.item.__vue__._data.currentClipboard, e.newIndex); + this.insertItem(e.item.__node.ctx.data.currentClipboard, e.newIndex); } else { const data = { type: item.attributes['container-type'], diff --git a/resources/vue/components/courseware/unit/CoursewareSharedItems.vue b/resources/vue/components/courseware/unit/CoursewareSharedItems.vue index e68179c715322aa14c156a988890e26e53b5317b..a7de0c91d647deefc4ddd2f6a08e13d3235ee959 100644 --- a/resources/vue/components/courseware/unit/CoursewareSharedItems.vue +++ b/resources/vue/components/courseware/unit/CoursewareSharedItems.vue @@ -27,12 +27,7 @@ </div> <footer> {{ countChildren(element) + 1 }} - <translate - :translate-n="countChildren(element) + 1" - translate-plural="Seiten" - > - Seite - </translate> + {{ $ngettext('Seite', 'Seiten', countChildren(element) + 1) }} </footer> </div> </a> @@ -42,6 +37,7 @@ </template> <script> import { mapGetters } from 'vuex'; +import {$ngettext} from "../../../../assets/javascripts/lib/gettext"; export default { name: 'courseware-shared-items', @@ -52,6 +48,7 @@ export default { }), }, methods: { + $ngettext, getChildStyle(child) { let url = child.relationships?.image?.meta?.['download-url']; @@ -74,7 +71,7 @@ export default { const ownerId = element.relationships.owner.data.id; const owner = this.userById({ id: ownerId }); - return owner.attributes['formatted-name']; + return owner.attributes['formatted-name']; }, countChildren(element) { let data = element.relationships.children.data; @@ -85,4 +82,4 @@ export default { }, }, } -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue index 85379003a12e7f8ead524067f6fbcd7a585a11f4..13725b8584048f2fef7d79e03c4283d9ea74eabb 100644 --- a/resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue +++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogAdd.vue @@ -60,7 +60,7 @@ name="color" > <template #open-indicator="selectAttributes"> - <span v-bind="selectAttributes" + <span v-bind="{ selectAttributes }" ><studip-icon shape="arr_1down" :size="10" /></span> </template> diff --git a/resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue index c7447cea5855cabfb244de836dc7f515b6f84151..260c456111671f9b84849f866ee595135dac11b3 100644 --- a/resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue +++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogCopy.vue @@ -74,7 +74,7 @@ :getOptionLabel="option => option.attributes.title" v-model="selectedRange" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> @@ -94,17 +94,16 @@ <template v-slot:unit> <form class="default" @submit.prevent=""> <fieldset v-if="units.length !== 0" class="radiobutton-set"> - <template v-for="unit in units"> + <template v-for="unit in units" :key="'radio-' + unit.id"> <input :id="'cw-shelf-copy-unit-' + unit.id" type="radio" v-model="selectedUnit" :checked="unit.id === selectedUnitId" :value="unit" - :key="'radio-' + unit.id" :aria-description="unit.element.attributes.title" /> - <label @click="selectedUnit = unit" :key="'label-' + unit.id" :for="'cw-shelf-copy-unit-' + unit.id"> + <label @click="selectedUnit = unit" :for="'cw-shelf-copy-unit-' + unit.id"> <div class="icon"><studip-icon shape="courseware" :size="32"/></div> <div class="text">{{ unit.element.attributes.title }}</div> <studip-icon shape="radiobutton-unchecked" :size="24" class="unchecked" /> @@ -134,7 +133,7 @@ :clearable="false" label="class" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> @@ -367,7 +366,7 @@ export default { this.selectedUnit = null; this.validateSelection(); const slot = this.wizardSlots[0]; - + if (newRid !== '') { slot.valid = true; if (this.source === 'courses' || this.source === 'self') { diff --git a/resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue index 0f9dc518ef65841e6af4ba841a1033be8261d2ec..467c3f381d8a875cd72ddf1ca6ff11b03ebce229 100644 --- a/resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue +++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogImport.vue @@ -43,7 +43,7 @@ :clearable="false" label="class" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes" ><studip-icon shape="arr_1down" :size="10" /></span> diff --git a/resources/vue/components/courseware/unit/CoursewareShelfDialogTopics.vue b/resources/vue/components/courseware/unit/CoursewareShelfDialogTopics.vue index 70745e815807a231311c3ef01755ad3cef835021..ce18cbf8a74b6940eba42aa080a2fd478cedb6c8 100644 --- a/resources/vue/components/courseware/unit/CoursewareShelfDialogTopics.vue +++ b/resources/vue/components/courseware/unit/CoursewareShelfDialogTopics.vue @@ -65,7 +65,7 @@ <label> {{ $gettext('Farbe') }} <studip-select v-model="color" :options="colors" :reduce="(color) => color.class" label="class"> - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> <template #no-options> diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItem.vue b/resources/vue/components/courseware/unit/CoursewareUnitItem.vue index f2c4d4a73f589c8eaa1cd47903cb0ac194cce25a..564747a19d672c729c711562151b922b62d2c287 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItem.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItem.vue @@ -35,11 +35,10 @@ v-if="hasFeedbackEntries" :amount="feedbackAverage" :size="16" - :title=" - $gettextInterpolate($gettext('Lernmaterial wurde mit %{avg} Sternen bewertet'), { - avg: feedbackAverage, - }) - " + :title="$gettext( + 'Lernmaterial wurde mit %{avg} Sternen bewertet', + { avg: feedbackAverage } + )" /> <studip-five-stars v-else @@ -74,11 +73,11 @@ <studip-dialog v-if="showDeleteDialog" :title="$gettext('Lernmaterial löschen')" - :question=" - $gettextInterpolate($gettext('Möchten Sie das Lernmaterial %{ unitTitle } wirklich löschen?'), { - unitTitle: title, - }, true) - " + :question="$gettext( + 'Möchten Sie das Lernmaterial %{ unitTitle } wirklich löschen?', + { unitTitle: title }, + true + )" height="200" @confirm="executeDelete" @close="closeDeleteDialog" @@ -157,6 +156,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-unit-item', + emits: ['unit-keydown'], components: { CoursewareTile, CoursewareUnitItemDialogExport, @@ -322,9 +322,10 @@ export default { if (!this.userIsTeacher) { if (this.unit.attributes.visible === 'period') { info.icon = 'date'; - info.text = this.$gettextInterpolate(this.$gettext('Sichtbar bis zum %{end}'), { - end: this.permissionVisibleEndDate, - }); + info.text = this.$gettext( + 'Sichtbar bis zum %{end}', + { end: this.permissionVisibleEndDate } + ); return info; } @@ -343,12 +344,10 @@ export default { info.text = this.$gettext('Sichtbar für alle'); } else { const users = this.unit.attributes['visible-approval'].length; - info.text = this.$gettextInterpolate( - this.$ngettext( - 'Sichtbar für einen Studierenden', - 'Sichtbar für %{count} Studierende', - users - ), + info.text = this.$ngettext( + 'Sichtbar für einen Studierenden', + 'Sichtbar für %{count} Studierende', + users, { count: users } ); if (users === 0) { @@ -363,8 +362,10 @@ export default { info.text = this.$gettext('Sichtbar für alle'); } else { const groups = this.unit.attributes['visible-approval'].length; - info.text = this.$gettextInterpolate( - this.$ngettext('Sichtbar für eine Gruppe', 'Sichtbar für %{count} Gruppen', groups), + info.text = this.$ngettext( + 'Sichtbar für eine Gruppe', + 'Sichtbar für %{count} Gruppen', + groups, { count: groups } ); if (groups === 0) { @@ -382,8 +383,8 @@ export default { break; case 'period': { info.icon = 'date'; - info.title = this.$gettextInterpolate( - this.$gettext('Für %{persons} sichtbar vom %{start} bis zum %{end}'), + info.title = this.$gettext( + 'Für %{persons} sichtbar vom %{start} bis zum %{end}', { start: this.permissionVisibleStartDate, end: this.permissionVisibleEndDate, @@ -428,9 +429,10 @@ export default { if (this.unit.attributes['can-edit-content']) { info.icon = 'edit'; if (this.unit.attributes.writable === 'period') { - info.text = this.$gettextInterpolate(this.$gettext('Bearbeitbar bis zum %{end}'), { - end: this.permissionWritableEndDate, - }); + info.text = this.$gettext( + 'Bearbeitbar bis zum %{end}', + { end: this.permissionWritableEndDate } + ); } else { info.text = this.$gettext('Bearbeitbar'); } @@ -451,13 +453,14 @@ export default { } info.icon = 'edit'; if (this.unit.attributes.writable === 'always') { - info.text = this.$gettextInterpolate(this.$gettext('Bearbeitbar für %{persons} '), { - persons: this.getPermissionPersons('writable-approval'), - }); + info.text = this.$gettext( + 'Bearbeitbar für %{persons}', + { persons: this.getPermissionPersons('writable-approval') } + ); } if (this.unit.attributes.writable === 'period') { - info.title = this.$gettextInterpolate( - this.$gettext('Für %{persons} bearbeitbar vom %{start} bis zum %{end}'), + info.title = this.$gettext( + 'Für %{persons} bearbeitbar vom %{start} bis zum %{end}', { start: this.permissionWritableStartDate, end: this.permissionWritableEndDate, @@ -575,8 +578,10 @@ export default { return this.$gettext('alle'); } else { const users = this.unit.attributes[type].length; - return this.$gettextInterpolate( - this.$ngettext('einen Studierenden', '%{count} Studierende', users), + return this.$ngettext( + 'einen Studierenden', + '%{count} Studierende', + users, { count: users } ); } @@ -586,9 +591,12 @@ export default { return this.$gettext('alle'); } else { const groups = this.unit.attributes[type].length; - return this.$gettextInterpolate(this.$ngettext('eine Gruppe', '%{count} Gruppen', groups), { - count: groups, - }); + return this.$ngettext( + 'eine Gruppe', + '%{count} Gruppen', + groups, + { count: groups } + ); } } } diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue index 08f0a21fbedd687da9fdf4a0f67fa4ad578f37c4..c606073e68b1cc4b2df0635db81432b8ed06950f 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogExport.vue @@ -12,13 +12,13 @@ <template v-slot:dialogContent> <courseware-companion-box v-show="!exportRunning" - :msgCompanion="$gettextInterpolate($gettext('Export des Lernmaterials: %{title}'), {title: title})" + :msgCompanion="$gettext('Export des Lernmaterials: %{title}', { title })" mood="curious" /> <courseware-companion-box v-show="exportRunning" - :msgCompanion="$gettextInterpolate($gettext('%{title} wird exportiert, bitte haben sie einen Moment Geduld...'), {title: title})" + :msgCompanion="$gettext('%{title} wird exportiert, bitte haben sie einen Moment Geduld...', { title })" mood="pointing" /> <div v-show="exportRunning" class="cw-import-zip"> @@ -48,6 +48,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-unit-item-dialog-export', mixins: [CoursewareExport], + emits: ['close'], components: { CoursewareCompanionBox, }, @@ -67,7 +68,7 @@ export default { exportState: 'exportState', instanceById: 'courseware-instances/byId', structuralElementById: 'courseware-structural-elements/byId', - userIsTeacher: 'userIsTeacher', + userIsTeacher: 'userIsTeacher', }), instance() { if (this.inCourseContext) { @@ -75,7 +76,7 @@ export default { } else { return this.instanceById({id: 'user_' + this.context.id + '_' + this.unit.id}); } - + }, inCourseContext() { return this.context.type === 'courses'; @@ -103,7 +104,7 @@ export default { } this.exportRunning = true; - + this.setExportState(this.$gettext('Lade Einstellungen')); await this.loadUnitInstance(); this.setExportState(''); @@ -129,4 +130,4 @@ export default { await this.loadUnitInstance(); } } -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue index 572e171fc28eddfe3f5e72c79a4a7f2d4f452c92..a188b44adac0ddb3a9ab18ef43aed613bf608ca4 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogLayout.vue @@ -75,7 +75,7 @@ label="class" class="cw-vs-select" > - <template #open-indicator="selectAttributes"> + <template #open-indicator="{ selectAttributes }"> <span v-bind="selectAttributes"><studip-icon shape="arr_1down" :size="10" /></span> </template> <template #no-options> {{ $gettext('Es steht keine Auswahl zur Verfügung') }}. </template> @@ -112,6 +112,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-unit-item-dialog-layout', + emits: ['close'], components: { CoursewareCompanionBox, StockImageSelector, diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissionScope.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissionScope.vue index 46a85c5c2cd9e0d86e5a3ab9ebe86c0caea65ec1..deed35f29537b00d908d3da56e44ae4d24caf5a0 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissionScope.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissionScope.vue @@ -17,6 +17,7 @@ import { mapActions } from 'vuex'; export default { name: 'courseware-unit-item-dialog-permission-scope', + emits: ['close', 'switch'], props: { unit: { type: Object, diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissions.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissions.vue index 86ac64128522a83e2c1de77e8df88d87ee434bf3..6a96d90cf6a18326e6aeae038de9b6addda056ad 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissions.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogPermissions.vue @@ -255,6 +255,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-unit-item-dialog-permissions', + emits: ['close'], components: { CoursewareCompanionBox, Datepicker, diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue index 14c8d304d935564b5fb666da0e08333e8bcbaa4a..f4f7a22ab2dbd90d0ffcce6fb9e92d36f11d601e 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItemDialogSettings.vue @@ -219,6 +219,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'courseware-unit-item-dialog-settings', + emits: ['close'], components: { CoursewareFileChooser, StudipProgressIndicator, diff --git a/resources/vue/components/courseware/unit/CoursewareUnitItems.vue b/resources/vue/components/courseware/unit/CoursewareUnitItems.vue index 8f747bfc445fbb07382dbbb1129a467362984698..def2d1712f9886867a5298c8ae9cbeec62b7ee72 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitItems.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitItems.vue @@ -3,8 +3,8 @@ <h2 v-if="!inCourseContext && hasUnits">{{ $gettext('Persönliche Lernmaterialien') }}</h2> <template v-if="hasUnits"> <ol v-if="(!userIsTeacher && inCourseContext) || units.length === 1" class="cw-tiles"> - <template v-for="unit in units"> - <courseware-unit-item :key="unit.id" :unit="unit" :handle="false"/> + <template v-for="unit in units" :key="unit.id"> + <courseware-unit-item :unit="unit" :handle="false"/> </template> </ol> <template v-else> @@ -13,23 +13,24 @@ {{ $gettext('Drücken Sie die Leertaste oder Entertaste, um neu anzuordnen.') }} </span> <draggable + v-bind="dragOptions" tag="ol" role="listbox" v-model="unitList" - v-bind="dragOptions" handle=".cw-tile-handle" group="units" @start="isDragging = true" @end="dropUnit" ref="sortables" class="cw-tiles" + item-key="id" > - <courseware-unit-item - v-for="unit in unitList" - :key="unit.id" - :unit="unit" - @unit-keydown="keyHandler($event, unit.id)" - /> + <template #item="{element}"> + <courseware-unit-item + :unit="element" + @unit-keydown="keyHandler($event, element.id)" + /> + </template> </draggable> </template> </template> @@ -159,13 +160,15 @@ export default { } else { this.keyboardSelected = { id: unitId, title: this.getUnitTitle(unitId) }; const index = this.unitList.findIndex((unit) => unit.id === unitId); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - 'Lernmaterial %{unitTitle} ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. ' + - 'Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste oder ' + - 'Entertaste zum Ablegen, die Escape-Taste zum Abbrechen.' - ), - { unitTitle: this.keyboardSelected.title, pos: index + 1, listLength: this.unitList.length } + this.assistiveLive = this.$gettext( + 'Lernmaterial %{unitTitle} ausgewählt. Aktuelle Position in der Liste: %{pos} von %{listLength}. ' + + 'Drücken Sie die Aufwärts- und Abwärtspfeiltasten, um die Position zu ändern, die Leertaste oder ' + + 'Entertaste zum Ablegen, die Escape-Taste zum Abbrechen.', + { + unitTitle: this.keyboardSelected.title, + pos: index + 1, + listLength: this.unitList.length + } ); } break; @@ -189,8 +192,8 @@ export default { } }, abortKeyboardSorting() { - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Lernmaterial %{unitTitle}, Neuordnung abgebrochen.'), + this.assistiveLive = this.$gettext( + 'Lernmaterial %{unitTitle}, Neuordnung abgebrochen.', { unitTitle: this.keyboardSelected.title } ); this.keyboardSelected = null; @@ -198,11 +201,13 @@ export default { }, storeKeyboardSorting() { const index = this.unitList.findIndex((unit) => unit.id === this.keyboardSelected.id); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - 'Lernmaterial %{unitTitle}, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.' - ), - { unitTitle: this.keyboardSelected.title, pos: index + 1, listLength: this.unitList.length } + this.assistiveLive = this.$gettext( + 'Lernmaterial %{unitTitle}, abgelegt. Endgültige Position in der Liste: %{pos} von %{listLength}.', + { + unitTitle: this.keyboardSelected.title, + pos: index + 1, + listLength: this.unitList.length + } ); this.keyboardSelected = null; this.dropUnit(); @@ -213,11 +218,13 @@ export default { const newPos = currentIndex - 1; this.unitList.splice(newPos, 0, this.unitList.splice(currentIndex, 1)[0]); this.focusHandle(unitId); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - 'Lernmaterial %{unitTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}.' - ), - { unitTitle: this.keyboardSelected.title, pos: newPos + 1, listLength: this.unitList.length } + this.assistiveLive = this.$gettext( + 'Lernmaterial %{unitTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + unitTitle: this.keyboardSelected.title, + pos: newPos + 1, + listLength: this.unitList.length + } ); } }, @@ -227,11 +234,13 @@ export default { const newPos = currentIndex + 1; this.unitList.splice(newPos, 0, this.unitList.splice(currentIndex, 1)[0]); this.focusHandle(unitId); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext( - 'Lernmaterial %{unitTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}.' - ), - { unitTitle: this.keyboardSelected.title, pos: newPos + 1, listLength: this.unitList.length } + this.assistiveLive = this.$gettext( + 'Lernmaterial %{unitTitle}. Aktuelle Position in der Liste: %{pos} von %{listLength}.', + { + unitTitle: this.keyboardSelected.title, + pos: newPos + 1, + listLength: this.unitList.length + } ); } }, @@ -245,9 +254,12 @@ export default { this.initCurrentData(); }, watch: { - units(newState) { - this.initCurrentData(); + units: { + handler(newState) { + this.initCurrentData(); + }, + deep: true }, - }, + } }; </script> diff --git a/resources/vue/components/courseware/unit/CoursewareUnitProgress.vue b/resources/vue/components/courseware/unit/CoursewareUnitProgress.vue index 31c6c01d3a7eb37717d3c058c0c555c23524b4ee..9d21d4cd76baf1b670f256432358abebab76bba1 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitProgress.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitProgress.vue @@ -17,7 +17,7 @@ <h1> <a :href="chapterUrl" - :title="$gettextInterpolate('%{ pageTitle } öffnen', { pageTitle: selected.name }, true)" + :title="$gettext('%{ pageTitle } öffnen', { pageTitle: selected.name }, true)" > {{ selected.name }} </a> diff --git a/resources/vue/components/courseware/unit/CoursewareUnitProgressItem.vue b/resources/vue/components/courseware/unit/CoursewareUnitProgressItem.vue index b83a69289841360bd5b7c4af14e55d30835a8d93..c0614c193f5145a68b6e6ad627839277dd8c5f93 100644 --- a/resources/vue/components/courseware/unit/CoursewareUnitProgressItem.vue +++ b/resources/vue/components/courseware/unit/CoursewareUnitProgressItem.vue @@ -1,5 +1,5 @@ <template> - <a + <a href="#" class="cw-unit-progress-item" :title="name" @@ -19,6 +19,7 @@ import CoursewareProgressCircle from './CoursewareProgressCircle.vue'; export default { name: 'courseware-unit-progress-item', + emits: ['selectChapter'], components: { CoursewareProgressCircle, }, diff --git a/resources/vue/components/courseware/widgets/CoursewareAdminActionWidget.vue b/resources/vue/components/courseware/widgets/CoursewareAdminActionWidget.vue index 6c02699650e97cd40ddb8caf91c7e5f88ea5d156..78e529ce61f3b4291e0d9a256c6f2343a66b87b3 100644 --- a/resources/vue/components/courseware/widgets/CoursewareAdminActionWidget.vue +++ b/resources/vue/components/courseware/widgets/CoursewareAdminActionWidget.vue @@ -2,7 +2,7 @@ <ul class="widget-list widget-links cw-action-widget"> <li v-if="templatesView" class="cw-action-widget-add"> <a href="#" @click.prevent="addTemplate"> - <translate>Vorlage hinzufügen</translate> + {{ $gettext('Vorlage hinzufügen') }} </a> </li> </ul> diff --git a/resources/vue/components/courseware/widgets/CoursewareAdminViewWidget.vue b/resources/vue/components/courseware/widgets/CoursewareAdminViewWidget.vue index 81a80715e37198c9094cbd4c3b81e22b170f8d52..aad266d0dace17d1d6a84e379a6febd264020c98 100644 --- a/resources/vue/components/courseware/widgets/CoursewareAdminViewWidget.vue +++ b/resources/vue/components/courseware/widgets/CoursewareAdminViewWidget.vue @@ -2,7 +2,7 @@ <ul class="widget-list widget-links sidebar-views cw-view-widget"> <li :class="{ active: templatesView }"> <a href="#" @click.prevent="setTemplatesView"> - <translate>Vorlagen</translate> + {{ $gettext('Vorlagen') }} </a> </li> </ul> diff --git a/resources/vue/components/feedback/FeedbackCreateDialog.vue b/resources/vue/components/feedback/FeedbackCreateDialog.vue index 204254c395aef2129e149e02c2fc2d72de43f243..865cffd100498a86772e838b701ebe073fb8c9b5 100644 --- a/resources/vue/components/feedback/FeedbackCreateDialog.vue +++ b/resources/vue/components/feedback/FeedbackCreateDialog.vue @@ -37,10 +37,11 @@ </template> <script> -import { mapActions, mapGetters } from 'vuex'; +import { mapActions } from 'vuex'; export default { name: 'feedback-create-dialog', + emits: ['close', 'created'], props: { defaultQuestion: { type: String, diff --git a/resources/vue/components/feedback/FeedbackDialog.vue b/resources/vue/components/feedback/FeedbackDialog.vue index e432b1b4354d32e68d3bdc6dc25950e311db4dbf..1c15b843a981ea719b1523dd1a4dcbb2d5e8ec77 100644 --- a/resources/vue/components/feedback/FeedbackDialog.vue +++ b/resources/vue/components/feedback/FeedbackDialog.vue @@ -119,6 +119,7 @@ export default { FeedbackFiveStarsHistogram, StudipProgressIndicator, }, + emits: ['close', 'deleted'], props: { feedbackElementId: { type: Number, diff --git a/resources/vue/components/feedback/FeedbackElementUpdate.vue b/resources/vue/components/feedback/FeedbackElementUpdate.vue index d9706de490f66e9103667583e68c9a772f728a37..3d0c42b7bb32f3ce1271cd90f8b87e226bf50d3a 100644 --- a/resources/vue/components/feedback/FeedbackElementUpdate.vue +++ b/resources/vue/components/feedback/FeedbackElementUpdate.vue @@ -24,6 +24,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'feedback-element-update', + emits: ['cancel', 'submit'], props: { feedbackElementId: { type: Number, diff --git a/resources/vue/components/feedback/FeedbackEntryBox.vue b/resources/vue/components/feedback/FeedbackEntryBox.vue index 0400c9d25a20cc6784ca806aa5146e9d5f01a57a..bd68a8fef193ad4e24a053d0fcfe46239c8e3d4b 100644 --- a/resources/vue/components/feedback/FeedbackEntryBox.vue +++ b/resources/vue/components/feedback/FeedbackEntryBox.vue @@ -27,6 +27,7 @@ export default { components: { StudipFiveStars, }, + emits: ['delete', 'edit'], props: { entry: { type: Object, diff --git a/resources/vue/components/feedback/FeedbackEntryCreate.vue b/resources/vue/components/feedback/FeedbackEntryCreate.vue index 5735d45738776dfd332eb70d4f0b2ab19df298a0..7833a64b6650461fd7ddfbc941ce00cb18e64b56 100644 --- a/resources/vue/components/feedback/FeedbackEntryCreate.vue +++ b/resources/vue/components/feedback/FeedbackEntryCreate.vue @@ -16,7 +16,7 @@ <button v-if="hasEntry" class="button cancel" @click="$emit('cancel')"> {{ $gettext('Abbrechen') }} </button> - + </div> </div> </template> @@ -30,6 +30,7 @@ export default { components: { StudipFiveStarsInput, }, + emits: ['cancel', 'submit'], props: { feedbackElement: { type: Object || null, @@ -82,7 +83,7 @@ export default { author: { data: { id: this.currentUser.id, - type: 'users' + type: 'users' } } }, @@ -111,4 +112,4 @@ export default { } }, }; -</script> \ No newline at end of file +</script> diff --git a/resources/vue/components/feedback/FeedbackFiveStarsHistogram.vue b/resources/vue/components/feedback/FeedbackFiveStarsHistogram.vue index b40245276ba41252d0dd1cb20f763b86be96e52f..f66653136da8be6082aa19c45a142c5f18f232f5 100644 --- a/resources/vue/components/feedback/FeedbackFiveStarsHistogram.vue +++ b/resources/vue/components/feedback/FeedbackFiveStarsHistogram.vue @@ -7,11 +7,12 @@ </p> <studip-five-stars :amount="average" /> <p class="total"> - {{ - $gettextInterpolate($ngettext('%{n} Bewertung', '%{n} Bewertungen', entries.length), { - n: entries.length, - }) - }} + {{ $ngettext( + '%{n} Bewertung', + '%{n} Bewertungen', + entries.length, + { n: entries.length } + ) }} </p> </div> <div class="five-stars-histogram-chart" v-if="ratings"> diff --git a/resources/vue/components/feedback/StudipFiveStarsInput.vue b/resources/vue/components/feedback/StudipFiveStarsInput.vue index 6fa95f09ce8602f13654767669dada90ba1660d1..73448528f55a14c5734aa8c7de8953958c8d8917 100644 --- a/resources/vue/components/feedback/StudipFiveStarsInput.vue +++ b/resources/vue/components/feedback/StudipFiveStarsInput.vue @@ -4,16 +4,12 @@ <studip-icon :shape="getShape(i)" :size="size" - :alt=" - $gettextInterpolate( - $ngettext( - 'auswählen, um mit einem Stern zu bewerten.', - 'auswählen, um mit %{i} Sternen zu bewerten.', - i - ), - { i: i } - ) - " + :alt="$ngettext( + 'auswählen, um mit einem Stern zu bewerten.', + 'auswählen, um mit %{i} Sternen zu bewerten.', + i, + { i } + )" /> </button> </div> @@ -25,8 +21,9 @@ export default { components: { StudipIcon, }, + emits: ['update:model-value'], props: { - value: { + modelValue: { type: Number, }, size: { @@ -41,10 +38,10 @@ export default { }, methods: { setValue(val) { - this.$emit('input', val); + this.$emit('update:model-value', val); }, getShape(pos) { - return pos <= this.value ? 'star' : 'star-empty'; + return pos <= this.modelValue ? 'star' : 'star-empty'; }, }, }; diff --git a/resources/vue/components/file-chooser/FileChooserBox.vue b/resources/vue/components/file-chooser/FileChooserBox.vue index 0a3896223868a16b89550d680dbe05df93ec81ad..38ce9924f1648634f349ec17511678b3a3047d79 100644 --- a/resources/vue/components/file-chooser/FileChooserBox.vue +++ b/resources/vue/components/file-chooser/FileChooserBox.vue @@ -72,6 +72,7 @@ export default { FileChooserToolbar, StudipProgressIndicator, }, + emits: ['selectId'], props: { excludedFolderTypes: { type: Array, default: () => [] }, }, diff --git a/resources/vue/components/file-chooser/FileChooserDialog.vue b/resources/vue/components/file-chooser/FileChooserDialog.vue index 2b21f5188c2bae62a44f93f50907a2ecdc7337ad..49bff431389bd25516f47dcc74b5ac3f9c483fbb 100644 --- a/resources/vue/components/file-chooser/FileChooserDialog.vue +++ b/resources/vue/components/file-chooser/FileChooserDialog.vue @@ -56,6 +56,7 @@ export default { FileChooserBox, FileChooserTree, }, + emits: ['close', 'selected'], props: { selectable: { type: String, diff --git a/resources/vue/components/file-chooser/FileChooserFileItem.vue b/resources/vue/components/file-chooser/FileChooserFileItem.vue index 90c2f397d46e432c4640ce1d65b5324732a0f04f..e7d1794f82267036c4170b3bfcff06af48c14fca 100644 --- a/resources/vue/components/file-chooser/FileChooserFileItem.vue +++ b/resources/vue/components/file-chooser/FileChooserFileItem.vue @@ -29,6 +29,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'file-chooser-file-item', + emits: ['selectId'], props: { file: { type: Object, diff --git a/resources/vue/components/file-chooser/FileChooserFolderItem.vue b/resources/vue/components/file-chooser/FileChooserFolderItem.vue index 116f582458637ac511e8141a23466a0f8e05da6f..f3784f481d753919e399893e63c6899e078b0ba8 100644 --- a/resources/vue/components/file-chooser/FileChooserFolderItem.vue +++ b/resources/vue/components/file-chooser/FileChooserFolderItem.vue @@ -77,9 +77,12 @@ export default { }, folderSize() { const length = this.folderSubfolderCounter + this.folderFilesCounter; - return this.$gettextInterpolate(this.$ngettext('%{length} Objekt', '%{length} Objekte', length), { - length: length, - }); + return this.$ngettext( + '%{length} Objekt', + '%{length} Objekte', + length, + { length: length } + ); }, }, methods: { diff --git a/resources/vue/components/file-chooser/FileChooserTable.vue b/resources/vue/components/file-chooser/FileChooserTable.vue index ad7363dc9e6d5e5e03d3bd28c39381471daca632..5606361e1fc2675d11ad879f3c8fff8cdbd70c3e 100644 --- a/resources/vue/components/file-chooser/FileChooserTable.vue +++ b/resources/vue/components/file-chooser/FileChooserTable.vue @@ -58,6 +58,7 @@ export default { fileChooserFileItem, fileChooserFolderItem, }, + emits: ['selectId'], props: { files: { type: Array, diff --git a/resources/vue/components/file-chooser/FileChooserToolbar.vue b/resources/vue/components/file-chooser/FileChooserToolbar.vue index 4f3053e94288876d5177c8052fa333d6dbc70e2a..6f8442b8fd6263e785d88e472a8589780fbc4b78 100644 --- a/resources/vue/components/file-chooser/FileChooserToolbar.vue +++ b/resources/vue/components/file-chooser/FileChooserToolbar.vue @@ -46,6 +46,7 @@ import { mapActions, mapGetters } from 'vuex'; export default { name: 'file-chooser-toolbar', + emits: ['fileAdded', 'folderAdded'], data() { return { showFolderAdder: false, diff --git a/resources/vue/components/form_inputs/CalendarPermissionsTable.vue b/resources/vue/components/form_inputs/CalendarPermissionsTable.vue index e507adce1e37f649b34426cc7e76fc0c1819c161..59130580833fd16e78b3a010cf154c188c83426c 100644 --- a/resources/vue/components/form_inputs/CalendarPermissionsTable.vue +++ b/resources/vue/components/form_inputs/CalendarPermissionsTable.vue @@ -28,19 +28,20 @@ <td> <input type="checkbox" :name="name + '_write_permissions[]'" :value="user.id" v-model="user.write_permissions" - :aria-label="$gettextInterpolate( - $gettext('Schreibzugriff für %{name}'), + :aria-label="$gettext( + 'Schreibzugriff für %{name}', {name: user.name}, true )"> </td> <td class="actions"> <studip-icon shape="trash" aria-role="button" @click="removeContact(user.id)" - :title="$gettextInterpolate( - $gettext('Kalender nicht mehr mit %{name} teilen'), + :title="$gettext( + 'Kalender nicht mehr mit %{name} teilen', {name: user.name}, true - )"></studip-icon> + )" + ></studip-icon> </td> </tr> </tbody> diff --git a/resources/vue/components/form_inputs/CaptchaInput.vue b/resources/vue/components/form_inputs/CaptchaInput.vue index 1ace43ddc42b04d15d12d0cc59de5e69f392a38d..a30cdca65d01efa1f4062d13692af47d5b5b69f9 100644 --- a/resources/vue/components/form_inputs/CaptchaInput.vue +++ b/resources/vue/components/form_inputs/CaptchaInput.vue @@ -10,6 +10,7 @@ import { $gettext } from '../../../assets/javascripts/lib/gettext'; export default { name: 'CaptchaInput', + emits: ['update:model-value'], props: { name: { type: String, @@ -44,7 +45,7 @@ export default { this.$refs.widget.addEventListener('statechange', (ev) => { if (ev.detail.state === 'verified') { - this.$emit('input', ev.detail.payload); + this.$emit('update:model-value', ev.detail.payload); } }) }); diff --git a/resources/vue/components/form_inputs/DateListInput.vue b/resources/vue/components/form_inputs/DateListInput.vue index d77c993454fb949e279b8c95b6e50da2a049a107..48cf05c328da56b26a87d0b16e5bca55bf441115 100644 --- a/resources/vue/components/form_inputs/DateListInput.vue +++ b/resources/vue/components/form_inputs/DateListInput.vue @@ -2,7 +2,7 @@ <div class="formpart"> <div class="sr-only" aria-live="polite" ref="list_message_field"></div> <ul> - <li v-for="date in selected_date_list" v-bind="selected_date_list" :key="getISODate(date)"> + <li v-for="date in selected_date_list" :key="getISODate(date)"> <input type="hidden" :name="input_name + '[]'" :value="getISODate(date)"> <studip-date-time :timestamp="Math.floor(date.getTime() / 1000)" :date_only="true"></studip-date-time> <studip-icon shape="trash" :title="$gettext('Löschen')" @click="removeDate(date)" @@ -22,11 +22,11 @@ <script> import StudipDateTime from "../StudipDateTime.vue"; -import {$gettext, $gettextInterpolate} from "@/assets/javascripts/lib/gettext"; export default { name: "date-list-input", components: {StudipDateTime}, + emits: ['selected_date_list', 'selected_date_value'], props: { name: { type: String, @@ -80,14 +80,14 @@ export default { } let reformatted_date = date_parts[2] + '-' + date_parts[1] + '-' + date_parts[0]; this.selected_date_list.push(new Date(reformatted_date)); - this.$refs.list_message_field.innerText = $gettextInterpolate($gettext('Datum %{date} hinzugefügt'), {date: this.selected_date_value}); + this.$refs.list_message_field.innerText = this.$gettext('Datum %{date} hinzugefügt', {date: this.selected_date_value}); }, removeDate(date) { this.selected_date_list = this.selected_date_list.filter(d => d !== date); - this.$refs.list_message_field.innerText = $gettextInterpolate( - $gettext('Datum %{date} entfernt'), - {date: STUDIP.DateTime.getStudipDate(date, false, true)} + this.$refs.list_message_field.innerText = this.$gettext( + 'Datum %{date} entfernt', + { date: STUDIP.DateTime.getStudipDate(date, false, true) } ); }, getISODate(date) { diff --git a/resources/vue/components/form_inputs/DayOfWeekSelect.vue b/resources/vue/components/form_inputs/DayOfWeekSelect.vue index c28ddb6db4a435f3c4dbb7c666ebe952dcd9eded..0f8792c49b2754b53d353b4f8e5b18337c765179 100644 --- a/resources/vue/components/form_inputs/DayOfWeekSelect.vue +++ b/resources/vue/components/form_inputs/DayOfWeekSelect.vue @@ -31,6 +31,7 @@ <script> export default { name: "day-of-week-select", + emits: ['selected_value'], props: { name: { type: String, diff --git a/resources/vue/components/form_inputs/FileUpload.vue b/resources/vue/components/form_inputs/FileUpload.vue index b512c026a20bed7711774d42478faf4a7b808fad..d0b159e4c9c53a80d6078e47ef08a01522a5ecf2 100644 --- a/resources/vue/components/form_inputs/FileUpload.vue +++ b/resources/vue/components/form_inputs/FileUpload.vue @@ -21,7 +21,7 @@ {{ $gettext('Eine Datei gewählt') }} </template> <template v-else> - {{ $gettextInterpolate($gettext('%{number} Dateien gewählt'), { number: selectedFiles.length }) }} + {{ $gettext('%{number} Dateien gewählt', { number: selectedFiles.length }) }} </template> </div> <input type="file" @@ -142,19 +142,19 @@ export default { } }, getTextualFileSize(bytes) { - let unit = ''; - let context = {size: bytes}; if (bytes < 1024) { - unit = this.$gettext('%{size} B'); - } else if (bytes < 1024 * 1024) { - unit = this.$gettext('%{size} KB'); - context.size = (bytes / 1024).toFixed(2); - } else { - unit = this.$gettext('%{size} MB'); - context.size = (bytes / (1024 * 1024)).toFixed(2); + return this.$gettext('%{size} B', {size: bytes}); } - return this.$gettextInterpolate(unit, context); + if (bytes < 1024 * 1024) { + return this.$gettext('%{size} KB', { + size: (bytes / 1024).toFixed(2) + }); + } + + return this.$gettext('%{size} MB', { + size: (bytes / (1024 * 1024)).toFixed(2) + }); }, openFileSelect() { this.$refs.files.click(); diff --git a/resources/vue/components/form_inputs/MyCoursesColouredTable.vue b/resources/vue/components/form_inputs/MyCoursesColouredTable.vue index fe67db55661b5670712b6b5b2f1ea5430d2d4d33..d8431dd99993d4e49af5a846c1bca786c26f4b06 100644 --- a/resources/vue/components/form_inputs/MyCoursesColouredTable.vue +++ b/resources/vue/components/form_inputs/MyCoursesColouredTable.vue @@ -42,7 +42,7 @@ <input type="hidden" :name="`${name}_course_ids[${course.id}]`" value="0"> <input type="checkbox" :name="`${name}_course_ids[${course.id}]`" value="1" :checked="selected_course_id_list.includes(course.id)" - :title="$gettextInterpolate($gettext('%{course} auswählen'), {course: course.name}, true)"> + :title="$gettext('%{course} auswählen', {course: course.name}, true)"> </td> </tr> <tr v-if="loadedSemesters.includes(semester_id) && courses.length === 0"> diff --git a/resources/vue/components/form_inputs/QuicksearchListInput.vue b/resources/vue/components/form_inputs/QuicksearchListInput.vue index 4a3e21c4cd3af36a6958ac72b77c24bb6199bc21..eb6c3b87028bb0a83200964ffe6745bce7e1476f 100644 --- a/resources/vue/components/form_inputs/QuicksearchListInput.vue +++ b/resources/vue/components/form_inputs/QuicksearchListInput.vue @@ -2,7 +2,7 @@ <div> <quicksearch :searchtype="searchtype" :autocomplete="autocomplete" - @input="addElement"></quicksearch> + @update:model-value="addElement"></quicksearch> <table v-if="elements.length > 0" ref="results" class="default"> <tbody> <tr v-for="(element, index) in elements" @@ -52,7 +52,7 @@ export default { }, data() { return { - elements: [] + elements: [], } }, computed: { diff --git a/resources/vue/components/form_inputs/RepetitionInput.vue b/resources/vue/components/form_inputs/RepetitionInput.vue index 2a265b1d52c3af40441beb7a81412027d9f7a432..ab033bd8c38d3534448980b2416bb60bc5fa534d 100644 --- a/resources/vue/components/form_inputs/RepetitionInput.vue +++ b/resources/vue/components/form_inputs/RepetitionInput.vue @@ -237,6 +237,18 @@ <script> export default { name: "repetition-input", + emits: [ + 'input_number_of_dates', + 'input_repetition_dom', + 'input_repetition_dow', + 'input_repetition_dow_week', + 'input_repetition_end_date', + 'input_repetition_end_type', + 'input_repetition_interval', + 'input_repetition_month', + 'input_repetition_month_type', + 'input_repetition_type', + ], props: { name: { type: String, diff --git a/resources/vue/components/form_inputs/SerialTextMarkers.vue b/resources/vue/components/form_inputs/SerialTextMarkers.vue index 20e542dab79671263b56a469b3bd8d928597992a..775f4e96e0fd18dec6fd057bfbbe98b81369872c 100644 --- a/resources/vue/components/form_inputs/SerialTextMarkers.vue +++ b/resources/vue/components/form_inputs/SerialTextMarkers.vue @@ -67,7 +67,7 @@ export default { } }); }, - destroyed() { + unmounted() { STUDIP.eventBus.off('editor-loaded'); } } diff --git a/resources/vue/components/massmail/MassMailPermissions.vue b/resources/vue/components/massmail/MassMailPermissions.vue index 6342427f4eef649331a6089ec25cfe5baef785ed..b493dc5fd1b4f19639f4b36eac872abd88165ee5 100644 --- a/resources/vue/components/massmail/MassMailPermissions.vue +++ b/resources/vue/components/massmail/MassMailPermissions.vue @@ -26,13 +26,13 @@ </td> <td> <div v-if="permission.meta['allowed-degrees-count'] > 0"> - {{ $gettextInterpolate($gettext('%{degrees} Abschlüsse'), { degrees: permission.meta['allowed-degrees-count']}) }} + {{ $gettext('%{degrees} Abschlüsse', { degrees: permission.meta['allowed-degrees-count']}) }} </div> <div v-if="permission.meta['allowed-subjects-count'] > 0"> - {{ $gettextInterpolate($gettext('%{subjects} Fächer'), { subjects: permission.meta['allowed-subjects-count']}) }} + {{ $gettext('%{subjects} Fächer', { subjects: permission.meta['allowed-subjects-count']}) }} </div> <div v-if="permission.meta['allowed-institutes-count'] > 0"> - {{ $gettextInterpolate($gettext('%{institutes} Einrichtungen'), { institutes: permission.meta['allowed-institutes-count']}) }} + {{ $gettext('%{institutes} Einrichtungen', { institutes: permission.meta['allowed-institutes-count']}) }} </div> </td> <td> diff --git a/resources/vue/components/questionnaires/FreetextEdit.vue b/resources/vue/components/questionnaires/FreetextEdit.vue index 60852ffa858a249fa45821e5e87c683fc55aa273..d2c05358c0b8997e8b404602411af3f0aa8f94b3 100644 --- a/resources/vue/components/questionnaires/FreetextEdit.vue +++ b/resources/vue/components/questionnaires/FreetextEdit.vue @@ -14,10 +14,12 @@ <script> import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; +import StudipWysiwyg from "../StudipWysiwyg.vue"; export default { + extends: QuestionnaireComponent, name: 'freetext-edit', - mixins: [ QuestionnaireComponent ], + components: {StudipWysiwyg}, created() { this.setDefaultValues({ description: '', diff --git a/resources/vue/components/questionnaires/InputArray.vue b/resources/vue/components/questionnaires/InputArray.vue index b26237ca392f5db4abca9d3cae79cf5423fb3861..8d514c574c1fc306c637b75334f094f1314a42ba 100644 --- a/resources/vue/components/questionnaires/InputArray.vue +++ b/resources/vue/components/questionnaires/InputArray.vue @@ -17,39 +17,46 @@ <th class="actions"></th> </tr> </thead> - <Draggable v-model="options" handle=".dragarea" tag="tbody" class="statements"> - <tr v-for="(option, index) in options" :key="index"> - <td class="dragcolumn"> - <a class="dragarea" - tabindex="0" - :title="$gettextInterpolate($gettext(`Sortierelement für %{label} %{option}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.`), {option, label}, true)" - @keydown="keyHandler($event, index)" - ref="draghandle"> - <span class="drag-handle"></span> - </a> - </td> - <td> - <input type="text" - ref="inputs" - :placeholder="label" - @paste="(ev) => onPaste(ev, index)" - v-model="options[index]"> - </td> - <slot name="body-cells" /> - <td class="actions"> - <StudipIcon name="delete" - shape="trash" - @click.prevent="deleteOption(index)" - :title="$gettextInterpolate($gettext('%{label} löschen'), {label}, true)" - /> - </td> - </tr> + <Draggable v-model="options" + item-key="index" + handle=".dragarea" + tag="tbody" + class="statements" + > + <template #item="{element, index}"> + <tr> + <td class="dragcolumn"> + <a class="dragarea" + tabindex="0" + :title="$gettext(`Sortierelement für %{label} %{option}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.`, {option: element.value, label}, true)" + @keydown="keyHandler($event, index)" + :ref="`draghandle${index}`"> + <span class="drag-handle"></span> + </a> + </td> + <td> + <input type="text" + ref="inputs" + :placeholder="label" + @paste="(ev) => onPaste(ev, index)" + v-model="element.value"> + </td> + <slot name="body-cells" /> + <td class="actions"> + <StudipIcon name="delete" + shape="trash" + @click.prevent="deleteOption(index)" + :title="$gettext('%{label} löschen', {label: element.value}, true)" + /> + </td> + </tr> + </template> </Draggable> <tfoot> <tr> <td :colspan="3 + additionalColspan"> <button class="as-link" - :title="$gettextInterpolate($gettext('%{label} hinzufügen'), {label}, true)" + :title="$gettext('%{label} hinzufügen', {label}, true)" @click.prevent="addOption()"> <StudipIcon shape="add" alt="" /> </button> @@ -66,6 +73,7 @@ import { $gettext } from '../../../assets/javascripts/lib/gettext'; export default { name: 'input-array', + emits: ['update:modelValue'], components: { Draggable }, props: { additionalColspan: { @@ -80,17 +88,32 @@ export default { type: String, default: $gettext('Optionen'), }, - value: Array, + modelValue: Array, }, data() { return { - options: [], assistiveLive: '', }; }, + computed: { + options: { + get() { + return this.modelValue.map((element, index) => ({ + value: element, + index: index, + })); + }, + set(value) { + this.$emit('update:modelValue', value.map(element => element.value)); + } + } + }, methods: { addOption(val = '', position = this.options.length) { - this.$set(this.options, position, val.trim()); + this.$set(this.options, position, { + value: val.trim(), + index: position, + }); this.$nextTick(() => { this.$refs.inputs[position].focus(); @@ -120,45 +143,32 @@ export default { const moveUp = e.keyCode === 38; this.moveElement(index, moveUp ? -1 : 1).then((newIndex) => { - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), + if (newIndex === false) { + return; + } + + this.assistiveLive = this.$gettext( + 'Aktuelle Position in der Liste: %{pos} von %{listLength}.', {pos: newIndex + 1, listLength: this.options.length} ); this.$nextTick(() => { - this.$refs['draghandle'][newIndex].focus(); + this.$refs[`draghandle${newIndex}`].focus(); }); }) }, moveElement(index, direction) { if (this.options[index + direction] === undefined) { - return Promise.resolve(index); + return Promise.resolve(false); } const indices = [index, index + direction].sort(); - this.options.splice( - Math.min(...indices), - 2, - ...indices.reverse().map(idx => this.options[idx]) - ); + [this.options[indices[0]], this.options[indices[1]]] = [this.options[indices[1]], this.options[indices[0]]]; + this.options = [...this.options]; return Promise.resolve(index + direction); - } - }, - watch: { - options: { - handler(current) { - this.$emit('input', current); - }, - deep: true }, - value: { - handler(current) { - this.options = current; - }, - immediate: true - } } } </script> diff --git a/resources/vue/components/questionnaires/LikertEdit.vue b/resources/vue/components/questionnaires/LikertEdit.vue index 311bf6d4109b7b80392a9d67f67231df5cfcaa58..c25126c02760c83842461701417e7fe29383b8dd 100644 --- a/resources/vue/components/questionnaires/LikertEdit.vue +++ b/resources/vue/components/questionnaires/LikertEdit.vue @@ -44,6 +44,7 @@ import { $gettext } from '../../../assets/javascripts/lib/gettext'; import InputArray from "./InputArray.vue"; import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; +import StudipWysiwyg from "../StudipWysiwyg.vue"; // This is necesssar since $gettext does not seem to work in data() or created() const default_values = () => ({ @@ -62,8 +63,8 @@ const default_values = () => ({ export default { name: 'likert-edit', - components: { InputArray }, - mixins: [ QuestionnaireComponent ], + extends: QuestionnaireComponent, + components: {StudipWysiwyg, InputArray }, created() { this.setDefaultValues(default_values()); } diff --git a/resources/vue/components/questionnaires/QuestionnaireEditor.vue b/resources/vue/components/questionnaires/QuestionnaireEditor.vue index 089353bbfcae65fb0a172a60a0dc6da8c6bc58e8..7512bce5d07c318fc2a7501feb745958c5abc9d5 100644 --- a/resources/vue/components/questionnaires/QuestionnaireEditor.vue +++ b/resources/vue/components/questionnaires/QuestionnaireEditor.vue @@ -87,7 +87,8 @@ </div> <div v-else> <component :is="componentForQuestionIndex(indexForQuestion)" - v-model="data.questions[indexForQuestion].questiondata" + :model-value="data.questions[indexForQuestion].questiondata" + @update:modelValue="(v) => data.questions[indexForQuestion].questiondata = v" :question_id="data.questions[indexForQuestion].id" :key="data.questions[indexForQuestion].id"> </component> @@ -101,38 +102,47 @@ <span class="icon"><studip-icon shape="evaluation" :size="30" alt=""></studip-icon></span> {{ $gettext('Einstellungen') }} </a> - <draggable v-if="data.questions.length > 0" v-model="data.questions" handle=".drag-handle" group="questions" class="questions_container questions"> - <div v-for="question in data.questions" - :key="question.id" - @mouseenter="hoverTab = question.id" - @mouseleave="hoverTab = null" - :class="(activeTab === question.id || activeTab === 'meta_' + question.id ? 'active' : '') + (hoverTab === question.id ? ' hovered' : '')"> - <a href="#" - @click.prevent="switchTab(question.id)"> - <span class="drag-handle"></span> - <span class="icon type"> - <studip-icon :shape="questionTypes[question.questiontype].icon" :size="30" alt=""></studip-icon> + <draggable :list="data.questions" + handle=".drag-handle" + group="questions" + class="questions_container questions" + item-key="id" + > + <template #item="{ element }"> + <div @mouseenter="hoverTab = element.id" + @mouseleave="hoverTab = null" + :class="{ + active: activeTab === element.id || activeTab === 'meta_' + element.id, + hovered: hoverTab === element.id, + }" + > + <a href="#" + @click.prevent="switchTab(element.id)"> + <span class="drag-handle"></span> + <span class="icon type"> + <studip-icon :shape="questionTypes[element.questiontype].icon" :size="30" alt=""></studip-icon> </span> - <div v-if="editInternalName !== question.id">{{ question.internal_name || questionTypes[question.questiontype].name}}</div> - <div v-else class="inline_editing"> - <input type="text" ref="editInternalName" v-model="tempInternalName" class="inlineediting_internal_name"> - <button @click="saveInternalName(question.id)"> - <studip-icon shape="accept" :size="20" :title="$gettext('Internen Namen speichern')"></studip-icon> - </button> - <button @click="editInternalName = null"> - <studip-icon shape="decline" :size="20" :title="$gettext('Internen Namen nicht speichern')"></studip-icon> - </button> - </div> - </a> + <div v-if="editInternalName !== element.id">{{ element.internal_name || questionTypes[element.questiontype].name}}</div> + <div v-else class="inline_editing"> + <input type="text" ref="editInternalName" v-model="tempInternalName" class="inlineediting_internal_name"> + <button @click="saveInternalName(element.id)"> + <studip-icon shape="accept" :size="20" :title="$gettext('Internen Namen speichern')"></studip-icon> + </button> + <button @click="editInternalName = null"> + <studip-icon shape="decline" :size="20" :title="$gettext('Internen Namen nicht speichern')"></studip-icon> + </button> + </div> + </a> - <studip-action-menu :items="actionMenuItems" - @copy="duplicateQuestion(question.id)" - @rename="renameInternalName(question.id)" - @moveup="moveQuestionUp(question.id)" - @movedown="moveQuestionDown(question.id)" - @delete="deleteQuestion(question.id)"></studip-action-menu> - </div> + <studip-action-menu :items="actionMenuItems" + @copy="duplicateQuestion(element.id)" + @rename="renameInternalName(element.id)" + @moveup="moveQuestionUp(element.id)" + @movedown="moveQuestionDown(element.id)" + @delete="deleteQuestion(element.id)"></studip-action-menu> + </div> + </template> </draggable> <a :class="activeTab === 'add_question' ? 'add_question active' : 'add_question'" href="#" @@ -160,6 +170,7 @@ import md5 from 'md5'; import StudipIcon from '../StudipIcon.vue'; import StudipActionMenu from '../StudipActionMenu.vue'; import Datetimepicker from '../Datetimepicker.vue'; +import {defineAsyncComponent} from 'vue'; const loadedComponents = {}; @@ -198,8 +209,8 @@ export default { const componentInfo = this.questionTypes[this.data.questions[index].questiontype].component; if (loadedComponents[componentInfo[0]] === undefined) { loadedComponents[componentInfo[0]] = componentInfo[1] === '' - ? () => import(`./${componentInfo[0]}.vue`) - : () => import(/* webpackIgnore: true */componentInfo[1]); + ? defineAsyncComponent(() => import(`./${componentInfo[0]}.vue`)) + : defineAsyncComponent(() => import(/* webpackIgnore: true */componentInfo[1])); } return loadedComponents[componentInfo[0]]; @@ -329,7 +340,7 @@ export default { ]; }, activateFormSecure() { - return this.form_secured && !this.objectsEqual(this.oldData, this.data); + return this.form_secured && !this.objectsEqual(this.oldData, this.data) ? true : null; }, indexForQuestion() { return this.getIndexForQuestion(this.activeTab); diff --git a/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue b/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue index 57452d49dd531e73517b9f4477ea7d02136b9154..828d24e7c392d62b945cc9c630a9ece226ae0fc3 100644 --- a/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue +++ b/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue @@ -15,10 +15,12 @@ <script> import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; +import StudipWysiwyg from "../StudipWysiwyg.vue"; export default { name: 'questionnaire-info-edit', - mixins: [ QuestionnaireComponent ], + extends: QuestionnaireComponent, + components: {StudipWysiwyg}, created() { this.setDefaultValues({ url: '', diff --git a/resources/vue/components/questionnaires/RangescaleEdit.vue b/resources/vue/components/questionnaires/RangescaleEdit.vue index 044c921cd349681ef431916573ea93e76fb83efe..b3ff7da61ef1d905909b883d7c50a69f512cc1db 100644 --- a/resources/vue/components/questionnaires/RangescaleEdit.vue +++ b/resources/vue/components/questionnaires/RangescaleEdit.vue @@ -52,11 +52,12 @@ <script> import InputArray from './InputArray.vue'; import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; +import StudipWysiwyg from "../StudipWysiwyg.vue"; export default { name: 'rangescale-edit', - components: { InputArray }, - mixins: [ QuestionnaireComponent ], + extends: QuestionnaireComponent, + components: {StudipWysiwyg, InputArray }, created() { this.setDefaultValues({ alternative_answer: '', diff --git a/resources/vue/components/questionnaires/VoteEdit.vue b/resources/vue/components/questionnaires/VoteEdit.vue index 56dd160f4446d683aaa0b3a02bab7ab178fb4f77..b4855cabf912db47426a1fb6e9f1dec6f188d09b 100644 --- a/resources/vue/components/questionnaires/VoteEdit.vue +++ b/resources/vue/components/questionnaires/VoteEdit.vue @@ -26,11 +26,12 @@ <script> import InputArray from "./InputArray.vue"; import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; +import StudipWysiwyg from "../StudipWysiwyg.vue"; export default { + extends: QuestionnaireComponent, name: 'vote-edit', - components: { InputArray }, - mixins: [QuestionnaireComponent], + components: {StudipWysiwyg, InputArray }, created() { this.setDefaultValues({ description: '', diff --git a/resources/vue/components/responsive/NavigationItem.vue b/resources/vue/components/responsive/NavigationItem.vue index d65bda39917ec9e73bf1794da91ff2026870e505..8db20f8d38092ea5612a9142aa836b2b93b9a249 100644 --- a/resources/vue/components/responsive/NavigationItem.vue +++ b/resources/vue/components/responsive/NavigationItem.vue @@ -58,10 +58,10 @@ </template> <script lang="ts"> -import Vue, { PropType } from 'vue'; +import { defineComponent } from 'vue'; import StudipIcon from '../StudipIcon.vue'; -export default Vue.extend({ +export default defineComponent({ name: 'NavigationItem', components: { StudipIcon }, props: { @@ -96,13 +96,17 @@ export default Vue.extend({ hasChildren() { return this.item.children && Object.keys(this.item.children).length > 0; }, - navigateToText(itemTitle: string) { - return this.$gettextInterpolate(this.$gettext('Navigiere zu %{ title }'), { title: itemTitle }); + navigateToText(title: string) { + return this.$gettext( + 'Navigiere zu %{title}', + { title } + ); }, - openNavigationText(itemTitle: string): string { - return this.$gettextInterpolate(this.$gettext('Unternavigation zu %{ title } öffnen'), { - title: itemTitle, - }); + openNavigationText(title: string): string { + return this.$gettext( + 'Unternavigation zu %{title} öffnen', + { title } + ); }, }, }); diff --git a/resources/vue/components/responsive/ResponsiveContentBar.vue b/resources/vue/components/responsive/ResponsiveContentBar.vue index d21ae21028c78afa6903d7b9be4ef50cca6f2333..408fe95a9baef157cd3eee294f421f9996547b36 100644 --- a/resources/vue/components/responsive/ResponsiveContentBar.vue +++ b/resources/vue/components/responsive/ResponsiveContentBar.vue @@ -1,8 +1,8 @@ <template> <div v-if="realContentbarSource === ''"> - <MountingPortal mount-to="#responsive-contentbar-container" append> + <Teleport to="#responsive-contentbar-container" append> <portal-target name="layout-page"></portal-target> - </MountingPortal> + </Teleport> <portal to="layout-page"> <div id="responsive-contentbar" class="contentbar" ref="contentbar"> <div v-if="hasSidebar" class="contentbar-nav" ref="leftNav"> @@ -225,9 +225,10 @@ export default { this.globalOn('courseware-contentbar-mounted', this.onCoursewareContentbarMounted) this.globalOn('courseware-contentbar-before-destroy', this.onCoursewareContentbarBeforeDestroy); }, - beforeDestroy() { + beforeUnmount() { this.globalOff('courseware-contentbar-mounted', this.onCoursewareContentbarMounted); this.globalOff('courseware-contentbar-before-destroy', this.onCoursewareContentbarBeforeDestroy); + if (this.realContentbar) { this.adjustExistingContentbar(false); } diff --git a/resources/vue/components/responsive/ResponsiveNavigation.vue b/resources/vue/components/responsive/ResponsiveNavigation.vue index e53e19c0914319ae2a9395178f8e0a95fb72f685..33b3ccbc246a3e0d7aca51d4a84da2ba8b5f94ce 100644 --- a/resources/vue/components/responsive/ResponsiveNavigation.vue +++ b/resources/vue/components/responsive/ResponsiveNavigation.vue @@ -585,7 +585,7 @@ export default { // Check initial state after load this.headerMagic = document.querySelector('body').classList.contains('fixed'); }, - beforeDestroy() { + beforeUnmount() { this.classObserver.disconnect(); this.dialogObserver.disconnect(); document.getElementById('header-links').style.display = null; @@ -603,13 +603,11 @@ export default { transition: all var(--transition-duration) ease; } -.slide-enter-to, -.slide-leave-from, -.slide-leave { +.slide-enter-from, +.slide-leave-from { margin-left: -3px; } -.slide-enter, .slide-enter-from, .slide-leave-to { margin-left: -50px; @@ -620,13 +618,11 @@ export default { transition: opacity var(--transition-duration) ease; } -.appear-leave, .appear-leave-from, .appear-enter-to { opacity: 1; } -.appear-enter, .appear-enter-from, .appear-leave-to { opacity: 0; diff --git a/resources/vue/components/responsive/ResponsiveSkipLinks.vue b/resources/vue/components/responsive/ResponsiveSkipLinks.vue index 7668191d0951627f0208e0b6df12e6dfebf091f0..18ccc8d790ae8066afe91bcc72ce756e799f2e4c 100644 --- a/resources/vue/components/responsive/ResponsiveSkipLinks.vue +++ b/resources/vue/components/responsive/ResponsiveSkipLinks.vue @@ -1,8 +1,8 @@ <template> <div> - <MountingPortal mount-to="#skiplink_list" append> + <Teleport to="#skiplink_list" append> <portal-target name="additional-skiplinks"></portal-target> - </MountingPortal> + </Teleport> <portal to="additional-skiplinks"> <li v-for="(link) in links" :key="link.url"> <button class="skiplink" role="link" @click.prevent="goto(link.url)"> @@ -39,7 +39,7 @@ export default { }); }); }, - beforeDestroy() { + beforeUnmount() { const buttons = document.querySelectorAll('button.skiplink:not([data-in-fullscreen="1"])'); buttons.forEach(button => { button.style.display = null; diff --git a/resources/vue/components/stock-images/ActionsWidget.vue b/resources/vue/components/stock-images/ActionsWidget.vue index ee2d6cfb7e07dcd378600b2c3cdd4d74fafd2050..4553249648c008f4539ed28f2a604fd4ff5cac4a 100644 --- a/resources/vue/components/stock-images/ActionsWidget.vue +++ b/resources/vue/components/stock-images/ActionsWidget.vue @@ -18,6 +18,7 @@ import SidebarWidget from '../SidebarWidget.vue'; export default { + emits: ['initiateUpload', 'initiateZipUpload'], components: { SidebarWidget, }, diff --git a/resources/vue/components/stock-images/AttributesFieldset.vue b/resources/vue/components/stock-images/AttributesFieldset.vue index a88501c13b71690f66417a57d24f63719d00d489..bdf3875cd55292568dab0c4430aeb754084b40d1 100644 --- a/resources/vue/components/stock-images/AttributesFieldset.vue +++ b/resources/vue/components/stock-images/AttributesFieldset.vue @@ -18,7 +18,7 @@ </label> <label> {{ $gettext('Tags') }} - <TagsInput v-model="tags" :suggestions="suggestedTags" /> + <TagsInput v-model:tags="tags" :suggestions="suggestedTags" /> </label> </div> </template> @@ -28,6 +28,7 @@ import TagsInput from './TagsInput.vue'; export default { props: ['metadata', 'suggestedTags'], components: { TagsInput }, + emits: ['change'], computed: { author: { get() { diff --git a/resources/vue/components/stock-images/ColorFilterWidget.vue b/resources/vue/components/stock-images/ColorFilterWidget.vue index b816bdb33a6b63bc9c61c1c28b2734d7327be8be..79d403881cb3c79974c8d3fbcf02e608f0346fe0 100644 --- a/resources/vue/components/stock-images/ColorFilterWidget.vue +++ b/resources/vue/components/stock-images/ColorFilterWidget.vue @@ -26,10 +26,7 @@ import SidebarWidget from '../SidebarWidget.vue'; import { orientations } from './filters.js'; export default { - model: { - prop: 'filters', - event: 'change', - }, + emits: ['update:filters'], props: { filters: { type: Object, @@ -48,7 +45,7 @@ export default { methods: { onVueSelectInput(selectedColors) { const colors = selectedColors.map(({ hex }) => hex); - this.$emit('change', { ...this.filters, colors }); + this.$emit('update:filters', { ...this.filters, colors }); }, }, mounted() { diff --git a/resources/vue/components/stock-images/EditDialog.vue b/resources/vue/components/stock-images/EditDialog.vue index 68c71e2331033c5e063568f9817c13ee21dc54aa..c3e6cb9f850d989b17374383414a60d6f4b54360 100644 --- a/resources/vue/components/stock-images/EditDialog.vue +++ b/resources/vue/components/stock-images/EditDialog.vue @@ -42,6 +42,7 @@ import AttributesFieldset from './AttributesFieldset.vue'; export default { props: ['stockImage', 'suggestedTags'], components: { AttributesFieldset, ThumbnailCard }, + emits: ['cancel', 'confirm'], data: () => ({ metadata: {}, }), diff --git a/resources/vue/components/stock-images/ImagesList.vue b/resources/vue/components/stock-images/ImagesList.vue index 7d2c0db9b73f198f7bececea425cd9cfbaae7b98..41a3d6f893cdec4c5122a1254b7ae10a7b861c75 100644 --- a/resources/vue/components/stock-images/ImagesList.vue +++ b/resources/vue/components/stock-images/ImagesList.vue @@ -89,6 +89,7 @@ import ImagesListItem from './ImagesListItem.vue'; import { mapActions } from 'vuex'; export default { + emits: ['checked', 'open-page', 'search', 'select'], props: { checkedImages: { type: Array, @@ -120,11 +121,16 @@ export default { }), computed: { allChecked() { - return this.paged.length && this.paged.every(({ id }) => this.checkedImages.includes(id)); + return this.paged.length && this.paged.every(({ id }) => this.checkedImages.includes(id)) ? true : null; }, caption() { const n = this.stockImages.length; - return this.$gettextInterpolate(this.$ngettext('%{ n } Bild gefunden', '%{ n } Bilder gefunden', n), { n }); + return this.$ngettext( + '%{ n } Bild gefunden', + '%{ n } Bilder gefunden', + n, + { n } + ); }, paged() { return this.stockImages.slice((this.page - 1) * this.perPage, this.page * this.perPage); @@ -163,9 +169,12 @@ export default { }, }, watch: { - checkedImages({ length }) { - this.$refs.checkAll.indeterminate = 0 < length && length < this.paged.length; - }, + checkedImages: { + handler({length}) { + this.$refs.checkAll.indeterminate = 0 < length && length < this.paged.length; + }, + deep: true + } }, }; </script> diff --git a/resources/vue/components/stock-images/ImagesListItem.vue b/resources/vue/components/stock-images/ImagesListItem.vue index 1e1dda29f698c041acb3ffb7cb1906ace94b6c45..6143a22d77667e46f4b91a6cc2951a2e27e29c48 100644 --- a/resources/vue/components/stock-images/ImagesListItem.vue +++ b/resources/vue/components/stock-images/ImagesListItem.vue @@ -2,9 +2,9 @@ <tr @click="onSelect"> <td> <label> - <input type="checkbox" :checked="isChecked" @change="onCheckboxChange" /> + <input type="checkbox" :checked="isChecked ? true : null" @change="onCheckboxChange" /> <span class="sr-only">{{ - $gettextInterpolate($gettext('%{context} auswählen'), { context: stockImage.attributes.title }) + $gettext('%{context} auswählen', { context: stockImage.attributes.title }) }}</span> </label> </td> @@ -58,6 +58,7 @@ import Thumbnail from './Thumbnail.vue'; import { getFormat } from './format.js'; export default { + emits: ['checked', 'search', 'select'], props: { stockImage: { type: Object, diff --git a/resources/vue/components/stock-images/ImagesPagination.vue b/resources/vue/components/stock-images/ImagesPagination.vue index 16dd96ab0a7728ea983fc3f7ed0c80267daf852b..2d6a013512180c00925db22b33b907d0706812aa 100644 --- a/resources/vue/components/stock-images/ImagesPagination.vue +++ b/resources/vue/components/stock-images/ImagesPagination.vue @@ -23,10 +23,7 @@ import StudipPagination from '../StudipPagination.vue'; export default { components: { StudipPagination }, - model: { - prop: 'page', - event: 'change', - }, + emits: ['update:page'], props: { stockImages: { type: Array, @@ -51,7 +48,7 @@ export default { }, methods: { onUpdateOffset(offset) { - this.$emit('change', offset + 1); + this.$emit('update:page', offset + 1); }, }, }; diff --git a/resources/vue/components/stock-images/MetadataBox.vue b/resources/vue/components/stock-images/MetadataBox.vue index ac819de4c7446025ca0127970db056d2a7235144..7395b768ce83fc8f6f9b22450556a69299911c0c 100644 --- a/resources/vue/components/stock-images/MetadataBox.vue +++ b/resources/vue/components/stock-images/MetadataBox.vue @@ -11,7 +11,7 @@ /> </div> <div> - <AttributesFieldset :metadata="metadata" :suggested-tags="suggestedTags" @change="onChange" /> + <AttributesFieldset :metadata="metadata" :suggested-tags="suggestedTags" @change="metadata => onChange(metadata)" /> </div> </div> </template> @@ -26,6 +26,8 @@ export default { components: { AttributesFieldset, ThumbnailCard }, + emits: ['change'], + data: () => ({ fileURL: null, height: null, @@ -39,7 +41,7 @@ export default { return this.metadata.tags; }, set(tags) { - this.$set(this.metadata, 'tags', tags); + this.$emit('change', { ...this.metadata, tags }); }, }, }, @@ -58,10 +60,10 @@ export default { this.width = target.width; }; this.image.src = this.fileURL; - this.$set(this.metadata, 'title', this.file.name); + this.$emit('change', { ...this.metadata, title: this.file.name }); }, - beforeDestroy() { + beforeUnmount() { if (this.fileURL) { URL.revokeObjectURL(this.fileURL); } diff --git a/resources/vue/components/stock-images/OrientationFilterWidget.vue b/resources/vue/components/stock-images/OrientationFilterWidget.vue index 5ae4a2c4dee06154927e5425f8ba84bbd7ab0040..933b66a4b5acaa7bf3f8518846ade2dbc34aa761 100644 --- a/resources/vue/components/stock-images/OrientationFilterWidget.vue +++ b/resources/vue/components/stock-images/OrientationFilterWidget.vue @@ -17,10 +17,7 @@ import SidebarWidget from '../SidebarWidget.vue'; import { orientations } from './filters.js'; export default { - model: { - prop: 'filters', - event: 'change', - }, + emits: ['update:filters'], props: { filters: { type: Object, @@ -36,7 +33,7 @@ export default { return this.filters.orientation; }, set(orientation) { - this.$emit('change', { ...this.filters, orientation }); + this.$emit('update:filters', { ...this.filters, orientation }); } }, orientations() { diff --git a/resources/vue/components/stock-images/Page.vue b/resources/vue/components/stock-images/Page.vue index 3f06042b54fa5b1630636e2fe6f5fd2c7b2ba490..b27cc52645793979492f3bc61d4d9f4561a11186 100644 --- a/resources/vue/components/stock-images/Page.vue +++ b/resources/vue/components/stock-images/Page.vue @@ -7,7 +7,7 @@ v-show="!showUploadIndicator" :per-page="perPage" :stock-images="filteredStockImages" - v-model="page" + v-model:page="page" > <ImagesList :checked-images="checkedImages" @@ -26,12 +26,12 @@ :description="$gettext('Bilder werden hochgeladen...')" > </studip-progress-indicator> - <MountingPortal mountTo="#stock-images-widget" name="sidebar-stock-images"> + <Teleport to="#stock-images-widget" name="sidebar-stock-images"> <SearchWidget :query="query" @search="onSearch" /> - <OrientationFilterWidget v-model="filters" /> - <ColorFilterWidget v-model="filters" /> + <OrientationFilterWidget v-model:filters="filters" /> + <ColorFilterWidget v-model:filters="filters" /> <ActionsWidget @initiateUpload="onUploadDialogShow" @initiateZipUpload="onZipUploadDialogShow" /> - </MountingPortal> + </Teleport> <EditDialog :stock-image="selectedImage" :suggested-tags="suggestedTags" @@ -150,15 +150,11 @@ export default { this.showUploadIndicator = false; this.showZipUploadMessage = true; this.zipUploadMessageType = 'success'; - this.zipUploadMessage = this.$gettextInterpolate( - this.$ngettext( - '%{length} Bild wurde hinzugefügt', - '%{length} Bilder wurden hinzugefügt', - resp.data['image-count'] - ), - { - length: resp.data['image-count'], - } + this.zipUploadMessage = this.$ngettext( + '%{length} Bild wurde hinzugefügt', + '%{length} Bilder wurden hinzugefügt', + resp.data['image-count'], + { length: resp.data['image-count'] } ); this.$nextTick(() => { this.fetchStockImages(); diff --git a/resources/vue/components/stock-images/SearchWidget.vue b/resources/vue/components/stock-images/SearchWidget.vue index 53e0aa715a34144b62cab9a158ff52be35a19b13..7c09973dccc0337928c8220a14dde54d8198749e 100644 --- a/resources/vue/components/stock-images/SearchWidget.vue +++ b/resources/vue/components/stock-images/SearchWidget.vue @@ -39,6 +39,7 @@ import SidebarWidget from '../SidebarWidget.vue'; export default { + emits: ['search'], props: { query: { type: String, diff --git a/resources/vue/components/stock-images/Selector.vue b/resources/vue/components/stock-images/Selector.vue index 4e34f9f6f3a33806b74a2677c59f568809ae9d45..bba39d2475667c7383802047e381d1e7a900d750 100644 --- a/resources/vue/components/stock-images/Selector.vue +++ b/resources/vue/components/stock-images/Selector.vue @@ -10,7 +10,7 @@ </div> <ul> <li v-for="stockImage in filteredStockImages" :key="stockImage.id"> - <SelectableImageCard :stock-image="stockImage" @click.native="onSelectImage(stockImage)" @keyup.enter.native="onSelectImage(stockImage)" /> + <SelectableImageCard :stock-image="stockImage" @click="onSelectImage(stockImage)" @keyup.enter="onSelectImage(stockImage)" /> </li> </ul> </div> @@ -22,6 +22,7 @@ import SelectableImageCard from './SelectableImageCard.vue'; import { searchFilterAndSortImages } from './filters.js'; export default { + emits: ['select'], props: { stockImages: { type: Array, diff --git a/resources/vue/components/stock-images/SelectorDialog.vue b/resources/vue/components/stock-images/SelectorDialog.vue index c6c46f8f88de0334e3645187d569c31d83d27a07..fa9743e72ca4980cdd4a227838d003ad50f4a88e 100644 --- a/resources/vue/components/stock-images/SelectorDialog.vue +++ b/resources/vue/components/stock-images/SelectorDialog.vue @@ -17,6 +17,7 @@ import { mapActions, mapGetters } from 'vuex'; import Selector from './Selector.vue'; export default { + emits: ['close', 'select'], data: () => ({ query: '', selectedImage: null, diff --git a/resources/vue/components/stock-images/SelectorSearch.vue b/resources/vue/components/stock-images/SelectorSearch.vue index 849e91541a821b7672eaf70a8ba216e04cd6f025..f9b138fb00a8aacc2d8d5983c9b809f3068fadf6 100644 --- a/resources/vue/components/stock-images/SelectorSearch.vue +++ b/resources/vue/components/stock-images/SelectorSearch.vue @@ -12,7 +12,7 @@ <ActiveFilter v-for="color in selectedColors" :key="color.hex" - :name="$gettextInterpolate($gettext('Farbe %{color}'), { color: color.name })" + :name="$gettext('Farbe %{color}', { color: color.name })" @remove="onRemoveColorFilter(color)" > <label> @@ -68,6 +68,7 @@ import { colors as selectableColors } from './colors.js'; import { orientations, similarColors } from './filters.js'; export default { + emits: ['search', 'update-active-filters'], props: { activeFilters: { type: Object, diff --git a/resources/vue/components/stock-images/TagsInput.vue b/resources/vue/components/stock-images/TagsInput.vue index 7e7f11587767c1965e8a0d4a370b50a2e6aed875..bcdca9d16f126d7cc730de10c6086f666ca5f131 100644 --- a/resources/vue/components/stock-images/TagsInput.vue +++ b/resources/vue/components/stock-images/TagsInput.vue @@ -3,7 +3,7 @@ <span class="sr-only">{{ $gettext('Um einen Tag zu erstellen, schließen Sie Ihre Eingabe mit der Eingabetaste ab.') }}</span> - <TagsInput + <VueTagsInput v-model="tag" :add-on-key="[13, ';']" :autocomplete-items="filteredItems" @@ -31,20 +31,17 @@ :title="$gettext('Tag entfernen')" /> </template> - </TagsInput> + </VueTagsInput> </div> </template> <script> -import TagsInput from '@johmun/vue-tags-input'; +import { VueTagsInput } from '@vojtechlanka/vue-tags-input'; const fromSimpleTags = (array) => array.map((text) => ({ text })); const toSimpleTags = (tags) => tags.map(({ text }) => text); export default { - model: { - prop: 'tags', - event: 'change', - }, + emits: ['update:tags'], props: { tags: { type: Array, @@ -56,7 +53,7 @@ export default { }, }, - components: { TagsInput }, + components: { VueTagsInput }, data: () => ({ tag: '', @@ -77,7 +74,7 @@ export default { methods: { onTagsChanged(newTags) { - this.$emit('change', toSimpleTags(newTags)); + this.$emit('update:tags', toSimpleTags(newTags)); }, }, diff --git a/resources/vue/components/stock-images/UploadBox.vue b/resources/vue/components/stock-images/UploadBox.vue index 7eeb8631eeec512b36c091a35283ab1e368d11f2..eace13cf9f3e43865b58da03d1b4668fa41376dd 100644 --- a/resources/vue/components/stock-images/UploadBox.vue +++ b/resources/vue/components/stock-images/UploadBox.vue @@ -20,6 +20,7 @@ <script> export default { + emits: ['upload'], props: { type: { type: String, diff --git a/resources/vue/components/stock-images/UploadDialog.vue b/resources/vue/components/stock-images/UploadDialog.vue index 51040b265c9f6de44ac03741f429d71956aa5a63..7ac86a329285e5dafea80b346e7dd0ba5cec138e 100644 --- a/resources/vue/components/stock-images/UploadDialog.vue +++ b/resources/vue/components/stock-images/UploadDialog.vue @@ -21,7 +21,7 @@ :file="file" :metadata="metadata" :suggested-tags="suggestedTags" - @change="onChangeMetadata" + @change="metadata => onChangeMetadata(metadata)" /> </form> </template> @@ -48,6 +48,7 @@ const STATES = { IDLE: 'idle', UPLOADED: 'uploaded' }; export default { props: ['show', 'suggestedTags'], components: { MetadataBox, UploadBox }, + emits: ['cancel', 'confirm'], data: () => ({ file: null, metadata: { diff --git a/resources/vue/components/stock-images/ZipUploadDialog.vue b/resources/vue/components/stock-images/ZipUploadDialog.vue index e2818343f4fc55392d7d69242ee9f13b3f594f25..102be161592ce55dba313b713a95ef0e6a9ea1fa 100644 --- a/resources/vue/components/stock-images/ZipUploadDialog.vue +++ b/resources/vue/components/stock-images/ZipUploadDialog.vue @@ -27,6 +27,7 @@ <script> export default { name: 'ZipUploadDialog', + emits: ['cancel', 'confirm'], props: { show: { type: Boolean, diff --git a/resources/vue/components/stock-images/colors.js b/resources/vue/components/stock-images/colors.js index 910b1435d308de8fa209e5c3d0d618a166f4e2e7..923b9a15ee767da5cf4a56df05790012bc6567ee 100644 --- a/resources/vue/components/stock-images/colors.js +++ b/resources/vue/components/stock-images/colors.js @@ -1,4 +1,6 @@ -import { $gettext } from '@/assets/javascripts/lib/gettext'; +import gettext from '@/assets/javascripts/lib/gettext'; + +const { $gettext } = gettext; const colors = [ { name: $gettext('Schwarz'), hex: '#000000' }, diff --git a/resources/vue/components/stock-images/filters.js b/resources/vue/components/stock-images/filters.js index 42de27dc6fc346f817271d885b8ab65d6165c170..c450f8f61e937420faa3914b35ffe9d9ec2dc5b4 100644 --- a/resources/vue/components/stock-images/filters.js +++ b/resources/vue/components/stock-images/filters.js @@ -1,4 +1,5 @@ import { $gettext } from '@/assets/javascripts/lib/gettext'; + import { fromHex, rgbToCIELab, cie94 } from 'colorpare'; const SQUARE_DELTA = 1.1; diff --git a/resources/vue/components/tree/AssignLinkWidget.vue b/resources/vue/components/tree/AssignLinkWidget.vue index fec478f43b994f4c5572980bd82a6b013acb46c2..7ca99ff3242c7b898dbd9b02790c2876c47bd8c1 100644 --- a/resources/vue/components/tree/AssignLinkWidget.vue +++ b/resources/vue/components/tree/AssignLinkWidget.vue @@ -21,7 +21,7 @@ export default { mixins: [ TreeMixin ], props: { node: { - type: String, + type: Object, required: true }, courses: { diff --git a/resources/vue/components/tree/StudipTree.vue b/resources/vue/components/tree/StudipTree.vue index fc6dc41dd57ad267163aa6265a1f037ab6c1b41f..999840e150bc6a0ea78c1a60eeb6a689c5252960 100644 --- a/resources/vue/components/tree/StudipTree.vue +++ b/resources/vue/components/tree/StudipTree.vue @@ -30,14 +30,14 @@ <div v-else class="studip-tree"> <tree-search-result :search-config="searchConfig"></tree-search-result> </div> - <MountingPortal v-if="withSearch" mountTo="#search-widget" name="sidebar-search"> + <Teleport v-if="withSearch" to="#search-widget" name="sidebar-search"> <search-widget v-if="currentNode" :min-length="3" ref="searchWidget"></search-widget> - </MountingPortal> - <MountingPortal v-if="!editable && !isSearching && !isLoading && currentNode" - mountTo="#views-widget" + </Teleport> + <Teleport v-if="!editable && !isSearching && !isLoading && currentNode" + to="#views-widget" name="sidebar-views"> <studip-tree-view-widget :config="viewConfig" /> - </MountingPortal> + </Teleport> </div> </template> diff --git a/resources/vue/components/tree/StudipTreeList.vue b/resources/vue/components/tree/StudipTreeList.vue index c57c31f3ac7e042722b1196362e0cb8efd7846b3..a5db1722f672cc47a8b18e31e5a141ba40418a39 100644 --- a/resources/vue/components/tree/StudipTreeList.vue +++ b/resources/vue/components/tree/StudipTreeList.vue @@ -15,8 +15,7 @@ <a v-if="editable && currentNode.attributes.id !== 'root'" :href="editUrl + '/' + currentNode.attributes.id" @click.prevent="editNode(editUrl, currentNode.id)" data-dialog="size=medium" - :title="$gettextInterpolate($gettext('%{name} bearbeiten'), {name: currentNode.attributes.name}, true)" - > + :title="$gettext('%{name} bearbeiten', {name: currentNode.attributes.name}, true)"> <studip-icon shape="edit"></studip-icon> </a> </h1> @@ -31,19 +30,26 @@ <h1> {{ $gettext('Unterebenen') }} </h1> - <draggable v-model="children" handle=".drag-handle" :animation="300" tag="ul" - class="studip-tree-children" @end="dropChild"> - <li v-for="(child, index) in children" :key="index" class="studip-tree-child"> - <a v-if="editable && children.length > 1" class="drag-link" - tabindex="0" - :title="$gettextInterpolate($gettext('Sortierelement für Element %{node}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.'), {node: child.attributes.name}, true)" - @keydown="keyHandler($event, index)" - :ref="'draghandle-' + index"> - <span class="drag-handle"></span> - </a> - <tree-node-tile :node="child" :semester="withCourses ? semester : 'all'" :sem-class="semClass" - :url="nodeUrl(child.id, semester !== 'all' ? semester : null)"></tree-node-tile> - </li> + <draggable v-model="children" + handle=".drag-handle" + :animation="300" + tag="ul" + class="studip-tree-children" + item-key="id" + @end="dropChild"> + <template #item="{element, index}"> + <li class="studip-tree-child"> + <a v-if="editable && children.length > 1" class="drag-link" + tabindex="0" + :title="$gettext('Sortierelement für Element %{node}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.', {node: child.attributes.name}, true)" + @keydown="keyHandler($event, index)" + :ref="'draghandle-' + index"> + <span class="drag-handle"></span> + </a> + <tree-node-tile :node="element" :semester="withCourses ? semester : 'all'" :sem-class="semClass" + :url="nodeUrl(element.id, semester !== 'all' ? semester : null)"></tree-node-tile> + </li> + </template> </draggable> </nav> <section v-else-if="withChildren && !currentNode.attributes['has-children']" class="studip-tree-node-no-children"> @@ -92,8 +98,8 @@ <tr v-for="(course) in courses" :key="course.id" class="studip-tree-child studip-tree-course"> <td> <a :href="courseUrl(course.id)" tabindex="0" - :title="$gettextInterpolate( - $gettext('Zur Veranstaltung %{ title }'), + :title="$gettext( + 'Zur Veranstaltung %{ title }', { title: course.attributes.title }, true )"> @@ -122,14 +128,14 @@ </tr> </tfoot> </table> - <MountingPortal v-if="showExport" mountTo="#export-widget" name="sidebar-export"> + <Teleport v-if="showExport" to="#export-widget" name="sidebar-export"> <tree-export-widget v-if="courses.length > 0" :title="$gettext('Veranstaltungen exportieren')" :url="exportUrl()" :export-data="courses"></tree-export-widget> - </MountingPortal> - <MountingPortal v-if="withCourseAssign" mountTo="#assign-widget" name="sidebar-assign-courses"> + </Teleport> + <Teleport v-if="withCourseAssign" to="#assign-widget" name="sidebar-assign-courses"> <assign-link-widget v-if="courses.length > 0" :node="currentNode" :courses="courses"></assign-link-widget> - </MountingPortal> + </Teleport> </article> </template> @@ -151,6 +157,7 @@ export default { AssignLinkWidget, StudipPagination }, mixins: [ TreeMixin ], + emits: ['change-current-node'], props: { node: { type: Object, @@ -278,8 +285,8 @@ export default { this.decreasePosition(index); this.$nextTick(() => { this.$refs['draghandle-' + (index - 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), + this.assistiveLive = this.$gettext( + 'Aktuelle Position in der Liste: %{pos} von %{listLength}.', { pos: index, listLength: this.children.length } ); }); @@ -289,8 +296,8 @@ export default { this.increasePosition(index); this.$nextTick(function () { this.$refs['draghandle-' + (index + 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), + this.assistiveLive = this.$gettext( + 'Aktuelle Position in der Liste: %{pos} von %{listLength}.', { pos: index + 2, listLength: this.children.length } ); }); @@ -384,7 +391,7 @@ export default { semesterForm.appendChild(nodeField); }); }, - beforeDestroy() { + beforeUnmount() { STUDIP.eventBus.off('open-tree-node'); STUDIP.eventBus.off('load-tree-node'); STUDIP.eventBus.off('sort-tree-children'); diff --git a/resources/vue/components/tree/StudipTreeNode.vue b/resources/vue/components/tree/StudipTreeNode.vue index 8eb13fa0f0c1b9e17fdd2752fb55b96e06b886ff..78691c890a00fda5e80d46eb5331e9bbd3b408aa 100644 --- a/resources/vue/components/tree/StudipTreeNode.vue +++ b/resources/vue/components/tree/StudipTreeNode.vue @@ -272,7 +272,7 @@ export default { } }); }, - beforeDestroy() { + beforeUnmount() { STUDIP.eventBus.off('sort-tree-children'); } } diff --git a/resources/vue/components/tree/StudipTreeTable.vue b/resources/vue/components/tree/StudipTreeTable.vue index 89e85df40d69fc4265538a9f4e67bda94c5ce878..acbb1045388f5895be355eb2ed7b2fcd0de9c92c 100644 --- a/resources/vue/components/tree/StudipTreeTable.vue +++ b/resources/vue/components/tree/StudipTreeTable.vue @@ -41,13 +41,10 @@ </span> </section> - <table v-if="currentNode.attributes['has-children'] || courses.length > 0" class="default"> + <table v-if="currentNode.attributes['has-children']" class="default"> <caption class="studip-tree-node-info"> <span v-if="withChildren && children.length > 0"> - {{ $gettextInterpolate($gettext('%{ count } Unterebenen'), { count: children.length }) }} - </span> - <span v-if="withChildren && children.length > 0 && withCourses && courses.length > 0"> - , + {{ $gettext('%{ count } Unterebenen', { count: children.length }) }} </span> </caption> <colgroup> @@ -57,15 +54,6 @@ <col style="width: 40%"> </colgroup> <thead> - <tr v-if="totalCourseCount > limit"> - <td colspan="4"> - <studip-pagination :items-per-page="limit" - :total-items="totalCourseCount" - :current-offset="offset" - @updateOffset="updateOffset" - /> - </td> - </tr> <tr> <th></th> <th>{{ $gettext('Typ') }}</th> @@ -73,43 +61,53 @@ <th>{{ $gettext('Information') }}</th> </tr> </thead> - <draggable v-model="children" handle=".drag-handle" :animation="300" - @end="dropChild" tag="tbody" role="listbox"> - <tr v-for="(child, index) in children" :key="index" class="studip-tree-child"> - <td> - <a v-if="editable && children.length > 1" class="drag-link" role="option" - tabindex="0" - :title="$gettextInterpolate($gettext('Sortierelement für Element %{node}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.'), {node: child.attributes.name}, true)" - @keydown="keyHandler($event, index)" - :ref="'draghandle-' + index"> - <span class="drag-handle"></span> - </a> - </td> - <td> - <a :href="nodeUrl(child.id, semester !== 'all' ? semester : null)" tabindex="0" - @click.prevent="openNode(child)" - :title="$gettextInterpolate($gettext('Unterebene %{ node } öffnen'), - { node: node.attributes.name }, true)"> - <studip-icon :shape="child.attributes['has-children'] ? 'folder-full' : 'folder-empty'" - :size="26"></studip-icon> - </a> - </td> - <td> - <a :href="nodeUrl(child.id, semester !== 'all' ? semester : null)" tabindex="0" - @click.prevent="openNode(child)" - :title="$gettextInterpolate($gettext('Unterebene %{ node } öffnen'), - { node: node.attributes.name }, true)"> - {{ child.attributes.name }} - </a> - </td> - <td> - <tree-node-course-info v-if="node.attributes.ancestors.length > 2" - :node="child" - :semester="semester" - :sem-class="semClass" - ></tree-node-course-info> - </td> - </tr> + <draggable v-model="children" + handle=".drag-handle" + :animation="300" + @end="dropChild" + tag="tbody" + item-key="id" + role="listbox" + > + <template #item="{element, index}"> + <StudipTreeTableRows :element="element" + :editable="editable" + :children="children" + :index="index" + :semester="semester" + :sem-class="semClass" + :node="node" + @open:node="element => openNode(element)" + ></StudipTreeTableRows> + </template> + </draggable> + </table> + + <table v-if="courses.length > 0" class="default"> + <colgroup> + <col style="width: 20px"> + <col style="width: 30px"> + <col> + <col style="width: 40%"> + </colgroup> + <thead> + <tr v-if="totalCourseCount > limit"> + <td colspan="4"> + <studip-pagination :items-per-page="limit" + :total-items="totalCourseCount" + :current-offset="offset" + @updateOffset="updateOffset" + /> + </td> + </tr> + <tr> + <th></th> + <th>{{ $gettext('Typ') }}</th> + <th>{{ $gettext('Name') }}</th> + <th>{{ $gettext('Information') }}</th> + </tr> + </thead> + <tbody role="listbox"> <tr v-for="(course) in courses" :key="course.id" class="studip-tree-child studip-tree-course"> <td></td> <td> @@ -117,11 +115,12 @@ </td> <td> <a :href="courseUrl(course.id)" tabindex="0" - :title="$gettextInterpolate( - $gettext('Zur Veranstaltung %{ title }'), + :title="$gettext( + 'Zur Veranstaltung %{ title }', { title: course.attributes.title }, true - )"> + )" + > <template v-if="course.attributes['course-number']"> {{ course.attributes['course-number'] }} </template> @@ -133,7 +132,7 @@ <tree-course-details :course="course.id"></tree-course-details> </td> </tr> - </draggable> + </tbody> <tfoot v-if="totalCourseCount > limit"> <tr> <td colspan="4"> @@ -146,13 +145,14 @@ </tr> </tfoot> </table> - <MountingPortal v-if="showExport" mountTo="#export-widget" name="sidebar-export"> + + <Teleport v-if="showExport" to="#export-widget" name="sidebar-export"> <tree-export-widget v-if="courses.length > 0" :title="$gettext('Download des Ergebnisses')" :url="exportUrl()" :export-data="courses"></tree-export-widget> - </MountingPortal> - <MountingPortal v-if="withCourseAssign" mountTo="#assign-widget" name="sidebar-assign-courses"> + </Teleport> + <Teleport v-if="withCourseAssign" to="#assign-widget" name="sidebar-assign-courses"> <assign-link-widget v-if="courses.length > 0" :node="currentNode" :courses="courses"></assign-link-widget> - </MountingPortal> + </Teleport> </article> </template> @@ -162,18 +162,23 @@ import { TreeMixin } from '../../mixins/TreeMixin'; import TreeExportWidget from './TreeExportWidget.vue'; import TreeBreadcrumb from './TreeBreadcrumb.vue'; import StudipProgressIndicator from '../StudipProgressIndicator.vue'; -import StudipIcon from '../StudipIcon.vue'; -import TreeNodeCourseInfo from './TreeNodeCourseInfo.vue'; -import TreeCourseDetails from "./TreeCourseDetails.vue"; import AssignLinkWidget from "./AssignLinkWidget.vue"; +import StudipPagination from "../StudipPagination.vue"; +import StudipTreeTableRows from "./StudipTreeTableRows.vue"; +import TreeCourseDetails from "./TreeCourseDetails.vue"; +import StudipIcon from "../StudipIcon.vue"; export default { name: 'StudipTreeTable', components: { - draggable, TreeExportWidget, TreeCourseDetails, StudipIcon, StudipProgressIndicator, TreeBreadcrumb, - TreeNodeCourseInfo, AssignLinkWidget + StudipIcon, TreeCourseDetails, + StudipTreeTableRows, + StudipPagination, + draggable, TreeExportWidget, StudipProgressIndicator, TreeBreadcrumb, + AssignLinkWidget }, mixins: [ TreeMixin ], + emits: ['change-current-node'], props: { node: { type: Object, @@ -302,8 +307,8 @@ export default { this.decreasePosition(index); this.$nextTick(() => { this.$refs['draghandle-' + (index - 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), + this.assistiveLive = this.$gettext( + 'Aktuelle Position in der Liste: %{pos} von %{listLength}.', { pos: index, listLength: this.children.length } ); }); @@ -313,8 +318,8 @@ export default { this.increasePosition(index); this.$nextTick(function () { this.$refs['draghandle-' + (index + 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), + this.assistiveLive = this.$gettext( + 'Aktuelle Position in der Liste: %{pos} von %{listLength}.', { pos: index + 2, listLength: this.children.length } ); }); @@ -410,7 +415,7 @@ export default { semesterForm.appendChild(nodeField); }); }, - beforeDestroy() { + beforeUnmount() { STUDIP.eventBus.off('open-tree-node'); STUDIP.eventBus.off('load-tree-node'); STUDIP.eventBus.off('sort-tree-children'); diff --git a/resources/vue/components/tree/StudipTreeTableRows.vue b/resources/vue/components/tree/StudipTreeTableRows.vue new file mode 100644 index 0000000000000000000000000000000000000000..e13b97d82fe4e2c08baf5ae66310f47d2ae6c9e6 --- /dev/null +++ b/resources/vue/components/tree/StudipTreeTableRows.vue @@ -0,0 +1,66 @@ +<template> + <tr v-bind="$attrs" class="studip-tree-child"> + <td> + <a v-if="editable && children.length > 1" class="drag-link" role="option" + tabindex="0" + :title="$gettext('Sortierelement für Element %{node}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.', {node: element.attributes.name}, true)" + @keydown="keyHandler($event, index)" + :ref="'draghandle-' + index"> + <span class="drag-handle"></span> + </a> + </td> + <td> + <a :href="nodeUrl(element.id, semester !== 'all' ? semester : null)" tabindex="0" + @click.prevent="$emit('open:node', element)" + :title="$gettext( + 'Unterebene %{ node } öffnen', + { node: node.attributes.name }, + true + )" + > + <studip-icon :shape="element.attributes['has-children'] ? 'folder-full' : 'folder-empty'" + :size="26"></studip-icon> + </a> + </td> + <td> + <a :href="nodeUrl(element.id, semester !== 'all' ? semester : null)" tabindex="0" + @click.prevent="$emit('open:node', element)" + :title="$gettext( + 'Unterebene %{ node } öffnen', + { node: node.attributes.name }, + true + )" + > + {{ element.attributes.name }} + </a> + </td> + <td> + <tree-node-course-info v-if="node.attributes.ancestors.length > 2" + :node="element" + :semester="semester" + :sem-class="semClass" + ></tree-node-course-info> + </td> + </tr> +</template> +<script> +import StudipIcon from "../StudipIcon.vue"; +import TreeNodeCourseInfo from "./TreeNodeCourseInfo.vue"; +import {TreeMixin} from "../../mixins/TreeMixin"; + +export default { + name: 'studip-tree-table-rows', + components: { StudipIcon, TreeNodeCourseInfo}, + emits: ['open:node'], + mixins: [ TreeMixin ], + props: { + children: Array, + editable: Boolean, + element: Object, + index: Number, + semester: String, + semClass: Number, + node: Object, + } +}; +</script> diff --git a/resources/vue/components/tree/TreeBreadcrumb.vue b/resources/vue/components/tree/TreeBreadcrumb.vue index 4ba4664d07eb8a13998d78fe59cfd8d27981e66c..00486dfd9bc9c4b4861ffdbf457e6f1b5e30f1d2 100644 --- a/resources/vue/components/tree/TreeBreadcrumb.vue +++ b/resources/vue/components/tree/TreeBreadcrumb.vue @@ -10,7 +10,7 @@ <a :href="nodeUrl(ancestor.classname + '_' + ancestor.id)" :ref="ancestor.id" @click.prevent="openNode(ancestor.id, ancestor.classname)" tabindex="0" :id="'tree-breadcrumb-' + ancestor.id" - :title="$gettextInterpolate($gettext('%{ node } öffnen'), { node: ancestor.name}, true)"> + :title="$gettext('%{ node } öffnen', { node: ancestor.name}, true)"> {{ ancestor.name }} </a> <template v-if="index !== node.attributes.ancestors.length - 1"> @@ -157,7 +157,9 @@ export default { STUDIP.Dialog.fromURL(this.editUrl + '/' + node.id, { data: { from: this.nodeUrl(node.id) }}); }, deleteNode(node) { - let text = this.$gettext('Sind sie sicher, dass der Eintrag "%{ node }" gelöscht werden soll?'); + let text = this.$gettext( + 'Sind sie sicher, dass der Eintrag "%{ node }" gelöscht werden soll?', + ); let context = { node: node.attributes.name }; diff --git a/resources/vue/components/tree/TreeCourseDetails.vue b/resources/vue/components/tree/TreeCourseDetails.vue index 020cc330c0d9246622e0a991354ad89b1f1c5936..a6e08b42a48ba66684d07d9191eb34d4ecc14136 100644 --- a/resources/vue/components/tree/TreeCourseDetails.vue +++ b/resources/vue/components/tree/TreeCourseDetails.vue @@ -11,16 +11,19 @@ <div class="course-lecturers"> <span v-for="(lecturer, index) in details.lecturers" :key="index"> <a :href="profileUrl(lecturer.username)" - :title="$gettextInterpolate($gettext('Zum Profil von %{ user }'), - { user: lecturer.name }, true)" + :title="$gettext( + 'Zum Profil von %{ user }', + { user: lecturer.name }, + true + )" tabindex="0"> {{ lecturer.name }} </a><template v-if="details.lecturers.length > 1 && index < details.lecturers.length - 1">, </template> </span> </div> - <MountingPortal :mountTo="'#course-dates-' + course" :append="true"> + <Teleport :to="'#course-dates-' + course" :append="true"> <span v-html="details.dates"></span> - </MountingPortal> + </Teleport> </div> </template> diff --git a/resources/vue/components/tree/TreeNodeCourseInfo.vue b/resources/vue/components/tree/TreeNodeCourseInfo.vue index 859429e76529fb33362866a7010b4ae6b2fc78db..b3a58dad1e8c73f76ef29ddb14decd074638ed6b 100644 --- a/resources/vue/components/tree/TreeNodeCourseInfo.vue +++ b/resources/vue/components/tree/TreeNodeCourseInfo.vue @@ -1,21 +1,27 @@ <template> <div class="studip-tree-child-description"> <studip-loading-skeleton v-if="isLoading" /> - <div v-else v-translate="{ count: courseCount }" :translate-n="courseCount" - translate-plural="<strong>%{count}</strong> Veranstaltungen"> - <strong>Eine</strong> Veranstaltung - </div> + <div v-else + v-html="$ngettext( + '<strong>Eine</strong> Veranstaltung', + '<strong>%{count}</strong> Veranstaltungen', + courseCount, + { count: courseCount } + )" + ></div> </div> </template> <script> import { TreeMixin } from '../../mixins/TreeMixin'; import StudipLoadingSkeleton from '../StudipLoadingSkeleton.vue'; +import {$ngettext} from "../../../assets/javascripts/lib/gettext"; export default { name: 'TreeNodeCourseInfo', components: { StudipLoadingSkeleton }, mixins: [ TreeMixin ], + emits: ['showAllCourses'], props: { node: { type: Object, @@ -42,6 +48,7 @@ export default { } }, methods: { + $ngettext, showAllCourses(state) { this.showingAllCourses = state; this.$emit('showAllCourses', state); diff --git a/resources/vue/components/tree/TreeNodeTile.vue b/resources/vue/components/tree/TreeNodeTile.vue index 698cc25c024845440f6d9d0d12a731ad34192929..fb1edd354df1cc3e12a6feda9b1ed4e69e4fada9 100644 --- a/resources/vue/components/tree/TreeNodeTile.vue +++ b/resources/vue/components/tree/TreeNodeTile.vue @@ -1,11 +1,17 @@ <template> - <a :href="url" @click.prevent="openNode" :title="$gettextInterpolate($gettext('Unterebene %{ node } öffnen'), - { node: node.attributes.name }, true)"> + <a :href="url" + @click.prevent="openNode" + :title="$gettext( + 'Unterebene %{ node } öffnen', + { node: node.attributes.name }, + true + )" + > <p class="studip-tree-child-title"> {{ node.attributes.name }} </p> - <tree-node-course-info v-if="node.attributes.ancestors.length > 2" + <tree-node-course-info v-if="node.attributes.ancestors.length > 2" :node="node" :semester="semester" :sem-class="semClass" diff --git a/resources/vue/components/tree/TreeSearchResult.vue b/resources/vue/components/tree/TreeSearchResult.vue index 20a73ca392e5ec52f9ad3941f08f26e0bd44aa99..0f615b41c6ed104fd9bf70f9ad9f8144b432c4b5 100644 --- a/resources/vue/components/tree/TreeSearchResult.vue +++ b/resources/vue/components/tree/TreeSearchResult.vue @@ -8,9 +8,15 @@ <table v-if="courses.length > 0" class="default studip-tree-table"> <caption> <studip-icon shape="search"></studip-icon> - {{ $gettextInterpolate($ngettext('Ein Eintrag für den Begriff "%{searchterm}" gefunden', - '%{count} Einträge für den Begriff "%{searchterm}" gefunden', courses.length), - { count: courses.length, searchterm: searchConfig.searchterm}) }} + {{ $ngettext( + 'Ein Eintrag für den Begriff "%{searchterm}" gefunden', + '%{count} Einträge für den Begriff "%{searchterm}" gefunden', + courses.length, + { + count: courses.length, + searchterm: searchConfig.searchterm + } + ) }} </caption> <colgroup> <col style="width: 30px"> @@ -31,7 +37,7 @@ </td> <td> <a :href="courseUrl(course.id)" - :title="$gettextInterpolate($gettext('Zur Veranstaltung %{title}'), {title: course.attributes.title}, true)" + :title="$gettext('Zur Veranstaltung %{title}', {title: course.attributes.title}, true)" tabindex="0"> <template v-if="course.attributes['course-number']"> {{ course.attributes['course-number'] }} @@ -49,8 +55,10 @@ </tbody> </table> <studip-message-box v-else type="info"> - {{ $gettextInterpolate($gettext('Es wurden keine Ergebnisse zu Ihrem Suchbegriff "%{term}" gefunden.'), - { term: searchConfig.searchterm }) }} + {{ $gettext( + 'Es wurden keine Ergebnisse zu Ihrem Suchbegriff "%{term}" gefunden.', + { term: searchConfig.searchterm } + ) }} </studip-message-box> </article> </template> @@ -84,9 +92,9 @@ export default { }, computed: { searchDescription() { - return this.$gettextInterpolate( - this.$gettext('Suche nach dem Begriff "%{ term }"'), - {term: this.searchConfig.searchterm} + return this.$gettext( + 'Suche nach dem Begriff "%{ term }"', + { term: this.searchConfig.searchterm } ); } }, diff --git a/resources/vue/courseware-activities-app.js b/resources/vue/courseware-activities-app.js index 3122238c5a47c70bd86d26257cf5c97e41733196..858082faf771c3c0348fed924dea2f179c9b161a 100644 --- a/resources/vue/courseware-activities-app.js +++ b/resources/vue/courseware-activities-app.js @@ -1,12 +1,11 @@ import ActivitiesApp from './components/courseware/ActivitiesApp.vue'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; -import Vuex from 'vuex'; import CoursewareModule from './store/courseware/courseware.module'; import CoursewareActivitiesModule from './store/courseware/courseware-activities.module'; import CoursewareStructureModule from './store/courseware/structure.module'; import axios from 'axios'; +import { h } from "vue"; -const mountApp = async (STUDIP, createApp, element) => { +const mountApp = async (STUDIP, createApp, store, element) => { const getHttpClient = () => axios.create({ baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), @@ -17,43 +16,10 @@ const mountApp = async (STUDIP, createApp, element) => { const httpClient = getHttpClient(); - const store = new Vuex.Store({ - modules: { - courseware: CoursewareModule, - 'courseware-structure': CoursewareStructureModule, - 'courseware-activities': CoursewareActivitiesModule, - ...mapResourceModules({ - names: [ - 'activities', - 'users', - 'courses', - 'course-memberships', - 'courseware-blocks', - 'courseware-block-comments', - 'courseware-block-feedback', - 'courseware-containers', - 'courseware-instances', - 'courseware-structural-elements', - 'courseware-task-feedback', - 'courseware-task-groups', - 'courseware-tasks', - 'courseware-units', - 'courseware-user-data-fields', - 'courseware-user-progresses', - 'files', - 'file-refs', - 'folders', - 'users', - 'institutes', - 'semesters', - 'sem-classes', - 'sem-types', - 'status-groups', - ], - httpClient, - }), - }, - }); + store.registerModule('courseware', CoursewareModule); + store.registerModule('courseware-structure', CoursewareStructureModule); + store.registerModule('courseware-activities', CoursewareActivitiesModule); + let entry_id = null; let entry_type = null; let elem; @@ -80,11 +46,9 @@ const mountApp = async (STUDIP, createApp, element) => { await store.dispatch('loadCourseUnits', entry_id); const app = createApp({ - render: (h) => h(ActivitiesApp), - store, + render: () => h(ActivitiesApp), }); - - app.$mount(element); + app.mount(element); return app; }; diff --git a/resources/vue/courseware-admin-app.js b/resources/vue/courseware-admin-app.js index 2ca74549a14517467f13584954beaa54370ed5c2..57164a34e8343b786dde5a54b13befcebdfb6ad4 100644 --- a/resources/vue/courseware-admin-app.js +++ b/resources/vue/courseware-admin-app.js @@ -1,42 +1,18 @@ import AdminApp from './components/courseware/AdminApp.vue'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; -import Vuex from 'vuex'; import CoursewareAdminModule from './store/courseware/courseware-admin.module'; -import axios from 'axios'; +import { h } from "vue"; -const mountApp = (STUDIP, createApp, element) => { - const getHttpClient = () => - axios.create({ - baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), - headers: { - 'Content-Type': 'application/vnd.api+json', - }, - }); - - const httpClient = getHttpClient(); - - const store = new Vuex.Store({ - modules: { - courseware: CoursewareAdminModule, - ...mapResourceModules({ - names: [ - 'courseware-templates', - ], - httpClient, - }), - }, - }); +const mountApp = (STUDIP, createApp, store, element) => { + store.registerModule('courseware', CoursewareAdminModule); store.dispatch('courseware-templates/loadAll'); const app = createApp({ - render: (h) => h(AdminApp), - store + render: () => h(AdminApp), }); - - app.$mount(element); + app.mount(element); return app; } -export default mountApp; \ No newline at end of file +export default mountApp; diff --git a/resources/vue/courseware-comments-app.js b/resources/vue/courseware-comments-app.js index 0e9a4ba430c0403a76b8e6831bf29677848fbf3a..370cc28fb8ecef35349ec8794eb5c69ef4254a0a 100644 --- a/resources/vue/courseware-comments-app.js +++ b/resources/vue/courseware-comments-app.js @@ -1,10 +1,9 @@ import CoursewareCommentsModule from './store/courseware/courseware-comments.module'; import CommentsApp from './components/courseware/CommentsApp.vue'; -import Vuex from 'vuex'; import axios from 'axios'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; +import { h } from "vue"; -const mountApp = async (STUDIP, createApp, element) => { +const mountApp = async (STUDIP, createApp, store, element) => { const getHttpClient = () => axios.create({ baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), @@ -30,28 +29,8 @@ const mountApp = async (STUDIP, createApp, element) => { const httpClient = getHttpClient(); - const store = new Vuex.Store({ - modules: { - 'courseware-comments': CoursewareCommentsModule, - ...mapResourceModules({ - names: [ - 'courseware-blocks', - 'courseware-block-comments', - 'courseware-block-feedback', - 'courseware-containers', - 'courseware-units', - 'courseware-structural-elements', - 'courseware-structural-element-comments', - 'courseware-structural-element-feedback', - 'users', - 'course-memberships', - 'institutes', - 'institute-memberships', - ], - httpClient, - }), - }, - }); + store.registerModule('courseware-comments', CoursewareCommentsModule); + store.dispatch('setHttpClient', httpClient); store.dispatch('setContext', { id: entry_id, @@ -104,11 +83,9 @@ const mountApp = async (STUDIP, createApp, element) => { ); const app = createApp({ - render: (h) => h(CommentsApp), - store, + render: () => h(CommentsApp), }); - - app.$mount(element); + app.mount(element); }; export default mountApp; diff --git a/resources/vue/courseware-content-bookmark-app.js b/resources/vue/courseware-content-bookmark-app.js index 6d7eed95e32170664abc8107a2948fdaae9259c8..7a05033af69466409a9eb97165fefc7a623912b3 100644 --- a/resources/vue/courseware-content-bookmark-app.js +++ b/resources/vue/courseware-content-bookmark-app.js @@ -1,10 +1,9 @@ import ContentBookmarkApp from './components/courseware/ContentBookmarkApp.vue'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; -import Vuex from 'vuex'; import CoursewareModule from './store/courseware/courseware.module'; import axios from 'axios'; +import { h } from "vue"; -const mountApp = (STUDIP, createApp, element) => { +const mountApp = (STUDIP, createApp, store, element) => { const getHttpClient = () => axios.create({ baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), @@ -15,35 +14,8 @@ const mountApp = (STUDIP, createApp, element) => { const httpClient = getHttpClient(); - const store = new Vuex.Store({ - modules: { - courseware: CoursewareModule, - ...mapResourceModules({ - names: [ - 'activities', - 'file-refs', - 'courses', - 'course-memberships', - 'courseware-blocks', - 'courseware-block-comments', - 'courseware-block-feedback', - 'courseware-containers', - 'courseware-instances', - 'courseware-structural-elements', - 'courseware-units', - 'courseware-user-data-fields', - 'courseware-user-progresses', - 'institutes', - 'semesters', - 'sem-classes', - 'sem-types', - 'status-groups', - 'users', - ], - httpClient, - }), - }, - }); + store.registerModule('courseware', CoursewareModule); + let entry_id = null; let entry_type = null; let elem; @@ -70,11 +42,9 @@ const mountApp = (STUDIP, createApp, element) => { }); const app = createApp({ - render: (h) => h(ContentBookmarkApp), - store + render: () => h(ContentBookmarkApp), }); - - app.$mount(element); + app.mount(element); return app; } diff --git a/resources/vue/courseware-content-releases-app.js b/resources/vue/courseware-content-releases-app.js index 79d56cced2aceb6f4177046ce50912c9b0581471..27784c30e806869b42d8f02d489cd4ed5814b6cb 100644 --- a/resources/vue/courseware-content-releases-app.js +++ b/resources/vue/courseware-content-releases-app.js @@ -1,36 +1,24 @@ import ContentReleasesApp from './components/courseware/ContentReleasesApp.vue'; import CoursewareModule from './store/courseware/courseware.module'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; -import Vuex from 'vuex'; -import axios from 'axios'; +import { h } from "vue"; +import {mapResourceModules} from "../assets/javascripts/lib/reststate-vuex"; +import axios from "axios"; -const mountApp = (STUDIP, createApp, element) => { +const mountApp = (STUDIP, createApp, store, element) => { const getHttpClient = () => - axios.create({ - baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), - headers: { - 'Content-Type': 'application/vnd.api+json', - }, - }); - - const httpClient = getHttpClient(); + axios.create({ + baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), + headers: { + 'Content-Type': 'application/vnd.api+json', + }, + }); + + store.registerModule('courseware', CoursewareModule); + Object.entries(mapResourceModules({ + names: ['courseware-structural-elements-released'], + httpClient: getHttpClient() + })).forEach(([name, module]) => store.registerModule(name, module)); - const store = new Vuex.Store({ - modules: { - courseware: CoursewareModule, - ...mapResourceModules({ - names: [ - 'courseware-containers', - 'courseware-public-links', - 'courseware-structural-elements', - 'courseware-structural-elements-released', - 'file-refs', - 'users', - ], - httpClient, - }), - }, - }); let entry_id = null; let entry_type = null; let elem = document.getElementById(element.substring(1)); @@ -61,11 +49,9 @@ const mountApp = (STUDIP, createApp, element) => { store.dispatch('courseware-structural-elements-released/loadAll', {}); const app = createApp({ - render: (h) => h(ContentReleasesApp), - store + render: () => h(ContentReleasesApp), }); - - app.$mount(element); + app.mount(element); return app; } diff --git a/resources/vue/courseware-index-app.js b/resources/vue/courseware-index-app.js index a82dc9888a210b2cd29c9a837377253cebf203ff..79679fb5d977bf44677bd6196653c821a3ef64e7 100644 --- a/resources/vue/courseware-index-app.js +++ b/resources/vue/courseware-index-app.js @@ -5,22 +5,11 @@ import CoursewareStructuralElement from './components/courseware/structural-elem import CoursewareTasksModule from './store/courseware/courseware-tasks.module'; import IndexApp from './components/courseware/IndexApp.vue'; import PluginManager from './components/courseware/plugin-manager.js'; -import Vue from 'vue'; -import VueRouter from 'vue-router'; -import Vuex from 'vuex'; -import axios from 'axios'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; import { StockImagesPlugin } from './plugins/stock-images.js'; +import { createRouter, createWebHashHistory } from 'vue-router'; +import { h } from "vue"; -const mountApp = async (STUDIP, createApp, element) => { - const getHttpClient = () => - axios.create({ - baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), - headers: { - 'Content-Type': 'application/vnd.api+json', - }, - }); - +const mountApp = async (STUDIP, c, store, element) => { // get id of parent structural element let elem_id = null; let entry_id = null; @@ -58,6 +47,18 @@ const mountApp = async (STUDIP, createApp, element) => { } } } + + const { createApp, httpClient } = await STUDIP.Vue.load(); + + let base = new URL( + STUDIP.URLHelper.parameters.cid + ? STUDIP.URLHelper.getURL('dispatch.php/course/courseware/courseware/' + unit_id, { cid: STUDIP.URLHelper.parameters.cid }, true) + : STUDIP.URLHelper.getURL('dispatch.php/contents/courseware/courseware/' + unit_id) + ); + if (entry_type === 'courses') { + base.search += '&'; + } + const routes = [ { path: '/', @@ -70,77 +71,23 @@ const mountApp = async (STUDIP, createApp, element) => { }, ]; - let base = new URL( - STUDIP.URLHelper.parameters.cid - ? STUDIP.URLHelper.getURL('dispatch.php/course/courseware/courseware/' + unit_id, { cid: STUDIP.URLHelper.parameters.cid }, true) - : STUDIP.URLHelper.getURL('dispatch.php/contents/courseware/courseware/' + unit_id) - ); - if (entry_type === 'courses') { - base.search += '&'; - } - const router = new VueRouter({ - base: `${base.pathname}${base.search}`, - routes, - }); - const httpClient = getHttpClient(); - - const store = new Vuex.Store({ - modules: { - courseware: CoursewareModule, - 'courseware-structure': CoursewareStructureModule, - 'file-chooser': FileChooserStore, - 'tasks': CoursewareTasksModule, - ...mapResourceModules({ - names: [ - 'courses', - 'course-memberships', - 'courseware-blocks', - 'courseware-block-comments', - 'courseware-block-feedback', - 'courseware-clipboards', - 'courseware-containers', - 'courseware-instances', - 'courseware-public-links', - 'courseware-structural-elements', - 'courseware-structural-element-comments', - 'courseware-structural-element-feedback', - 'courseware-task-feedback', - 'courseware-task-groups', - 'courseware-tasks', - 'courseware-templates', - 'courseware-user-data-fields', - 'courseware-user-progresses', - 'courseware-units', - 'feedback-elements', - 'feedback-entries', - 'files', - 'file-refs', - 'folders', - 'lti-tools', - 'status-groups', - 'users', - 'institutes', - 'institute-memberships', - 'semesters', - 'sem-classes', - 'sem-types', - 'terms-of-use', - 'user-data-field', - 'studip-properties' - ], - httpClient, - }), - }, + const router = createRouter({ + history: createWebHashHistory(base.toString()), + routes }); - axios.get( - STUDIP.URLHelper.getURL('jsonapi.php/v1/studip/properties', {}, true) - ).then(response => { - response.data.data.forEach(prop => { - store.dispatch('studip-properties/storeRecord', prop); + store.registerModule('courseware', CoursewareModule); + store.registerModule('courseware-structure', CoursewareStructureModule); + store.registerModule('file-chooser', FileChooserStore); + store.registerModule('tasks', CoursewareTasksModule); + + httpClient.get('studip/properties') + .then(response => { + response.data.data.forEach(prop => { + store.dispatch('studip-properties/storeRecord', prop); + }); }); - }); store.dispatch('setUrlHelper', STUDIP.URLHelper); store.dispatch('setUserId', STUDIP.USER_ID); @@ -177,14 +124,12 @@ const mountApp = async (STUDIP, createApp, element) => { ); const app = createApp({ - render: (h) => h(IndexApp), - router, - store, + render: () => h(IndexApp), }); - Vue.use(StockImagesPlugin, { store }); - - app.$mount(element); + app.use(router); + app.use(StockImagesPlugin, { store }); + app.mount(element); return app; }; diff --git a/resources/vue/courseware-public-app.js b/resources/vue/courseware-public-app.js index 1d50b8ace89ccb393f50845904b645ff71b4c592..c4585224cc02a4a703bd018c5a6cda9d1b507725 100644 --- a/resources/vue/courseware-public-app.js +++ b/resources/vue/courseware-public-app.js @@ -3,13 +3,10 @@ import CoursewarePublicModule from './store/courseware/courseware-public.module' import PublicCoursewareStructuralElement from './components/courseware/structural-element/PublicCoursewareStructuralElement.vue'; import CoursewarePublicStructureModule from './store/courseware/public-structure.module'; import PluginManager from './components/courseware/plugin-manager.js'; -import VueRouter from 'vue-router'; -import Vuex from 'vuex'; -import axios from 'axios'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; -import _ from 'lodash'; +import { createRouter } from 'vue-router'; +import { h } from "vue"; -const mountApp = (STUDIP, createApp, element) => { +const mountApp = (STUDIP, createApp, store, element) => { let elem_id = null; let link_id = null; @@ -37,43 +34,12 @@ const mountApp = (STUDIP, createApp, element) => { } } - const getHttpClient = () => - axios.create({ - baseURL: STUDIP.URLHelper.getURL('jsonapi.php/v1/public/courseware/' + link_id, {}, true), - headers: { - 'Content-Type': 'application/vnd.api+json', - }, - }); - let base = new URL( STUDIP.URLHelper.getURL('dispatch.php/courseware/public', { link: link_id }, true) ); - const httpClient = getHttpClient(); - - const store = new Vuex.Store({ - modules: { - // courseware: CoursewareModule, - 'courseware-public': CoursewarePublicModule, - 'courseware-structure': CoursewarePublicStructureModule, - ...mapResourceModules({ - names: [ - 'courseware-blocks', - 'courseware-containers', - 'courseware-instances', - 'courseware-structural-elements', - 'courseware-user-data-fields', - 'courseware-user-progresses', - 'files', - 'file-refs', - 'folders', - 'users', - ], - httpClient, - }), - }, - }); - + store.registerModule('courseware-public', CoursewarePublicModule); + store.registerModule('courseware-structure', CoursewarePublicStructureModule); store.dispatch('setContext', { id: link_id, type: entry_type, @@ -108,18 +74,16 @@ const mountApp = (STUDIP, createApp, element) => { }, ]; - const router = new VueRouter({ + const router = createRouter({ base: `${base.pathname}${base.search}`, routes, }); const app = createApp({ - render: (h) => h(PublicApp), + render: () => h(PublicApp), router, - store }); - - app.$mount(element); + app.mount(element); return app; } diff --git a/resources/vue/courseware-shelf-app.js b/resources/vue/courseware-shelf-app.js index 35369c1c6d3c5b8ecc8b5f0cfc6791c33caedc71..efbf0ca9cef9743c02c822c91143c2e91fc20c42 100644 --- a/resources/vue/courseware-shelf-app.js +++ b/resources/vue/courseware-shelf-app.js @@ -1,12 +1,10 @@ import CoursewareShelfModule from './store/courseware/courseware-shelf.module'; import ShelfApp from './components/courseware/ShelfApp.vue'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import axios from 'axios'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; +import { resourceModule } from '@/assets/javascripts/lib/reststate-vuex.js'; import { StockImagesPlugin } from './plugins/stock-images.js'; +import { h } from 'vue'; -const mountApp = async (STUDIP, createApp, element) => { +const mountApp = async (STUDIP, c, store, element) => { // handle studip 5.0 to 5.2 urls const elemId = window.location.hash.match(/structural_element\/(\d+)/); @@ -18,14 +16,6 @@ const mountApp = async (STUDIP, createApp, element) => { return false; } - const getHttpClient = () => - axios.create({ - baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), - headers: { - 'Content-Type': 'application/vnd.api+json', - }, - }); - let elem; let entry_id = null; let entry_type = null; @@ -55,42 +45,17 @@ const mountApp = async (STUDIP, createApp, element) => { } } - const httpClient = getHttpClient(); + const { createApp, httpClient } = await STUDIP.Vue.load(); + store.registerModule('courseware-shelf', CoursewareShelfModule); + + store.registerModule( + 'courseware-structural-elements-shared', + resourceModule({ + name: 'courseware-structural-elements-shared', + httpClient + }) + ); - const store = new Vuex.Store({ - modules: { - 'courseware-shelf': CoursewareShelfModule, - ...mapResourceModules({ - names: [ - 'courses', - 'course-memberships', - 'courseware-blocks', - 'courseware-containers', - 'courseware-instances', - 'courseware-units', - 'courseware-user-data-fields', - 'courseware-user-progresses', - 'courseware-structural-elements', - 'courseware-structural-elements-shared', - 'feedback-elements', - 'feedback-entries', - 'files', - 'file-refs', - 'folders', - 'users', - 'institutes', - 'institute-memberships', - 'semesters', - 'sem-classes', - 'sem-types', - 'stock-images', - 'status-groups', - 'terms-of-use' - ], - httpClient, - }), - }, - }); store.dispatch('setUrlHelper', STUDIP.URLHelper); store.dispatch('setHttpClient', httpClient); store.dispatch('setLicenses', licenses); @@ -109,14 +74,11 @@ const mountApp = async (STUDIP, createApp, element) => { await store.dispatch('courseware-structural-elements-shared/loadAll', { options: { include: 'owner' } }); } - Vue.use(StockImagesPlugin, { store }); - const app = createApp({ - render: (h) => h(ShelfApp), - store, + render: () => h(ShelfApp), }); - - app.$mount(element); + app.use(StockImagesPlugin, { store }); + app.mount(element); }; diff --git a/resources/vue/courseware-tasks-app.js b/resources/vue/courseware-tasks-app.js index fc7bf655f3bc5a71807e31ccd5bab3168ca4f26c..df610fa972d745ab6fe4471362382a45edb30445 100644 --- a/resources/vue/courseware-tasks-app.js +++ b/resources/vue/courseware-tasks-app.js @@ -1,14 +1,13 @@ import TaskGroupsIndex from './components/courseware/tasks/PagesTaskGroupsIndex.vue'; import TaskGroupsShow from './components/courseware/tasks/PagesTaskGroupsShow.vue'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; -import VueRouter, { RouterView } from 'vue-router'; -import Vuex from 'vuex'; +import { createRouter, RouterView, createWebHashHistory } from 'vue-router'; import CoursewareModule from './store/courseware/courseware.module'; import CoursewareTasksModule from './store/courseware/courseware-tasks.module'; import CoursewareStructureModule from './store/courseware/structure.module'; import axios from 'axios'; +import {h} from "vue"; -const mountApp = async (STUDIP, createApp, element) => { +const mountApp = async (STUDIP, createApp, store, element) => { const getHttpClient = () => axios.create({ baseURL: STUDIP.URLHelper.getURL(`jsonapi.php/v1`, {}, true), @@ -40,56 +39,22 @@ const mountApp = async (STUDIP, createApp, element) => { true ) ); - const router = new VueRouter({ - base: base.pathname, - mode: 'history', + const router = createRouter({ + history: createWebHashHistory(), routes, }); router.beforeEach((to, from, next) => { - if ('cid' in to?.query) { + if (to?.query?.cid !== undefined) { next(); } else { next({ ...to, query: { ...to.query, cid: window.STUDIP.URLHelper.parameters.cid } }); } }); - const store = new Vuex.Store({ - modules: { - courseware: CoursewareModule, - tasks: CoursewareTasksModule, - 'courseware-structure': CoursewareStructureModule, - ...mapResourceModules({ - names: [ - 'activities', - 'users', - 'courses', - 'course-memberships', - 'courseware-blocks', - 'courseware-block-comments', - 'courseware-block-feedback', - 'courseware-containers', - 'courseware-instances', - 'courseware-structural-elements', - 'courseware-task-feedback', - 'courseware-task-groups', - 'courseware-tasks', - 'courseware-units', - 'courseware-user-data-fields', - 'courseware-user-progresses', - 'files', - 'file-refs', - 'folders', - 'users', - 'institutes', - 'semesters', - 'sem-classes', - 'sem-types', - 'status-groups', - ], - httpClient, - }), - }, - }); + store.registerModule('courseware', CoursewareModule); + store.registerModule('tasks', CoursewareTasksModule); + store.registerModule('courseware-structure', CoursewareStructureModule); + let entry_id = null; let entry_type = null; let isTeacher = false; @@ -122,12 +87,10 @@ const mountApp = async (STUDIP, createApp, element) => { await store.dispatch('tasks/loadTasksOfCourse', { cid: entry_id }); const app = createApp({ - render: (h) => h(RouterView), - router, - store, + render: () => h(RouterView), }); - - app.$mount(element); + app.use(router); + app.mount(element); return app; }; diff --git a/resources/vue/mixins/ContentModulesMixin.js b/resources/vue/mixins/ContentModulesMixin.js index b02561d9ee1060e19208c910f19ee247d7629add..0650342388284fec6c02d5c884c258d30036e4b4 100644 --- a/resources/vue/mixins/ContentModulesMixin.js +++ b/resources/vue/mixins/ContentModulesMixin.js @@ -19,8 +19,13 @@ export default { 'modules', 'view', ]), - activeModules() { - return this.sortedModules.filter(module => module.active); + activeModules: { + get() { + return this.sortedModules.filter(module => module.active); + }, + set(modules) { + this.sortedModules = modules; + } }, inactiveModules() { return this.sortedModules.filter(module => !module.active); diff --git a/resources/vue/mixins/QuestionnaireComponent.js b/resources/vue/mixins/QuestionnaireComponent.js index 277f21c87dde745db62eee0063a2896be1d5ce27..62f8e2d2dd949a2827c84b5e8a942cad614fc160 100644 --- a/resources/vue/mixins/QuestionnaireComponent.js +++ b/resources/vue/mixins/QuestionnaireComponent.js @@ -1,23 +1,26 @@ export const QuestionnaireComponent = { + emits: ['update:modelValue'], props: { - value: Object + modelValue: Object }, data () { - return {val_clone: this.value}; + return { + val_clone: {...this.modelValue} + }; }, methods: { setDefaultValues(value) { - this.val_clone = Object.assign(value, this.value); + this.val_clone = Object.assign(value, this.modelValue); } }, watch: { val_clone: { handler(current) { - this.$emit('input', current); + this.$emit('update:modelValue', current); }, deep: true }, - value (new_val) { + modelValue(new_val) { this.val_clone = new_val; } } diff --git a/resources/vue/mixins/courseware/container.js b/resources/vue/mixins/courseware/container.js index eb5fcaa106dc9ef140bce737bb4d6ca8ed24f0c7..df3ab09b86e44d7c7e473ce783708751febfa9f8 100644 --- a/resources/vue/mixins/courseware/container.js +++ b/resources/vue/mixins/courseware/container.js @@ -16,6 +16,7 @@ const containerMixin = { created: function () { this.pluginManager.registerComponentsLocally(this); }, + emits: ['select'], methods: { ...mapActions({ updateBlock: 'updateBlock', @@ -38,15 +39,15 @@ const containerMixin = { dropBlock(e) { this.isDragging = false; // implemented by each container type let data = {}; - data.originContainerId = e.from.__vue__.$attrs.containerId; - data.targetContainerId = e.to.__vue__.$attrs.containerId; + data.originContainerId = e.from.__vnode.ctx.attrs.containerId; + data.targetContainerId = e.to.__vnode.ctx.attrs.containerId; if (data.originContainerId === data.targetContainerId) { this.storeSort(); // implemented by each container type } else { - data.originSectionId = e.from.__vue__.$attrs.sectionId; - data.originSectionBlockList = e.from.__vue__.$children.map(b => { return b.$attrs.blockId; }); - data.targetSectionId = e.to.__vue__.$attrs.sectionId; - data.targetSectionBlockList = e.to.__vue__.$children.map(b => { return b.$attrs.blockId; }); + data.originSectionId = e.from.__vnode.ctx.attrs.sectionId; + data.originSectionBlockList = e.from.__vnode.children.map(b => { return b.ctx.attrs.blockId; }); + data.targetSectionId = e.to.__vnode.ctx.attrs.sectionId; + data.targetSectionBlockList = e.to.__vnode.children.map(b => { return b.ctx.attrs.blockId; }); data.blockId = e.item._underlying_vm_.id; data.newPos = e.newIndex; const indexInBlockList = data.targetSectionBlockList.findIndex(b => b === data.blockId); @@ -76,7 +77,7 @@ const containerMixin = { targetContainer, ); await this.unlockObject({ id: data.targetContainerId, type: 'courseware-containers' }); - + // update block container id let block = this.blockById({id: data.blockId }); block.relationships.container.data.id = data.targetContainerId; @@ -112,7 +113,7 @@ const containerMixin = { console.log(error); } } - + await this.createBlock({ container: targetContainer, section: section, diff --git a/resources/vue/plugins/blubber.js b/resources/vue/plugins/blubber.js index 5e732aa513069962f79a3f85a9eb0743c6609899..1f41767409fc136693d3e916f57351183512e560 100644 --- a/resources/vue/plugins/blubber.js +++ b/resources/vue/plugins/blubber.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; +import { mapResourceModules } from '@/assets/javascripts/lib/reststate-vuex.js'; import JSUpdater from '@/assets/javascripts/lib/jsupdater.js'; import blubberModule from '../store/blubber.js'; import * as components from '../components/blubber/components.js'; @@ -7,24 +7,24 @@ import * as components from '../components/blubber/components.js'; const JSONAPI_PATH = 'jsonapi.php/v1'; export const BlubberPlugin = { - install(Vue, options = {}) { + install(app, options = {}) { if (!('store' in options)) { throw new Error('You must provide the vuex store via the options argument'); } this.enhanceStore(options.store); - this.registerComponents(Vue); + this.registerComponents(app); this.registerUpdater(options.store); }, enhanceStore(store) { const httpClient = getHttpClient(window.STUDIP.URLHelper.getURL(JSONAPI_PATH, {}, true)); initializeStore(store, httpClient); }, - registerComponents(Vue) { + registerComponents(app) { Object.entries(components).forEach(([name, component]) => { - const exists = Vue.component(name); + const exists = app.component(name); if (!exists) { - Vue.component(name, component); + app.component(name, component); } }); }, diff --git a/resources/vue/plugins/stock-images.js b/resources/vue/plugins/stock-images.js index d99dbb385af16d906dea189099d963c53c01ea0a..63f3c8e1e2ce293daae9a61956473842c51ac938 100644 --- a/resources/vue/plugins/stock-images.js +++ b/resources/vue/plugins/stock-images.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import { mapResourceModules } from '@elan-ev/reststate-vuex'; +import { mapResourceModules } from '@/assets/javascripts/lib/reststate-vuex.js'; import stockImagesModule from '../store/stock-images.js'; import * as components from '../components/stock-images/components.js'; diff --git a/templates/forms/form.php b/templates/forms/form.php index 00e4c7df6d42b04c22c266a7aa3a544689de4fad..93dd49154fe3b04b7f3bd26b126005a72ce0b3fc 100644 --- a/templates/forms/form.php +++ b/templates/forms/form.php @@ -19,75 +19,80 @@ foreach ($allinputs as $input) { } } $form_id = md5(uniqid()); -?><form v-cloak - method="post" - <? if (!$form->isAutoStoring()) : ?> - action="<?= htmlReady($form->getURL()) ?>" - <? else : ?> - data-autosave="<?= htmlReady($_SERVER['REQUEST_URI']) ?>" - data-url="<?= htmlReady($form->getURL()) ?>" - <? endif ?> - @submit="submit" - @cancel="" - novalidate - <?= $form->getDataSecure() ? 'data-secure' : '' ?> - id="<?= htmlReady($form_id) ?>" - data-inputs="<?= htmlReady(json_encode($inputs)) ?>" - data-debugmode="<?= htmlReady(json_encode($form->getDebugMode())) ?>" - data-required="<?= htmlReady(json_encode($required_inputs)) ?>" - data-server_validation="<?= $server_validation ? 1 : 0?>" - data-validation_url="<?= htmlReady($_SERVER['REQUEST_URI']) ?>" - <?= $form->hasFileInput() ? ' enctype="application/x-www-form-urlencoded"' : '' ?> - class="default studipform<?= $form->isCollapsable() ? ' collapsable' : '' ?>"> - - <?= CSRFProtection::tokenTag(['ref' => 'securityToken']) ?> +?> +<div v-cloak + class="studipform" + data-inputs="<?= htmlReady(json_encode($inputs)) ?>" + data-debugmode="<?= htmlReady(json_encode($form->getDebugMode())) ?>" + data-required="<?= htmlReady(json_encode($required_inputs)) ?>" + data-server_validation="<?= $server_validation ? 1 : 0 ?>" + data-validation_url="<?= htmlReady($_SERVER['REQUEST_URI']) ?>" +<? if ($form->isAutoStoring()) : ?> + data-autosave="<?= htmlReady($_SERVER['REQUEST_URI']) ?>" + data-url="<?= htmlReady($form->getURL()) ?>" + <? endif; ?> +> + <form method="post" + <? if (!$form->isAutoStoring()) : ?> + action="<?= htmlReady($form->getURL()) ?>" + <? endif ?> + @submit="submit" + @cancel="" + novalidate + <? if ($form->getDataSecure()): ?> + data-secure + <? endif; ?> + id="<?= htmlReady($form_id) ?>" + class="default <?= $form->isCollapsable() ? ' collapsable' : '' ?>" + <? if ($form->hasFileInput()): ?> + enctype="multipart/form-data" + <? endif; ?> + > + <?= CSRFProtection::tokenTag(['ref' => 'securityToken']) ?> - <article aria-live="assertive" - class="validation_notes studip" - v-if="STUDIPFORM_REQUIRED.length > 0 || STUDIPFORM_VALIDATIONNOTES.length > 0"> - <header> - <h1> - <?= Icon::create('info-circle', Icon::ROLE_INFO)->asImg(['class' => 'text-bottom validation_notes_icon']) ?> - <?= _('Hinweise zum Ausfüllen des Formulars') ?> - </h1> - </header> - <div class="required_note" v-if="STUDIPFORM_REQUIRED.length > 0"> - <div aria-hidden="true"> - <?= _('Pflichtfelder sind mit Sternchen gekennzeichnet.') ?> + <article aria-live="assertive" + class="validation_notes studip" + v-if="STUDIPFORM_REQUIRED.length > 0 || STUDIPFORM_VALIDATIONNOTES.length > 0"> + <header> + <h1> + <?= Icon::create('info-circle', Icon::ROLE_INFO)->asImg(['class' => 'text-bottom validation_notes_icon']) ?> + <?= _('Hinweise zum Ausfüllen des Formulars') ?> + </h1> + </header> + <div class="required_note" v-if="STUDIPFORM_REQUIRED.length > 0"> + <div aria-hidden="true"> + <?= _('Pflichtfelder sind mit Sternchen gekennzeichnet.') ?> + </div> + <div class="sr-only"> + <?= _('Dieses Formular enthält Pflichtfelder.') ?> + </div> </div> - <div class="sr-only"> - <?= _('Dieses Formular enthält Pflichtfelder.') ?> + <div v-if="STUDIPFORM_DISPLAYVALIDATION && (STUDIPFORM_VALIDATIONNOTES.length > 0)"> + <?= _('Folgende Angaben müssen korrigiert werden, um das Formular abschicken zu können:') ?> + <ul> + <li v-for="note in ordererValidationNotes" :aria-describedby="note.describedby"> + {{ note.label.trim() + ": " + note.description }} + </li> + </ul> </div> + </article> + <div aria-live="polite"> + <? + foreach ($form->getParts() as $part) : ?> + <?= $part->renderWithCondition() ?> + <? + endforeach ?> </div> - <div v-if="STUDIPFORM_DISPLAYVALIDATION && (STUDIPFORM_VALIDATIONNOTES.length > 0)"> - <?= _('Folgende Angaben müssen korrigiert werden, um das Formular abschicken zu können:') ?> - <ul> - <li v-for="note in ordererValidationNotes" :aria-describedby="note.describedby">{{ note.label.trim() + ": " + note.description }}</li> - </ul> - </div> - </article> - - <div aria-live="polite"> - <? foreach ($form->getParts() as $part) : ?> - <?= $part->renderWithCondition() ?> - <? endforeach ?> - </div> - <? if (!Request::isDialog()) : ?> - <footer> - <?= \Studip\Button::createAccept($form->getSaveButtonText(), $form->getSaveButtonName(), ['form' => $form_id]) ?> - <?= \Studip\LinkButton::createCancel($form->getCancelButtonText(), $form->getCancelButtonName()) ?> + <footer data-dialog-button> + <?= \Studip\Button::create($form->getSaveButtonText(), $form->getSaveButtonName(), ['form' => $form_id]) ?> + <? foreach ($form->getButtons() as $button): ?> + <? + $button->attributes['form'] = $form_id; + echo $button; + ?> + <? endforeach ?> + <?= \Studip\LinkButton::createCancel($form->getCancelButtonText(), Request::url()) ?> </footer> - <? endif ?> -</form> -<? if (Request::isDialog()) : ?> - <footer data-dialog-button> - <?= \Studip\Button::create($form->getSaveButtonText(), $form->getSaveButtonName(), ['form' => $form_id]) ?> - <? foreach ($form->getButtons() as $button) : ?> - <? - $button->attributes['form'] = $form_id; - echo $button; - ?> - <? endforeach ?> - </footer> -<? endif ?> + </form> +</div> diff --git a/templates/layouts/base.php b/templates/layouts/base.php index b2b665094ccb911977e4408595cc60f8cf923a83..19440b6144fbd0db356d6276782528fa7add0ad7 100644 --- a/templates/layouts/base.php +++ b/templates/layouts/base.php @@ -12,6 +12,17 @@ $getInstalledLanguages = function () { return $languages; }; +$getJsonApiSchemas = function () { + return array_values( + array_unique( + array_map( + fn($class) => $class::TYPE, + app('json-api-integration-schemas') + ) + ) + ); +}; + $lang_attr = str_replace('_', '-', $_SESSION['_language']); ?> <!DOCTYPE html> @@ -57,6 +68,7 @@ $lang_attr = str_replace('_', '-', $_SESSION['_language']); 'PERSONAL_NOTIFICATIONS_AUDIO_DEACTIVATED' => (bool) User::findCurrent()?->getConfiguration()->PERSONAL_NOTIFICATIONS_AUDIO_DEACTIVATED, ]) ?>, + jsonapi_schemas: <?= json_encode($getJsonApiSchemas()) ?>, } </script> diff --git a/webpack.common.js b/webpack.common.js index 4c5b16c981ddb9e9fa88ba3ee208b2a2e0ceec20..9fa316d50be0b961c20d704f30f2dc15a78690d2 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,7 +1,6 @@ -const webpack = require("webpack"); const path = require("path"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const { VueLoaderPlugin } = require('vue-loader'); const ESLintPlugin = require('eslint-webpack-plugin'); const { CKEditorTranslationsPlugin } = require( '@ckeditor/ckeditor5-dev-translations' ); @@ -98,9 +97,6 @@ module.exports = { { test: /\.vue$/, loader: 'vue-loader', - options: { - compiler: require('vue-template-babel-compiler') - } } ] }, @@ -125,7 +121,6 @@ module.exports = { ], resolve: { alias: { - 'vue$': 'vue/dist/vue.esm.js', 'jquery-ui/data': 'jquery-ui/ui/data', 'jquery-ui/disable-selection': 'jquery-ui/ui/disable-selection', 'jquery-ui/focusable': 'jquery-ui/ui/focusable', @@ -146,7 +141,7 @@ module.exports = { 'jquery-ui/widgets/draggable': 'jquery-ui/ui/widgets/draggable', 'jquery-ui/widgets/droppable': 'jquery-ui/ui/widgets/droppable', 'jquery-ui/widgets/resizable': 'jquery-ui/ui/widgets/resizable', - '@': path.resolve(__dirname, 'resources') + '@': path.resolve(__dirname, 'resources'), }, extensions: ['.ts', '.vue', '.js'], fallback: { diff --git a/webpack.dev.js b/webpack.dev.js index 4049f54b28a6a9cd5fb2c3746597b739de813ee1..6d5da00d94b3d7c80e9f2cd8fafb0af053c5274b 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -18,6 +18,11 @@ module.exports = merge(common, { /\.d\.[cm]ts$/ ] }), + new webpack.DefinePlugin({ + __VUE_OPTIONS_API__: 'true', + __VUE_PROD_DEVTOOLS__: 'true', + __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'true' + }), new WebpackNotifierPlugin({ appID: 'Stud.IP Webpack', title: function (params) { diff --git a/webpack.prod.js b/webpack.prod.js index 92d6803622c45d5718e4655c299a128f6a3167ed..6378db502d7fa0b1b28e2074bc31830066ef1001 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -11,6 +11,11 @@ module.exports = merge(common, { optimization: { minimize: true, minimizer: [ + new webpack.DefinePlugin({ + __VUE_OPTIONS_API__: 'true', + __VUE_PROD_DEVTOOLS__: 'false', + __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false' + }), new TerserPlugin( { extractComments: false