diff --git a/.husky/addReferenceTag.js b/.husky/addReferenceTag.js new file mode 100644 index 000000000..b4ee706a0 --- /dev/null +++ b/.husky/addReferenceTag.js @@ -0,0 +1,33 @@ +const fs = require('fs'); +const path = require('path'); + +function getCurrentBranchName(p = process.cwd()) { + if (!fs.existsSync(p)) return false; + + const gitHeadPath = path.join(p, '.git', 'HEAD'); + + if (!fs.existsSync(gitHeadPath)) + return getCurrentBranchName(path.resolve(p, '..')); + + const headContent = fs.readFileSync(gitHeadPath, 'utf-8'); + return headContent.trim().split('/')[2]; +} + +const branchName = getCurrentBranchName(); + +if (branchName) { + const msgPath = `.git/COMMIT_EDITMSG`; + const msg = fs.readFileSync(msgPath, 'utf-8'); + const reference = branchName.match(/^\d+/); + + const referenceTag = `refs #${reference}`; + if (!msg.includes(referenceTag) && reference) { + const splitedMsg = msg.split(':'); + + if (splitedMsg.length > 1) { + const finalMsg = splitedMsg[0] + ': ' + referenceTag + splitedMsg.slice(1).join(':'); + fs.writeFileSync(msgPath, finalMsg); + } + } +} + diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 000000000..0c9a94c64 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,8 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +echo "Running husky commit-msg hook" +npx --no-install commitlint --edit +echo "Adding reference tag to commit message" +node .husky/addReferenceTag.js + diff --git a/CHANGELOG.md b/CHANGELOG.md index 47f2f49d1..86ffce3fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,91 @@ +# Version 24.32 - 2024-08-06 + +### Added 🆕 + +- chore: refs #7197 drop space by:jorgep +- chore: refs #7197 drop useless attr by:jorgep +- chore: refs #7197 fix test by:jorgep +- chore: refs #7197 fix tests by:jorgep +- chore: refs #7197 fix unit tests by:jorgep +- chore: refs #7197 idrop useless class by:jorgep +- chore: refs #7197 improve form filling in Cypress tests by:jorgep +- chore: refs #7197 remove unused import by:jorgep +- feat: customerPayments card view by:alexm +- feat: refs #6943 lock grid mode by:jorgep +- feat: refs #6943 wip consumption filter by:jorgep +- feat: refs #7197 add correcting filter by:jorgep +- feat: refs #7197 add supplier activities filter option by:jorgep +- feat: refs #7197 summary responsive by:jorgep +- feat: refs #7323 fix descriptors, added VnTable and minor changes by:Jon +- feat: refs #7323 fixed tests, changed calendar styles and fix workerCreate by:Jon +- feat: refs #7356 list & weekly to VnTable and style fixes by:Jon +- feat: refs #7401 add menu options by:pablone +- feat: SalesClientTable by:Javier Segarra +- feat: salesOrderTable by:Javier Segarra +- feat: salesTicketTable by:Javier Segarra +- feat: VnTable SalesTicketTable by:Javier Segarra +- fix: columns style by:alexm + +### Changed 📦 + +- perf: LeftMenu show/hide by:Javier Segarra +- perf: refs #7356 TicketList state column by:Jon +- perf: VnFilterPanel (origin/7323_WorkerMigration_End) by:Javier Segarra +- perf: width SalesTicketsTable by:Javier Segarra +- refactor: #6943 wip use vnTable CustomerCredits by:jorgep +- refactor: CustomerNotifications use VnTable by:alexm +- refactor: CustomerPayments use VnTable by:alexm +- refactor: refs #7014 deleted main files and changed route files by:Jon +- refactor: refs #7014 improved route.js & deleted RouteMain by:Jon +- refactor: refs #7014 refactor <module>Main.vue by:Jon +- refactor: refs #7014 refactor ZoneCard, deleted ZoneMain & created basic tests for functionality by:Jon +- refactor: refs #7197 use invoiceInSearchbar & queryParams by:jorgep +- refactor: refs #7323 hidden column filter proposal by:Jon +- refactor: refs #7356 fixed VnTable filters by:Jon +- refactor: refs #7356 requested changes by:Jon +- refactor: wip use vnTable CustomerCredits by:jorgep + +### Fixed 🛠️ + +- chore: refs #7197 fix test by:jorgep +- chore: refs #7197 fix tests by:jorgep +- chore: refs #7197 fix unit tests by:jorgep +- feat: refs #7323 fix descriptors, added VnTable and minor changes by:Jon +- feat: refs #7323 fixed tests, changed calendar styles and fix workerCreate by:Jon +- feat: refs #7356 list & weekly to VnTable and style fixes by:Jon +- fix(claim): small details (6336-claim-v6) by:alexm +- fix: columns style by:alexm +- fix: customer defaulter add amount order (6943-fixCustomer) by:alexm +- fix: customerDefaulter correct functionality by:alexm +- fix: customerNotifications filter by:alexm +- fix: fix conflicts by:Jon +- fix: refs #6101 fix TicketList by:Jon +- fix: refs #6891 worker tests by:jorgep +- fix: refs #6943 drop padding-left checkbox & create wrap mode vnRow by:jorgep +- fix: refs #6943 prevent undefined by:jorgep +- fix: refs #7014 fix tests by:Jon +- fix: refs #7014 fix wagon module by:Jon +- fix: refs #7197 add url InvoiceInSearchbar by:jorgep +- fix: refs #7197 amount reactivity by:jorgep +- fix: refs #7197 drop character by:jorgep +- fix: refs #7197 reactivity invoiceCorrection by:jorgep +- fix: refs #7197 responsive summary layout by:jorgep +- fix: refs #7197 rollback by:jorgep +- fix: refs #7197 rollback crudModel by:jorgep +- fix: refs #7197 setInvoiceInCorrecition by:jorgep +- fix: refs #7197 vat, intrastat, filter and list sections by:jorgep +- fix: refs #7323 fix department & email table filter by:Jon +- fix: refs #7323 fixed left filter by:Jon +- fix: refs #7323 fix workerTimeControl form by:Jon +- fix: refs #7401 fix routeForm by:pablone +- fix: refs #7401 remove console.log by:pablone +- fix: refs CAU 207504 fix itemDiary and logs by:Jon +- fix: workerCreate form street field to be always upperCase by:Jon +- hotfix: refs CAU #207614 fix sale.concept field by:Jon +- refactor: refs #7356 fixed VnTable filters by:Jon +- refs #6898 fix by:carlossa +- Ticket expedition initial load fix by:wbuezas + # Version 24.28 - 2024-07-09 ### Added 🆕 diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 000000000..422b19445 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1 @@ +module.exports = { extends: ['@commitlint/config-conventional'] }; diff --git a/package.json b/package.json index 0a66ddb4f..72bada823 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "salix-front", - "version": "24.32.0", + "version": "24.34.0", "description": "Salix frontend", "productName": "Salix", "author": "Verdnatura", @@ -13,7 +13,10 @@ "test:e2e:ci": "cd ../salix && gulp docker && cd ../salix-front && cypress run", "test": "echo \"See package.json => scripts for available tests.\" && exit 0", "test:unit": "vitest", - "test:unit:ci": "vitest run" + "test:unit:ci": "vitest run", + "commitlint": "commitlint --edit", + "prepare": "npx husky install", + "addReferenceTag": "node .husky/addReferenceTag.js" }, "dependencies": { "@quasar/cli": "^2.3.0", @@ -29,6 +32,8 @@ "vue-router": "^4.2.1" }, "devDependencies": { + "@commitlint/cli": "^19.2.1", + "@commitlint/config-conventional": "^19.1.0", "@intlify/unplugin-vue-i18n": "^0.8.1", "@pinia/testing": "^0.1.2", "@quasar/app-vite": "^1.7.3", @@ -41,6 +46,7 @@ "eslint-config-prettier": "^8.8.0", "eslint-plugin-cypress": "^2.13.3", "eslint-plugin-vue": "^9.14.1", + "husky": "^8.0.0", "postcss": "^8.4.23", "prettier": "^2.8.8", "vitest": "^0.31.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index abb1e8c55..e336c39bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,8612 +1,6628 @@ lockfileVersion: '6.0' settings: - autoInstallPeers: true - excludeLinksFromLockfile: false + autoInstallPeers: true + excludeLinksFromLockfile: false dependencies: - '@quasar/cli': - specifier: ^2.3.0 - version: 2.3.0 - '@quasar/extras': - specifier: ^1.16.9 - version: 1.16.9 - axios: - specifier: ^1.4.0 - version: 1.6.7 - chromium: - specifier: ^3.0.3 - version: 3.0.3 - croppie: - specifier: ^2.6.5 - version: 2.6.5 - pinia: - specifier: ^2.1.3 - version: 2.1.7(vue@3.4.19) - quasar: - specifier: ^2.14.5 - version: 2.14.5 - validator: - specifier: ^13.9.0 - version: 13.11.0 - vue: - specifier: ^3.3.4 - version: 3.4.19 - vue-i18n: - specifier: ^9.2.2 - version: 9.9.1(vue@3.4.19) - vue-router: - specifier: ^4.2.1 - version: 4.2.5(vue@3.4.19) + '@quasar/cli': + specifier: ^2.3.0 + version: 2.3.0 + '@quasar/extras': + specifier: ^1.16.9 + version: 1.16.9 + axios: + specifier: ^1.4.0 + version: 1.6.7 + chromium: + specifier: ^3.0.3 + version: 3.0.3 + croppie: + specifier: ^2.6.5 + version: 2.6.5 + pinia: + specifier: ^2.1.3 + version: 2.1.7(typescript@5.5.4)(vue@3.4.19) + quasar: + specifier: ^2.14.5 + version: 2.14.5 + validator: + specifier: ^13.9.0 + version: 13.11.0 + vue: + specifier: ^3.3.4 + version: 3.4.19(typescript@5.5.4) + vue-i18n: + specifier: ^9.2.2 + version: 9.9.1(vue@3.4.19) + vue-router: + specifier: ^4.2.1 + version: 4.2.5(vue@3.4.19) devDependencies: - '@intlify/unplugin-vue-i18n': - specifier: ^0.8.1 - version: 0.8.2(vue-i18n@9.9.1) - '@pinia/testing': - specifier: ^0.1.2 - version: 0.1.3(pinia@2.1.7)(vue@3.4.19) - '@quasar/app-vite': - specifier: ^1.7.3 - version: 1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19) - '@quasar/quasar-app-extension-qcalendar': - specifier: 4.0.0-beta.15 - version: 4.0.0-beta.15 - '@quasar/quasar-app-extension-testing-unit-vitest': - specifier: ^0.4.0 - version: 0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19) - '@vue/test-utils': - specifier: ^2.4.4 - version: 2.4.4(vue@3.4.19) - autoprefixer: - specifier: ^10.4.14 - version: 10.4.17(postcss@8.4.35) - cypress: - specifier: ^13.6.6 - version: 13.6.6 - eslint: - specifier: ^8.41.0 - version: 8.56.0 - eslint-config-prettier: - specifier: ^8.8.0 - version: 8.10.0(eslint@8.56.0) - eslint-plugin-cypress: - specifier: ^2.13.3 - version: 2.15.1(eslint@8.56.0) - eslint-plugin-vue: - specifier: ^9.14.1 - version: 9.21.1(eslint@8.56.0) - postcss: - specifier: ^8.4.23 - version: 8.4.35 - prettier: - specifier: ^2.8.8 - version: 2.8.8 - vitest: - specifier: ^0.31.1 - version: 0.31.4 + '@commitlint/cli': + specifier: ^19.2.1 + version: 19.4.0(@types/node@20.11.19)(typescript@5.5.4) + '@commitlint/config-conventional': + specifier: ^19.1.0 + version: 19.2.2 + '@intlify/unplugin-vue-i18n': + specifier: ^0.8.1 + version: 0.8.2(vue-i18n@9.9.1) + '@pinia/testing': + specifier: ^0.1.2 + version: 0.1.3(pinia@2.1.7)(vue@3.4.19) + '@quasar/app-vite': + specifier: ^1.7.3 + version: 1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19) + '@quasar/quasar-app-extension-qcalendar': + specifier: 4.0.0-beta.15 + version: 4.0.0-beta.15 + '@quasar/quasar-app-extension-testing-unit-vitest': + specifier: ^0.4.0 + version: 0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(typescript@5.5.4)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19) + '@vue/test-utils': + specifier: ^2.4.4 + version: 2.4.4(vue@3.4.19) + autoprefixer: + specifier: ^10.4.14 + version: 10.4.17(postcss@8.4.35) + cypress: + specifier: ^13.6.6 + version: 13.6.6 + eslint: + specifier: ^8.41.0 + version: 8.56.0 + eslint-config-prettier: + specifier: ^8.8.0 + version: 8.10.0(eslint@8.56.0) + eslint-plugin-cypress: + specifier: ^2.13.3 + version: 2.15.1(eslint@8.56.0) + eslint-plugin-vue: + specifier: ^9.14.1 + version: 9.21.1(eslint@8.56.0) + husky: + specifier: ^8.0.0 + version: 8.0.3 + postcss: + specifier: ^8.4.23 + version: 8.4.35 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + vitest: + specifier: ^0.31.1 + version: 0.31.4 packages: - /@aashutoshrathi/word-wrap@1.2.6: - resolution: - { - integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==, - } - engines: { node: '>=0.10.0' } - dev: true - - /@babel/helper-string-parser@7.23.4: - resolution: - { - integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==, - } - engines: { node: '>=6.9.0' } - - /@babel/helper-validator-identifier@7.22.20: - resolution: - { - integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==, - } - engines: { node: '>=6.9.0' } - - /@babel/parser@7.23.9: - resolution: - { - integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==, - } - engines: { node: '>=6.0.0' } - hasBin: true - dependencies: - '@babel/types': 7.23.9 - - /@babel/types@7.23.9: - resolution: - { - integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==, - } - engines: { node: '>=6.9.0' } - dependencies: - '@babel/helper-string-parser': 7.23.4 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - - /@colors/colors@1.5.0: - resolution: - { - integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==, - } - engines: { node: '>=0.1.90' } - requiresBuild: true - dev: true - optional: true - - /@cush/relative@1.0.0: - resolution: - { - integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==, - } - dev: true - - /@cypress/request@3.0.1: - resolution: - { - integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==, - } - engines: { node: '>= 6' } - dependencies: - aws-sign2: 0.7.0 - aws4: 1.12.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - http-signature: 1.3.6 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - performance-now: 2.1.0 - qs: 6.10.4 - safe-buffer: 5.2.1 - tough-cookie: 4.1.3 - tunnel-agent: 0.6.0 - uuid: 8.3.2 - dev: true - - /@cypress/xvfb@1.2.4(supports-color@8.1.1): - resolution: - { - integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==, - } - dependencies: - debug: 3.2.7(supports-color@8.1.1) - lodash.once: 4.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@esbuild/aix-ppc64@0.19.12: - resolution: - { - integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==, - } - engines: { node: '>=12' } - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm64@0.18.20: - resolution: - { - integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm64@0.19.12: - resolution: - { - integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm@0.18.20: - resolution: - { - integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==, - } - engines: { node: '>=12' } - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-arm@0.19.12: - resolution: - { - integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==, - } - engines: { node: '>=12' } - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.18.20: - resolution: - { - integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/android-x64@0.19.12: - resolution: - { - integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.18.20: - resolution: - { - integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-arm64@0.19.12: - resolution: - { - integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.18.20: - resolution: - { - integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/darwin-x64@0.19.12: - resolution: - { - integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64@0.18.20: - resolution: - { - integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-arm64@0.19.12: - resolution: - { - integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.18.20: - resolution: - { - integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/freebsd-x64@0.19.12: - resolution: - { - integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.18.20: - resolution: - { - integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm64@0.19.12: - resolution: - { - integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.18.20: - resolution: - { - integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==, - } - engines: { node: '>=12' } - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-arm@0.19.12: - resolution: - { - integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==, - } - engines: { node: '>=12' } - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.18.20: - resolution: - { - integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==, - } - engines: { node: '>=12' } - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ia32@0.19.12: - resolution: - { - integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==, - } - engines: { node: '>=12' } - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.18.20: - resolution: - { - integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==, - } - engines: { node: '>=12' } - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-loong64@0.19.12: - resolution: - { - integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==, - } - engines: { node: '>=12' } - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.18.20: - resolution: - { - integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==, - } - engines: { node: '>=12' } - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.19.12: - resolution: - { - integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==, - } - engines: { node: '>=12' } - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.18.20: - resolution: - { - integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==, - } - engines: { node: '>=12' } - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.19.12: - resolution: - { - integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==, - } - engines: { node: '>=12' } - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-riscv64@0.18.20: - resolution: - { - integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==, - } - engines: { node: '>=12' } - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: true + + /@babel/code-frame@7.24.7: + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.0 + dev: true + + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.24.7: + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/highlight@7.24.7: + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + dev: true + + /@babel/parser@7.23.9: + resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.9 + + /@babel/types@7.23.9: + resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + + /@commitlint/cli@19.4.0(@types/node@20.11.19)(typescript@5.5.4): + resolution: {integrity: sha512-sJX4J9UioVwZHq7JWM9tjT5bgWYaIN3rC4FP7YwfEwBYiIO+wMyRttRvQLNkow0vCdM0D67r9NEWU0Ui03I4Eg==} + engines: {node: '>=v18'} + hasBin: true + dependencies: + '@commitlint/format': 19.3.0 + '@commitlint/lint': 19.2.2 + '@commitlint/load': 19.4.0(@types/node@20.11.19)(typescript@5.5.4) + '@commitlint/read': 19.4.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - typescript + dev: true + + /@commitlint/config-conventional@19.2.2: + resolution: {integrity: sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-conventionalcommits: 7.0.2 + dev: true + + /@commitlint/config-validator@19.0.3: + resolution: {integrity: sha512-2D3r4PKjoo59zBc2auodrSCaUnCSALCx54yveOFwwP/i2kfEAQrygwOleFWswLqK0UL/F9r07MFi5ev2ohyM4Q==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + ajv: 8.12.0 + dev: true + + /@commitlint/ensure@19.0.3: + resolution: {integrity: sha512-SZEpa/VvBLoT+EFZVb91YWbmaZ/9rPH3ESrINOl0HD2kMYsjvl0tF7nMHh0EpTcv4+gTtZBAe1y/SS6/OhfZzQ==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + lodash.camelcase: 4.3.0 + lodash.kebabcase: 4.1.1 + lodash.snakecase: 4.1.1 + lodash.startcase: 4.4.0 + lodash.upperfirst: 4.3.1 + dev: true + + /@commitlint/execute-rule@19.0.0: + resolution: {integrity: sha512-mtsdpY1qyWgAO/iOK0L6gSGeR7GFcdW7tIjcNFxcWkfLDF5qVbPHKuGATFqRMsxcO8OUKNj0+3WOHB7EHm4Jdw==} + engines: {node: '>=v18'} + dev: true + + /@commitlint/format@19.3.0: + resolution: {integrity: sha512-luguk5/aF68HiF4H23ACAfk8qS8AHxl4LLN5oxPc24H+2+JRPsNr1OS3Gaea0CrH7PKhArBMKBz5RX9sA5NtTg==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + dev: true + + /@commitlint/is-ignored@19.2.2: + resolution: {integrity: sha512-eNX54oXMVxncORywF4ZPFtJoBm3Tvp111tg1xf4zWXGfhBPKpfKG6R+G3G4v5CPlRROXpAOpQ3HMhA9n1Tck1g==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + semver: 7.6.0 + dev: true + + /@commitlint/lint@19.2.2: + resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/is-ignored': 19.2.2 + '@commitlint/parse': 19.0.3 + '@commitlint/rules': 19.0.3 + '@commitlint/types': 19.0.3 + dev: true + + /@commitlint/load@19.4.0(@types/node@20.11.19)(typescript@5.5.4): + resolution: {integrity: sha512-I4lCWaEZYQJ1y+Y+gdvbGAx9pYPavqZAZ3/7/8BpWh+QjscAn8AjsUpLV2PycBsEx7gupq5gM4BViV9xwTIJuw==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/execute-rule': 19.0.0 + '@commitlint/resolve-extends': 19.1.0 + '@commitlint/types': 19.0.3 + chalk: 5.3.0 + cosmiconfig: 9.0.0(typescript@5.5.4) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.11.19)(cosmiconfig@9.0.0)(typescript@5.5.4) + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + lodash.uniq: 4.5.0 + transitivePeerDependencies: + - '@types/node' + - typescript + dev: true + + /@commitlint/message@19.0.0: + resolution: {integrity: sha512-c9czf6lU+9oF9gVVa2lmKaOARJvt4soRsVmbR7Njwp9FpbBgste5i7l/2l5o8MmbwGh4yE1snfnsy2qyA2r/Fw==} + engines: {node: '>=v18'} + dev: true + + /@commitlint/parse@19.0.3: + resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/types': 19.0.3 + conventional-changelog-angular: 7.0.0 + conventional-commits-parser: 5.0.0 + dev: true + + /@commitlint/read@19.4.0: + resolution: {integrity: sha512-r95jLOEZzKDakXtnQub+zR3xjdnrl2XzerPwm7ch1/cc5JGq04tyaNpa6ty0CRCWdVrk4CZHhqHozb8yZwy2+g==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/top-level': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + git-raw-commits: 4.0.0 + minimist: 1.2.8 + dev: true + + /@commitlint/resolve-extends@19.1.0: + resolution: {integrity: sha512-z2riI+8G3CET5CPgXJPlzftH+RiWYLMYv4C9tSLdLXdr6pBNimSKukYP9MS27ejmscqCTVA4almdLh0ODD2KYg==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/config-validator': 19.0.3 + '@commitlint/types': 19.0.3 + global-directory: 4.0.1 + import-meta-resolve: 4.1.0 + lodash.mergewith: 4.6.2 + resolve-from: 5.0.0 + dev: true + + /@commitlint/rules@19.0.3: + resolution: {integrity: sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==} + engines: {node: '>=v18'} + dependencies: + '@commitlint/ensure': 19.0.3 + '@commitlint/message': 19.0.0 + '@commitlint/to-lines': 19.0.0 + '@commitlint/types': 19.0.3 + execa: 8.0.1 + dev: true + + /@commitlint/to-lines@19.0.0: + resolution: {integrity: sha512-vkxWo+VQU5wFhiP9Ub9Sre0FYe019JxFikrALVoD5UGa8/t3yOJEpEhxC5xKiENKKhUkTpEItMTRAjHw2SCpZw==} + engines: {node: '>=v18'} + dev: true + + /@commitlint/top-level@19.0.0: + resolution: {integrity: sha512-KKjShd6u1aMGNkCkaX4aG1jOGdn7f8ZI8TR1VEuNqUOjWTOdcDSsmglinglJ18JTjuBX5I1PtjrhQCRcixRVFQ==} + engines: {node: '>=v18'} + dependencies: + find-up: 7.0.0 + dev: true + + /@commitlint/types@19.0.3: + resolution: {integrity: sha512-tpyc+7i6bPG9mvaBbtKUeghfyZSDgWquIDfMgqYtTbmZ9Y9VzEm2je9EYcQ0aoz5o7NvGS+rcDec93yO08MHYA==} + engines: {node: '>=v18'} + dependencies: + '@types/conventional-commits-parser': 5.0.0 + chalk: 5.3.0 + dev: true + + /@cush/relative@1.0.0: + resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} + dev: true + + /@cypress/request@3.0.1: + resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==} + engines: {node: '>= 6'} + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + http-signature: 1.3.6 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + performance-now: 2.1.0 + qs: 6.10.4 + safe-buffer: 5.2.1 + tough-cookie: 4.1.3 + tunnel-agent: 0.6.0 + uuid: 8.3.2 + dev: true + + /@cypress/xvfb@1.2.4(supports-color@8.1.1): + resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} + dependencies: + debug: 3.2.7(supports-color@8.1.1) + lodash.once: 4.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@esbuild/aix-ppc64@0.19.12: + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.19.12: + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.19.12: + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.19.12: + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.19.12: + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.19.12: + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.19.12: + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.19.12: + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.19.12: + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.19.12: + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.19.12: + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.19.12: + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.19.12: + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.19.12: + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.19.12: + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.19.12: + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.19.12: + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.19.12: + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.19.12: + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.19.12: + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.19.12: + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.19.12: + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.19.12: + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.56.0 + eslint-visitor-keys: 3.4.3 + dev: true + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@8.1.1) + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.56.0: + resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.2 + debug: 4.3.4(supports-color@8.1.1) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + dev: true + + /@intlify/bundle-utils@4.0.0(vue-i18n@9.9.1): + resolution: {integrity: sha512-klXrYT9VXyKEXsD6UY3pShg0O5MPC07n0TZ5RrSs5ry6T1eZVolIFGJi9c3qcDrh1qjJxgikRnPBmD7qGDqbjw==} + engines: {node: '>= 12'} + peerDependencies: + petite-vue-i18n: '*' + vue-i18n: '*' + peerDependenciesMeta: + petite-vue-i18n: optional: true - - /@esbuild/linux-riscv64@0.19.12: - resolution: - { - integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==, - } - engines: { node: '>=12' } - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + vue-i18n: optional: true - - /@esbuild/linux-s390x@0.18.20: - resolution: - { - integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==, - } - engines: { node: '>=12' } - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true + dependencies: + '@intlify/message-compiler': 10.0.0-beta.5 + '@intlify/shared': 10.0.0-beta.5 + jsonc-eslint-parser: 1.4.1 + source-map: 0.6.1 + vue-i18n: 9.9.1(vue@3.4.19) + yaml-eslint-parser: 0.3.2 + dev: true + + /@intlify/core-base@9.9.1: + resolution: {integrity: sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA==} + engines: {node: '>= 16'} + dependencies: + '@intlify/message-compiler': 9.9.1 + '@intlify/shared': 9.9.1 + + /@intlify/message-compiler@10.0.0-beta.5: + resolution: {integrity: sha512-hLLchnM1dmtSEruerkzvU9vePsLqBXz3RU85SCx/Vd12fFQiymP+/5Rn9MJ8MyfLmIOLDEx4PRh+/GkIQP6oog==} + engines: {node: '>= 16'} + dependencies: + '@intlify/shared': 10.0.0-beta.5 + source-map-js: 1.0.2 + dev: true + + /@intlify/message-compiler@9.9.1: + resolution: {integrity: sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==} + engines: {node: '>= 16'} + dependencies: + '@intlify/shared': 9.9.1 + source-map-js: 1.0.2 + + /@intlify/shared@10.0.0-beta.5: + resolution: {integrity: sha512-g9bq5Y1bOcC9qxtNk4UWtF3sXm6Wh0fGISb7vD5aLyF7yQv7ZFjxQjJzBP2GqG/9+PAGYutqjP1GGadNqFtyAQ==} + engines: {node: '>= 16'} + dev: true + + /@intlify/shared@9.9.1: + resolution: {integrity: sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA==} + engines: {node: '>= 16'} + + /@intlify/unplugin-vue-i18n@0.8.2(vue-i18n@9.9.1): + resolution: {integrity: sha512-cRnzPqSEZQOmTD+p4pwc3RTS9HxreLqfID0keoqZDZweCy/CGRMLLTNd15S4TUf1vSBhPF03DItEFDr1F+8MDA==} + engines: {node: '>= 14.16'} + peerDependencies: + petite-vue-i18n: '*' + vue-i18n: '*' + vue-i18n-bridge: '*' + peerDependenciesMeta: + petite-vue-i18n: optional: true - - /@esbuild/linux-s390x@0.19.12: - resolution: - { - integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==, - } - engines: { node: '>=12' } - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true + vue-i18n: optional: true - - /@esbuild/linux-x64@0.18.20: - resolution: - { - integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + vue-i18n-bridge: optional: true - - /@esbuild/linux-x64@0.19.12: - resolution: - { - integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + dependencies: + '@intlify/bundle-utils': 4.0.0(vue-i18n@9.9.1) + '@intlify/shared': 10.0.0-beta.5 + '@rollup/pluginutils': 4.2.1 + '@vue/compiler-sfc': 3.4.19 + debug: 4.3.4(supports-color@8.1.1) + fast-glob: 3.3.2 + js-yaml: 4.1.0 + json5: 2.2.3 + pathe: 1.1.2 + picocolors: 1.0.0 + source-map: 0.6.1 + unplugin: 1.7.1 + vue-i18n: 9.9.1(vue@3.4.19) + transitivePeerDependencies: + - supports-color + dev: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.22 + dev: true + + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + /@jridgewell/trace-mapping@0.3.22: + resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + dev: true + + /@one-ini/wasm@0.1.1: + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + dev: true + + /@pinia/testing@0.1.3(pinia@2.1.7)(vue@3.4.19): + resolution: {integrity: sha512-D2Ds2s69kKFaRf2KCcP1NhNZEg5+we59aRyQalwRm7ygWfLM25nDH66267U3hNvRUOTx8ofL24GzodZkOmB5xw==} + peerDependencies: + pinia: '>=2.1.5' + dependencies: + pinia: 2.1.7(typescript@5.5.4)(vue@3.4.19) + vue-demi: 0.14.7(vue@3.4.19) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + + /@pnpm/config.env-replace@1.1.0: + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + dev: false + + /@pnpm/network.ca-file@1.0.2: + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + dependencies: + graceful-fs: 4.2.10 + dev: false + + /@pnpm/npm-conf@2.2.2: + resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} + engines: {node: '>=12'} + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + dev: false + + /@quasar/app-vite@1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19): + resolution: {integrity: sha512-pnDInCFP9M1d7lJzS8UkiFq8bGWdekLz8Gu+NLI9UAxruIM9QVlSD4hUmWptTQXaVEvYlDnqfW3LOr57B8eVtw==} + engines: {node: ^24 || ^22 || ^20 || ^18 || ^16 || ^14.19, npm: '>= 6.14.12', yarn: '>= 1.17.3'} + hasBin: true + peerDependencies: + electron-builder: '>= 22' + electron-packager: '>= 15' + eslint: ^8.11.0 + pinia: ^2.0.0 + quasar: ^2.14.0 + vue: ^3.2.29 + vue-router: ^4.0.12 + vuex: ^4.0.0 + workbox-build: '>= 6' + peerDependenciesMeta: + electron-builder: optional: true - - /@esbuild/netbsd-x64@0.18.20: - resolution: - { - integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true + electron-packager: optional: true - - /@esbuild/netbsd-x64@0.19.12: - resolution: - { - integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true + eslint: optional: true - - /@esbuild/openbsd-x64@0.18.20: - resolution: - { - integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true + pinia: optional: true - - /@esbuild/openbsd-x64@0.19.12: - resolution: - { - integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true + vuex: optional: true - - /@esbuild/sunos-x64@0.18.20: - resolution: - { - integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true + workbox-build: optional: true - - /@esbuild/sunos-x64@0.19.12: - resolution: - { - integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true + dependencies: + '@quasar/render-ssr-error': 1.0.3 + '@quasar/vite-plugin': 1.6.0(@vitejs/plugin-vue@2.3.4)(quasar@2.14.5)(vite@2.9.17)(vue@3.4.19) + '@rollup/pluginutils': 4.2.1 + '@types/chrome': 0.0.208 + '@types/compression': 1.7.5 + '@types/cordova': 0.0.34 + '@types/express': 4.17.21 + '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.4.19) + archiver: 5.3.2 + chokidar: 3.6.0 + ci-info: 3.9.0 + compression: 1.7.4 + cross-spawn: 7.0.3 + dot-prop: 6.0.1 + elementtree: 0.1.7 + esbuild: 0.14.51 + eslint: 8.56.0 + express: 4.18.2 + fast-glob: 3.2.12 + fs-extra: 11.2.0 + html-minifier: 4.0.0 + inquirer: 8.2.6 + isbinaryfile: 5.0.2 + kolorist: 1.8.0 + lodash: 4.17.21 + minimist: 1.2.8 + open: 8.4.2 + pinia: 2.1.7(typescript@5.5.4)(vue@3.4.19) + quasar: 2.14.5 + register-service-worker: 1.7.2 + rollup-plugin-visualizer: 5.12.0 + sass: 1.71.1 + semver: 7.6.0 + serialize-javascript: 6.0.2 + table: 6.8.1 + vite: 2.9.17(sass@1.71.1) + vue: 3.4.19(typescript@5.5.4) + vue-router: 4.2.5(vue@3.4.19) + webpack-merge: 5.10.0 + transitivePeerDependencies: + - less + - rollup + - stylus + - supports-color + dev: true + + /@quasar/cli@2.3.0: + resolution: {integrity: sha512-DNFDemicj3jXe5+Ib+5w9Bwj1U3yoHQkqn0bU/qysIl/p0MmGA1yqOfUF0V4fw/5or1dfCvStIA/oZxUcC+2pQ==} + engines: {node: '>= 16', npm: '>= 5.6.0', yarn: '>= 1.6.0'} + hasBin: true + dependencies: + '@quasar/ssl-certificate': 1.0.0 + ci-info: 3.9.0 + compression: 1.7.4 + connect-history-api-fallback: 2.0.0 + cors: 2.8.5 + cross-spawn: 7.0.3 + express: 4.18.2 + fs-extra: 11.2.0 + http-proxy-middleware: 2.0.6 + kolorist: 1.8.0 + minimist: 1.2.8 + open: 9.1.0 + route-cache: 0.5.0 + selfsigned: 2.4.1 + update-notifier: 6.0.2 + transitivePeerDependencies: + - '@types/express' + - debug + - supports-color + dev: false + + /@quasar/extras@1.16.9: + resolution: {integrity: sha512-SlOhwzXyPQHWgQIS2ncyDdYdksCJvUYNtgsDQqzAKEG3r3d/ejOxvThle79HTK3Q6HB+gQWFG21Ux00Osr5XSw==} + dev: false + + /@quasar/quasar-app-extension-qcalendar@4.0.0-beta.15: + resolution: {integrity: sha512-i6hQkcP70LXLfVMPZMKQjSg3681gjZmASV3vq6ULzc0LhtBiPneLdVNNtH2itkWxAmaUj+1heQDI5Pa0F7VKLQ==} + engines: {node: '>= 10.0.0', npm: '>= 5.6.0', yarn: '>= 1.6.0'} + dependencies: + '@quasar/quasar-ui-qcalendar': 4.0.0-beta.19 + dev: true + + /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(typescript@5.5.4)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19): + resolution: {integrity: sha512-eyzdUdmZiCueNS+5nedjMmzdbpCetSrtdGIwW6KplW1dTzRbLiNvYUjpBOxQGmJCgEhWy9zuswJ7MZ/bTql24Q==} + engines: {node: '>= 12.22.1', npm: '>= 6.14.12', yarn: '>= 1.17.3'} + peerDependencies: + '@vitest/ui': ^0.34.0 + '@vue/test-utils': ^2.4.1 + quasar: ^2.12.7 + vitest: ^0.34.0 + vue: ^3.3.4 + peerDependenciesMeta: + '@vitest/ui': optional: true - - /@esbuild/win32-arm64@0.18.20: - resolution: - { - integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + dependencies: + '@vue/test-utils': 2.4.4(vue@3.4.19) + happy-dom: 11.2.0 + lodash-es: 4.17.21 + quasar: 2.14.5 + vite-jsconfig-paths: 2.0.1(vite@5.1.4) + vite-tsconfig-paths: 4.3.1(typescript@5.5.4)(vite@5.1.4) + vitest: 0.31.4 + vue: 3.4.19(typescript@5.5.4) + transitivePeerDependencies: + - supports-color + - typescript + - vite + dev: true + + /@quasar/quasar-ui-qcalendar@4.0.0-beta.19: + resolution: {integrity: sha512-BT0G2JjgKl1bqNrY5utcYeoy8gK+U9k3Pz1YDi1OB265W/jHU6nFoWMEUdY3JdvMccwkXTL2DLVyl3eqAUyLyg==} + dev: true + + /@quasar/render-ssr-error@1.0.3: + resolution: {integrity: sha512-A8RF99q6/sOSe1Ighnh5syEIbliD3qUYEJd2HyfFyBPSMF+WYGXon5dmzg4nUoK662NgOggInevkDyBDJcZugg==} + engines: {node: '>= 16'} + dependencies: + stack-trace: 1.0.0-pre2 + dev: true + + /@quasar/ssl-certificate@1.0.0: + resolution: {integrity: sha512-RhZF7rO76T7Ywer1/5lCe7xl3CIiXxSAH1xgwOj0wcHTityDxJqIN/5YIj6BxMvlFw8XkJDoB1udEQafoVFA4g==} + engines: {node: '>= 16'} + dependencies: + fs-extra: 11.2.0 + selfsigned: 2.4.1 + dev: false + + /@quasar/vite-plugin@1.6.0(@vitejs/plugin-vue@2.3.4)(quasar@2.14.5)(vite@2.9.17)(vue@3.4.19): + resolution: {integrity: sha512-LmbV76G1CwWZbrEQhqyZpkRQTJyO3xpW55aXY1zWN+JhyUeG77CcMCEWteBVnJ6I6ehUPFDC9ONd2+WlwH6rNQ==} + engines: {node: '>=12'} + peerDependencies: + '@vitejs/plugin-vue': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-beta.0 + quasar: ^2.8.0 + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-beta.0 + vue: ^3.0.0 + dependencies: + '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.4.19) + quasar: 2.14.5 + vite: 2.9.17(sass@1.71.1) + vue: 3.4.19(typescript@5.5.4) + dev: true + + /@rollup/pluginutils@4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + + /@rollup/rollup-android-arm-eabi@4.12.0: + resolution: {integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.12.0: + resolution: {integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.12.0: + resolution: {integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.12.0: + resolution: {integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.12.0: + resolution: {integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.12.0: + resolution: {integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.12.0: + resolution: {integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.12.0: + resolution: {integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.12.0: + resolution: {integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.12.0: + resolution: {integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.12.0: + resolution: {integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.12.0: + resolution: {integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.12.0: + resolution: {integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@sindresorhus/is@4.6.0: + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + dev: false + + /@sindresorhus/is@5.6.0: + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + dev: false + + /@szmarczak/http-timer@4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: false + + /@szmarczak/http-timer@5.0.1: + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + dependencies: + defer-to-connect: 2.0.1 + dev: false + + /@types/body-parser@1.19.5: + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.11.19 + dev: true + + /@types/cacheable-request@6.0.3: + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 20.11.19 + '@types/responselike': 1.0.3 + dev: false + + /@types/chai-subset@1.3.5: + resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} + dependencies: + '@types/chai': 4.3.12 + dev: true + + /@types/chai@4.3.12: + resolution: {integrity: sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==} + dev: true + + /@types/chrome@0.0.208: + resolution: {integrity: sha512-VDU/JnXkF5qaI7WBz14Azpa2VseZTgML0ia/g/B1sr9OfdOnHiH/zZ7P7qCDqxSlkqJh76/bPc8jLFcx8rHJmw==} + dependencies: + '@types/filesystem': 0.0.35 + '@types/har-format': 1.2.15 + dev: true + + /@types/compression@1.7.5: + resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==} + dependencies: + '@types/express': 4.17.21 + dev: true + + /@types/connect@3.4.38: + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 20.11.19 + dev: true + + /@types/conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + dependencies: + '@types/node': 20.11.19 + dev: true + + /@types/cordova@0.0.34: + resolution: {integrity: sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA==} + dev: true + + /@types/estree@1.0.5: + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + dev: true + + /@types/express-serve-static-core@4.17.43: + resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} + dependencies: + '@types/node': 20.11.19 + '@types/qs': 6.9.11 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + dev: true + + /@types/express@4.17.21: + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.17.43 + '@types/qs': 6.9.11 + '@types/serve-static': 1.15.5 + dev: true + + /@types/filesystem@0.0.35: + resolution: {integrity: sha512-1eKvCaIBdrD2mmMgy5dwh564rVvfEhZTWVQQGRNn0Nt4ZEnJ0C8oSUCzvMKRA4lGde5oEVo+q2MrTTbV/GHDCQ==} + dependencies: + '@types/filewriter': 0.0.33 + dev: true + + /@types/filewriter@0.0.33: + resolution: {integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==} + dev: true + + /@types/har-format@1.2.15: + resolution: {integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==} + dev: true + + /@types/http-cache-semantics@4.0.4: + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + dev: false + + /@types/http-errors@2.0.4: + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + dev: true + + /@types/http-proxy@1.17.14: + resolution: {integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==} + dependencies: + '@types/node': 20.11.19 + dev: false + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/keyv@3.1.4: + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + dependencies: + '@types/node': 20.11.19 + dev: false + + /@types/mime@1.3.5: + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + dev: true + + /@types/mime@3.0.4: + resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} + dev: true + + /@types/node-forge@1.3.11: + resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} + dependencies: + '@types/node': 20.11.19 + dev: false + + /@types/node@20.11.19: + resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} + dependencies: + undici-types: 5.26.5 + + /@types/qs@6.9.11: + resolution: {integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==} + dev: true + + /@types/range-parser@1.2.7: + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + dev: true + + /@types/responselike@1.0.3: + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + dependencies: + '@types/node': 20.11.19 + dev: false + + /@types/send@0.17.4: + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.11.19 + dev: true + + /@types/serve-static@1.15.5: + resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + dependencies: + '@types/http-errors': 2.0.4 + '@types/mime': 3.0.4 + '@types/node': 20.11.19 + dev: true + + /@types/sinonjs__fake-timers@8.1.1: + resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} + dev: true + + /@types/sizzle@2.3.8: + resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} + dev: true + + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + requiresBuild: true + dependencies: + '@types/node': 20.11.19 + dev: true + optional: true + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: true + + /@vitejs/plugin-vue@2.3.4(vite@5.1.4)(vue@3.4.19): + resolution: {integrity: sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==} + engines: {node: '>=12.0.0'} + peerDependencies: + vite: ^2.5.10 + vue: ^3.2.25 + dependencies: + vite: 5.1.4(@types/node@20.11.19) + vue: 3.4.19(typescript@5.5.4) + dev: true + + /@vitest/expect@0.31.4: + resolution: {integrity: sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==} + dependencies: + '@vitest/spy': 0.31.4 + '@vitest/utils': 0.31.4 + chai: 4.4.1 + dev: true + + /@vitest/runner@0.31.4: + resolution: {integrity: sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==} + dependencies: + '@vitest/utils': 0.31.4 + concordance: 5.0.4 + p-limit: 4.0.0 + pathe: 1.1.2 + dev: true + + /@vitest/snapshot@0.31.4: + resolution: {integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==} + dependencies: + magic-string: 0.30.7 + pathe: 1.1.2 + pretty-format: 27.5.1 + dev: true + + /@vitest/spy@0.31.4: + resolution: {integrity: sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==} + dependencies: + tinyspy: 2.2.1 + dev: true + + /@vitest/utils@0.31.4: + resolution: {integrity: sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==} + dependencies: + concordance: 5.0.4 + loupe: 2.3.7 + pretty-format: 27.5.1 + dev: true + + /@vue/compiler-core@3.4.19: + resolution: {integrity: sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/shared': 3.4.19 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + + /@vue/compiler-dom@3.4.19: + resolution: {integrity: sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==} + dependencies: + '@vue/compiler-core': 3.4.19 + '@vue/shared': 3.4.19 + + /@vue/compiler-sfc@3.4.19: + resolution: {integrity: sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==} + dependencies: + '@babel/parser': 7.23.9 + '@vue/compiler-core': 3.4.19 + '@vue/compiler-dom': 3.4.19 + '@vue/compiler-ssr': 3.4.19 + '@vue/shared': 3.4.19 + estree-walker: 2.0.2 + magic-string: 0.30.7 + postcss: 8.4.35 + source-map-js: 1.0.2 + + /@vue/compiler-ssr@3.4.19: + resolution: {integrity: sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==} + dependencies: + '@vue/compiler-dom': 3.4.19 + '@vue/shared': 3.4.19 + + /@vue/devtools-api@6.6.1: + resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==} + + /@vue/reactivity@3.4.19: + resolution: {integrity: sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==} + dependencies: + '@vue/shared': 3.4.19 + + /@vue/runtime-core@3.4.19: + resolution: {integrity: sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==} + dependencies: + '@vue/reactivity': 3.4.19 + '@vue/shared': 3.4.19 + + /@vue/runtime-dom@3.4.19: + resolution: {integrity: sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==} + dependencies: + '@vue/runtime-core': 3.4.19 + '@vue/shared': 3.4.19 + csstype: 3.1.3 + + /@vue/server-renderer@3.4.19(vue@3.4.19): + resolution: {integrity: sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==} + peerDependencies: + vue: 3.4.19 + dependencies: + '@vue/compiler-ssr': 3.4.19 + '@vue/shared': 3.4.19 + vue: 3.4.19(typescript@5.5.4) + + /@vue/shared@3.4.19: + resolution: {integrity: sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==} + + /@vue/test-utils@2.4.4(vue@3.4.19): + resolution: {integrity: sha512-8jkRxz8pNhClAf4Co4ZrpAoFISdvT3nuSkUlY6Ys6rmTpw3DMWG/X3mw3gQ7QJzgCZO9f+zuE2kW57fi09MW7Q==} + peerDependencies: + '@vue/server-renderer': ^3.0.1 + vue: ^3.0.1 + peerDependenciesMeta: + '@vue/server-renderer': optional: true - - /@esbuild/win32-arm64@0.19.12: - resolution: - { - integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + dependencies: + js-beautify: 1.15.1 + vue: 3.4.19(typescript@5.5.4) + vue-component-type-helpers: 1.8.27 + dev: true + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: true + + /abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + /acorn-jsx@5.3.2(acorn@7.4.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 7.4.1 + dev: true + + /acorn-jsx@5.3.2(acorn@8.11.3): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.3 + dev: true + + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + dependencies: + string-width: 4.2.3 + dev: false + + /ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /arch@2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + dev: true + + /archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 2.3.8 + dev: true + + /archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + dependencies: + glob: 7.2.3 + graceful-fs: 4.2.11 + lazystream: 1.0.1 + lodash.defaults: 4.2.0 + lodash.difference: 4.5.0 + lodash.flatten: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.union: 4.6.0 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + dev: true + + /archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + dependencies: + archiver-utils: 2.1.0 + async: 3.2.5 + buffer-crc32: 0.2.13 + readable-stream: 3.6.2 + readdir-glob: 1.1.3 + tar-stream: 2.2.0 + zip-stream: 4.1.1 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + /array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + dev: true + + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + dev: true + + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + + /astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + + /async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + /at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + dev: true + + /autoprefixer@10.4.17(postcss@8.4.35): + resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.23.0 + caniuse-lite: 1.0.30001588 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.35 + postcss-value-parser: 4.2.0 + dev: true + + /aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: true + + /aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} + dev: true + + /axios@1.6.7: + resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} + dependencies: + follow-redirects: 1.15.5 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + dependencies: + tweetnacl: 0.14.5 + dev: true + + /big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + dev: false + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /blob-util@2.0.2: + resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} + dev: true + + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + + /blueimp-md5@2.19.0: + resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} + dev: true + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} + engines: {node: '>=14.16'} + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.3.0 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + dev: false + + /bplist-parser@0.2.0: + resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} + engines: {node: '>= 5.10.0'} + dependencies: + big-integer: 1.6.52 + dev: false + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001588 + electron-to-chromium: 1.4.677 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) + dev: true + + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: false + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /bundle-name@3.0.0: + resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} + engines: {node: '>=12'} + dependencies: + run-applescript: 5.0.0 + dev: false + + /bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: false + + /cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + dev: false + + /cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.0 + responselike: 3.0.0 + dev: false + + /cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + dev: false + + /cachedir@2.4.0: + resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} + engines: {node: '>=6'} + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camel-case@3.0.0: + resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + dev: true + + /camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + dev: false + + /caniuse-lite@1.0.30001588: + resolution: {integrity: sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==} + dev: true + + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: true + + /chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /check-more-types@2.24.0: + resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} + engines: {node: '>= 0.8.0'} + dev: true + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /chromium@3.0.3: + resolution: {integrity: sha512-TfbzP/3t38Us5xrbb9x87M/y5I/j3jx0zeJhhQ72gjp6dwJuhVP6hBZnBH4wEg7512VVXk9zCfTuPFOdw7bQqg==} + os: [darwin, linux, win32] + requiresBuild: true + dependencies: + cachedir: 2.4.0 + debug: 4.3.4(supports-color@8.1.1) + extract-zip: 1.7.0 + got: 11.8.6 + progress: 2.0.3 + rimraf: 2.7.1 + tmp: 0.0.33 + tunnel: 0.0.6 + transitivePeerDependencies: + - supports-color + dev: false + + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + /clean-css@4.2.4: + resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} + engines: {node: '>= 4.0'} + dependencies: + source-map: 0.6.1 + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + dev: false + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: true + + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + + /cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + + /cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + + /clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + dependencies: + mimic-response: 1.0.1 + dev: false + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + + /commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + dev: true + + /commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + dev: true + + /common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + + /compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + dev: true + + /compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + dependencies: + buffer-crc32: 0.2.13 + crc32-stream: 4.0.3 + normalize-path: 3.0.0 + readable-stream: 3.6.2 + dev: true + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + /concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + dev: false + + /concordance@5.0.4: + resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} + engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} + dependencies: + date-time: 3.1.0 + esutils: 2.0.3 + fast-diff: 1.3.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + md5-hex: 3.0.1 + semver: 7.6.0 + well-known-symbols: 2.0.0 + dev: true + + /config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + /configstore@6.0.0: + resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} + engines: {node: '>=12'} + dependencies: + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 + dev: false + + /connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + dev: false + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + /conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-changelog-conventionalcommits@7.0.2: + resolution: {integrity: sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==} + engines: {node: '>=16'} + dependencies: + compare-func: 2.0.0 + dev: true + + /conventional-commits-parser@5.0.0: + resolution: {integrity: sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==} + engines: {node: '>=16'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + is-text-path: 2.0.0 + meow: 12.1.1 + split2: 4.2.0 + dev: true + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + /core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + /cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + dev: false + + /cosmiconfig-typescript-loader@5.0.0(@types/node@20.11.19)(cosmiconfig@9.0.0)(typescript@5.5.4): + resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} + engines: {node: '>=v16'} + peerDependencies: + '@types/node': '*' + cosmiconfig: '>=8.2' + typescript: '>=4' + dependencies: + '@types/node': 20.11.19 + cosmiconfig: 9.0.0(typescript@5.5.4) + jiti: 1.21.6 + typescript: 5.5.4 + dev: true + + /cosmiconfig@9.0.0(typescript@5.5.4): + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: optional: true - - /@esbuild/win32-ia32@0.18.20: - resolution: - { - integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==, - } - engines: { node: '>=12' } - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + typescript: 5.5.4 + dev: true + + /crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + dev: true + + /crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + dependencies: + crc-32: 1.2.2 + readable-stream: 3.6.2 + dev: true + + /croppie@2.6.5: + resolution: {integrity: sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ==} + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + /crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + dependencies: + type-fest: 1.4.0 + dev: false + + /css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + dev: true + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + /cypress@13.6.6: + resolution: {integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==} + engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} + hasBin: true + requiresBuild: true + dependencies: + '@cypress/request': 3.0.1 + '@cypress/xvfb': 1.2.4(supports-color@8.1.1) + '@types/sinonjs__fake-timers': 8.1.1 + '@types/sizzle': 2.3.8 + arch: 2.2.0 + blob-util: 2.0.2 + bluebird: 3.7.2 + buffer: 5.7.1 + cachedir: 2.4.0 + chalk: 4.1.2 + check-more-types: 2.24.0 + cli-cursor: 3.1.0 + cli-table3: 0.6.3 + commander: 6.2.1 + common-tags: 1.8.2 + dayjs: 1.11.10 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.4.1 + eventemitter2: 6.4.7 + execa: 4.1.0 + executable: 4.1.1 + extract-zip: 2.0.1(supports-color@8.1.1) + figures: 3.2.0 + fs-extra: 9.1.0 + getos: 3.2.1 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + lazy-ass: 1.6.0 + listr2: 3.14.0(enquirer@2.4.1) + lodash: 4.17.21 + log-symbols: 4.1.0 + minimist: 1.2.8 + ospath: 1.2.2 + pretty-bytes: 5.6.0 + process: 0.11.10 + proxy-from-env: 1.0.0 + request-progress: 3.0.0 + semver: 7.6.0 + supports-color: 8.1.1 + tmp: 0.2.1 + untildify: 4.0.0 + yauzl: 2.10.0 + dev: true + + /dargs@8.1.0: + resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} + engines: {node: '>=12'} + dev: true + + /dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + + /date-time@3.1.0: + resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} + engines: {node: '>=6'} + dependencies: + time-zone: 1.0.0 + dev: true + + /dayjs@1.11.10: + resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: optional: true - - /@esbuild/win32-ia32@0.19.12: - resolution: - { - integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==, - } - engines: { node: '>=12' } - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + dependencies: + ms: 2.0.0 + + /debug@3.1.0: + resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: optional: true - - /@esbuild/win32-x64@0.18.20: - resolution: - { - integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + dependencies: + ms: 2.0.0 + dev: false + + /debug@3.2.7(supports-color@8.1.1): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: optional: true - - /@esbuild/win32-x64@0.19.12: - resolution: - { - integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + dependencies: + ms: 2.1.3 + supports-color: 8.1.1 + dev: true + + /debug@4.3.4(supports-color@8.1.1): + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: optional: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): - resolution: - { - integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.56.0 - eslint-visitor-keys: 3.4.3 - dev: true - - /@eslint-community/regexpp@4.10.0: - resolution: - { - integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==, - } - engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } - dev: true - - /@eslint/eslintrc@2.1.4: - resolution: - { - integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - dependencies: - ajv: 6.12.6 - debug: 4.3.4(supports-color@8.1.1) - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@eslint/js@8.56.0: - resolution: - { - integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - dev: true - - /@humanwhocodes/config-array@0.11.14: - resolution: - { - integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==, - } - engines: { node: '>=10.10.0' } - dependencies: - '@humanwhocodes/object-schema': 2.0.2 - debug: 4.3.4(supports-color@8.1.1) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/module-importer@1.0.1: - resolution: - { - integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, - } - engines: { node: '>=12.22' } - dev: true - - /@humanwhocodes/object-schema@2.0.2: - resolution: - { - integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==, - } - dev: true - - /@intlify/bundle-utils@4.0.0(vue-i18n@9.9.1): - resolution: - { - integrity: sha512-klXrYT9VXyKEXsD6UY3pShg0O5MPC07n0TZ5RrSs5ry6T1eZVolIFGJi9c3qcDrh1qjJxgikRnPBmD7qGDqbjw==, - } - engines: { node: '>= 12' } - peerDependencies: - petite-vue-i18n: '*' - vue-i18n: '*' - peerDependenciesMeta: - petite-vue-i18n: - optional: true - vue-i18n: - optional: true - dependencies: - '@intlify/message-compiler': 9.4.1 - '@intlify/shared': 9.4.1 - jsonc-eslint-parser: 1.4.1 - source-map: 0.6.1 - vue-i18n: 9.9.1(vue@3.4.19) - yaml-eslint-parser: 0.3.2 - dev: true - - /@intlify/core-base@9.9.1: - resolution: - { - integrity: sha512-qsV15dg7jNX2faBRyKMgZS8UcFJViWEUPLdzZ9UR0kQZpFVeIpc0AG7ZOfeP7pX2T9SQ5jSiorq/tii9nkkafA==, - } - engines: { node: '>= 16' } - dependencies: - '@intlify/message-compiler': 9.9.1 - '@intlify/shared': 9.9.1 - - /@intlify/message-compiler@9.4.1: - resolution: - { - integrity: sha512-aN2N+dUx320108QhH51Ycd2LEpZ+NKbzyQ2kjjhqMcxhHdxtOnkgdx+MDBhOy/CObwBmhC3Nygzc6hNlfKvPNw==, - } - engines: { node: '>= 16' } - dependencies: - '@intlify/shared': 9.4.1 - source-map-js: 1.0.2 - dev: true - - /@intlify/message-compiler@9.9.1: - resolution: - { - integrity: sha512-zTvP6X6HeumHOXuAE1CMMsV6tTX+opKMOxO1OHTCg5N5Sm/F7d8o2jdT6W6L5oHUsJ/vvkGefHIs7Q3hfowmsA==, - } - engines: { node: '>= 16' } - dependencies: - '@intlify/shared': 9.9.1 - source-map-js: 1.0.2 - - /@intlify/shared@9.4.1: - resolution: - { - integrity: sha512-A51elBmZWf1FS80inf/32diO9DeXoqg9GR9aUDHFcfHoNDuT46Q+fpPOdj8jiJnSHSBh8E1E+6qWRhAZXdK3Ng==, - } - engines: { node: '>= 16' } - dev: true - - /@intlify/shared@9.9.1: - resolution: - { - integrity: sha512-b3Pta1nwkz5rGq434v0psHwEwHGy1pYCttfcM22IE//K9owbpkEvFptx9VcuRAxjQdrO2If249cmDDjBu5wMDA==, - } - engines: { node: '>= 16' } - - /@intlify/unplugin-vue-i18n@0.8.2(vue-i18n@9.9.1): - resolution: - { - integrity: sha512-cRnzPqSEZQOmTD+p4pwc3RTS9HxreLqfID0keoqZDZweCy/CGRMLLTNd15S4TUf1vSBhPF03DItEFDr1F+8MDA==, - } - engines: { node: '>= 14.16' } - peerDependencies: - petite-vue-i18n: '*' - vue-i18n: '*' - vue-i18n-bridge: '*' - peerDependenciesMeta: - petite-vue-i18n: - optional: true - vue-i18n: - optional: true - vue-i18n-bridge: - optional: true - dependencies: - '@intlify/bundle-utils': 4.0.0(vue-i18n@9.9.1) - '@intlify/shared': 9.4.1 - '@rollup/pluginutils': 4.2.1 - '@vue/compiler-sfc': 3.4.19 - debug: 4.3.4(supports-color@8.1.1) - fast-glob: 3.3.2 - js-yaml: 4.1.0 - json5: 2.2.3 - pathe: 1.1.2 - picocolors: 1.0.0 - source-map: 0.6.1 - unplugin: 1.7.1 - vue-i18n: 9.9.1(vue@3.4.19) - transitivePeerDependencies: - - supports-color - dev: true - - /@isaacs/cliui@8.0.2: - resolution: - { - integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, - } - engines: { node: '>=12' } - dependencies: - string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true - - /@jridgewell/gen-mapping@0.3.3: - resolution: - { - integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==, - } - engines: { node: '>=6.0.0' } - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.22 - dev: true - - /@jridgewell/resolve-uri@3.1.2: - resolution: - { - integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, - } - engines: { node: '>=6.0.0' } - dev: true - - /@jridgewell/set-array@1.1.2: - resolution: - { - integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, - } - engines: { node: '>=6.0.0' } - dev: true - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: - { - integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==, - } - - /@jridgewell/trace-mapping@0.3.22: - resolution: - { - integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==, - } - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - - /@nodelib/fs.scandir@2.1.5: - resolution: - { - integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, - } - engines: { node: '>= 8' } - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - - /@nodelib/fs.stat@2.0.5: - resolution: - { - integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, - } - engines: { node: '>= 8' } - dev: true - - /@nodelib/fs.walk@1.2.8: - resolution: - { - integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, - } - engines: { node: '>= 8' } - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - dev: true - - /@one-ini/wasm@0.1.1: - resolution: - { - integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==, - } - dev: true - - /@pinia/testing@0.1.3(pinia@2.1.7)(vue@3.4.19): - resolution: - { - integrity: sha512-D2Ds2s69kKFaRf2KCcP1NhNZEg5+we59aRyQalwRm7ygWfLM25nDH66267U3hNvRUOTx8ofL24GzodZkOmB5xw==, - } - peerDependencies: - pinia: '>=2.1.5' - dependencies: - pinia: 2.1.7(vue@3.4.19) - vue-demi: 0.14.7(vue@3.4.19) - transitivePeerDependencies: - - '@vue/composition-api' - - vue - dev: true - - /@pkgjs/parseargs@0.11.0: - resolution: - { - integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==, - } - engines: { node: '>=14' } - requiresBuild: true - dev: true + dependencies: + ms: 2.1.2 + supports-color: 8.1.1 + + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: false + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /default-browser-id@3.0.0: + resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} + engines: {node: '>=12'} + dependencies: + bplist-parser: 0.2.0 + untildify: 4.0.0 + dev: false + + /default-browser@4.0.0: + resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} + engines: {node: '>=14.16'} + dependencies: + bundle-name: 3.0.0 + default-browser-id: 3.0.0 + execa: 7.2.0 + titleize: 3.0.0 + dev: false + + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: true + + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: false + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + /define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + + /define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + dev: false + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + dependencies: + is-obj: 2.0.0 + dev: true + + /dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + dependencies: + is-obj: 2.0.0 + + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + /ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + + /editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.1 + semver: 7.6.0 + dev: true + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + /electron-to-chromium@1.4.677: + resolution: {integrity: sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==} + dev: true + + /elementtree@0.1.7: + resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==} + engines: {node: '>= 0.4.0'} + dependencies: + sax: 1.1.4 + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + + /enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + dev: true + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + /esbuild-android-64@0.14.51: + resolution: {integrity: sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-android-arm64@0.14.51: + resolution: {integrity: sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-64@0.14.51: + resolution: {integrity: sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-arm64@0.14.51: + resolution: {integrity: sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-64@0.14.51: + resolution: {integrity: sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-arm64@0.14.51: + resolution: {integrity: sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-32@0.14.51: + resolution: {integrity: sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-64@0.14.51: + resolution: {integrity: sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm64@0.14.51: + resolution: {integrity: sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm@0.14.51: + resolution: {integrity: sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-mips64le@0.14.51: + resolution: {integrity: sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-ppc64le@0.14.51: + resolution: {integrity: sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-riscv64@0.14.51: + resolution: {integrity: sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-s390x@0.14.51: + resolution: {integrity: sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-netbsd-64@0.14.51: + resolution: {integrity: sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-openbsd-64@0.14.51: + resolution: {integrity: sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-sunos-64@0.14.51: + resolution: {integrity: sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32@0.14.51: + resolution: {integrity: sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-64@0.14.51: + resolution: {integrity: sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-arm64@0.14.51: + resolution: {integrity: sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild@0.14.51: + resolution: {integrity: sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.51 + esbuild-android-arm64: 0.14.51 + esbuild-darwin-64: 0.14.51 + esbuild-darwin-arm64: 0.14.51 + esbuild-freebsd-64: 0.14.51 + esbuild-freebsd-arm64: 0.14.51 + esbuild-linux-32: 0.14.51 + esbuild-linux-64: 0.14.51 + esbuild-linux-arm: 0.14.51 + esbuild-linux-arm64: 0.14.51 + esbuild-linux-mips64le: 0.14.51 + esbuild-linux-ppc64le: 0.14.51 + esbuild-linux-riscv64: 0.14.51 + esbuild-linux-s390x: 0.14.51 + esbuild-netbsd-64: 0.14.51 + esbuild-openbsd-64: 0.14.51 + esbuild-sunos-64: 0.14.51 + esbuild-windows-32: 0.14.51 + esbuild-windows-64: 0.14.51 + esbuild-windows-arm64: 0.14.51 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + dev: true + + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + dev: true + + /escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + dev: false + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-prettier@8.10.0(eslint@8.56.0): + resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.56.0 + dev: true + + /eslint-plugin-cypress@2.15.1(eslint@8.56.0): + resolution: {integrity: sha512-eLHLWP5Q+I4j2AWepYq0PgFEei9/s5LvjuSqWrxurkg1YZ8ltxdvMNmdSf0drnsNo57CTgYY/NIHHLRSWejR7w==} + peerDependencies: + eslint: '>= 3.2.1' + dependencies: + eslint: 8.56.0 + globals: 13.24.0 + dev: true + + /eslint-plugin-vue@9.21.1(eslint@8.56.0): + resolution: {integrity: sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + eslint: 8.56.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.0.15 + semver: 7.6.0 + vue-eslint-parser: 9.4.2(eslint@8.56.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.56.0: + resolution: {integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.56.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@8.1.1) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@6.2.1: + resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} + engines: {node: '>=6.0.0'} + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + dev: true + + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 3.4.3 + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + /eventemitter2@6.4.7: + resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==} + dev: true + + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + + /execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: false + + /execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.2.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + dev: false + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.2.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + + /executable@4.1.1: + resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} + engines: {node: '>=4'} + dependencies: + pify: 2.3.0 + dev: true + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /extract-zip@1.7.0: + resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} + hasBin: true + dependencies: + concat-stream: 1.6.2 + debug: 2.6.9 + mkdirp: 0.5.6 + yauzl: 2.10.0 + transitivePeerDependencies: + - supports-color + dev: false + + /extract-zip@2.0.1(supports-color@8.1.1): + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: true + + /fast-glob@3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + dependencies: + reusify: 1.0.4 + dev: true + + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + + /figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.2.0 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@7.0.0: + resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} + engines: {node: '>=18'} + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + unicorn-magic: 0.1.0 + dev: true + + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + dev: true + + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true + + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + dev: true + + /follow-redirects@1.15.5: + resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: optional: true - - /@pnpm/config.env-replace@1.1.0: - resolution: - { - integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==, - } - engines: { node: '>=12.22.0' } - dev: false - - /@pnpm/network.ca-file@1.0.2: - resolution: - { - integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==, - } - engines: { node: '>=12.22.0' } - dependencies: - graceful-fs: 4.2.10 - dev: false - - /@pnpm/npm-conf@2.2.2: - resolution: - { - integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==, - } - engines: { node: '>=12' } - dependencies: - '@pnpm/config.env-replace': 1.1.0 - '@pnpm/network.ca-file': 1.0.2 - config-chain: 1.1.13 - dev: false - - /@quasar/app-vite@1.7.3(eslint@8.56.0)(pinia@2.1.7)(quasar@2.14.5)(vue-router@4.2.5)(vue@3.4.19): - resolution: - { - integrity: sha512-pnDInCFP9M1d7lJzS8UkiFq8bGWdekLz8Gu+NLI9UAxruIM9QVlSD4hUmWptTQXaVEvYlDnqfW3LOr57B8eVtw==, - } - engines: - { - node: ^24 || ^22 || ^20 || ^18 || ^16 || ^14.19, - npm: '>= 6.14.12', - yarn: '>= 1.17.3', - } - hasBin: true - peerDependencies: - electron-builder: '>= 22' - electron-packager: '>= 15' - eslint: ^8.11.0 - pinia: ^2.0.0 - quasar: ^2.14.0 - vue: ^3.2.29 - vue-router: ^4.0.12 - vuex: ^4.0.0 - workbox-build: '>= 6' - peerDependenciesMeta: - electron-builder: - optional: true - electron-packager: - optional: true - eslint: - optional: true - pinia: - optional: true - vuex: - optional: true - workbox-build: - optional: true - dependencies: - '@quasar/render-ssr-error': 1.0.3 - '@quasar/vite-plugin': 1.6.0(@vitejs/plugin-vue@2.3.4)(quasar@2.14.5)(vite@2.9.17)(vue@3.4.19) - '@rollup/pluginutils': 4.2.1 - '@types/chrome': 0.0.208 - '@types/compression': 1.7.5 - '@types/cordova': 0.0.34 - '@types/express': 4.17.21 - '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.4.19) - archiver: 5.3.2 - chokidar: 3.6.0 - ci-info: 3.9.0 - compression: 1.7.4 - cross-spawn: 7.0.3 - dot-prop: 6.0.1 - elementtree: 0.1.7 - esbuild: 0.14.51 - eslint: 8.56.0 - express: 4.18.2 - fast-glob: 3.2.12 - fs-extra: 11.2.0 - html-minifier: 4.0.0 - inquirer: 8.2.6 - isbinaryfile: 5.0.2 - kolorist: 1.8.0 - lodash: 4.17.21 - minimist: 1.2.8 - open: 8.4.2 - pinia: 2.1.7(vue@3.4.19) - quasar: 2.14.5 - register-service-worker: 1.7.2 - rollup-plugin-visualizer: 5.12.0 - sass: 1.71.1 - semver: 7.6.0 - serialize-javascript: 6.0.2 - table: 6.8.1 - vite: 2.9.17(sass@1.71.1) - vue: 3.4.19 - vue-router: 4.2.5(vue@3.4.19) - webpack-merge: 5.10.0 - transitivePeerDependencies: - - less - - rollup - - stylus - - supports-color - dev: true - - /@quasar/cli@2.3.0: - resolution: - { - integrity: sha512-DNFDemicj3jXe5+Ib+5w9Bwj1U3yoHQkqn0bU/qysIl/p0MmGA1yqOfUF0V4fw/5or1dfCvStIA/oZxUcC+2pQ==, - } - engines: { node: '>= 16', npm: '>= 5.6.0', yarn: '>= 1.6.0' } - hasBin: true - dependencies: - '@quasar/ssl-certificate': 1.0.0 - ci-info: 3.9.0 - compression: 1.7.4 - connect-history-api-fallback: 2.0.0 - cors: 2.8.5 - cross-spawn: 7.0.3 - express: 4.18.2 - fs-extra: 11.2.0 - http-proxy-middleware: 2.0.6 - kolorist: 1.8.0 - minimist: 1.2.8 - open: 9.1.0 - route-cache: 0.5.0 - selfsigned: 2.4.1 - update-notifier: 6.0.2 - transitivePeerDependencies: - - '@types/express' - - debug - - supports-color - dev: false - - /@quasar/extras@1.16.9: - resolution: - { - integrity: sha512-SlOhwzXyPQHWgQIS2ncyDdYdksCJvUYNtgsDQqzAKEG3r3d/ejOxvThle79HTK3Q6HB+gQWFG21Ux00Osr5XSw==, - } - dev: false - - /@quasar/quasar-app-extension-qcalendar@4.0.0-beta.15: - resolution: - { - integrity: sha512-i6hQkcP70LXLfVMPZMKQjSg3681gjZmASV3vq6ULzc0LhtBiPneLdVNNtH2itkWxAmaUj+1heQDI5Pa0F7VKLQ==, - } - engines: { node: '>= 10.0.0', npm: '>= 5.6.0', yarn: '>= 1.6.0' } - dependencies: - '@quasar/quasar-ui-qcalendar': 4.0.0-beta.19 - dev: true - - /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.4)(quasar@2.14.5)(vite@5.1.4)(vitest@0.31.4)(vue@3.4.19): - resolution: - { - integrity: sha512-eyzdUdmZiCueNS+5nedjMmzdbpCetSrtdGIwW6KplW1dTzRbLiNvYUjpBOxQGmJCgEhWy9zuswJ7MZ/bTql24Q==, - } - engines: { node: '>= 12.22.1', npm: '>= 6.14.12', yarn: '>= 1.17.3' } - peerDependencies: - '@vitest/ui': ^0.34.0 - '@vue/test-utils': ^2.4.1 - quasar: ^2.12.7 - vitest: ^0.34.0 - vue: ^3.3.4 - peerDependenciesMeta: - '@vitest/ui': - optional: true - dependencies: - '@vue/test-utils': 2.4.4(vue@3.4.19) - happy-dom: 11.2.0 - lodash-es: 4.17.21 - quasar: 2.14.5 - vite-jsconfig-paths: 2.0.1(vite@5.1.4) - vite-tsconfig-paths: 4.3.1(vite@5.1.4) - vitest: 0.31.4 - vue: 3.4.19 - transitivePeerDependencies: - - supports-color - - typescript - - vite - dev: true - - /@quasar/quasar-ui-qcalendar@4.0.0-beta.19: - resolution: - { - integrity: sha512-BT0G2JjgKl1bqNrY5utcYeoy8gK+U9k3Pz1YDi1OB265W/jHU6nFoWMEUdY3JdvMccwkXTL2DLVyl3eqAUyLyg==, - } - dev: true - - /@quasar/render-ssr-error@1.0.3: - resolution: - { - integrity: sha512-A8RF99q6/sOSe1Ighnh5syEIbliD3qUYEJd2HyfFyBPSMF+WYGXon5dmzg4nUoK662NgOggInevkDyBDJcZugg==, - } - engines: { node: '>= 16' } - dependencies: - stack-trace: 1.0.0-pre2 - dev: true - - /@quasar/ssl-certificate@1.0.0: - resolution: - { - integrity: sha512-RhZF7rO76T7Ywer1/5lCe7xl3CIiXxSAH1xgwOj0wcHTityDxJqIN/5YIj6BxMvlFw8XkJDoB1udEQafoVFA4g==, - } - engines: { node: '>= 16' } - dependencies: - fs-extra: 11.2.0 - selfsigned: 2.4.1 - dev: false - - /@quasar/vite-plugin@1.6.0(@vitejs/plugin-vue@2.3.4)(quasar@2.14.5)(vite@2.9.17)(vue@3.4.19): - resolution: - { - integrity: sha512-LmbV76G1CwWZbrEQhqyZpkRQTJyO3xpW55aXY1zWN+JhyUeG77CcMCEWteBVnJ6I6ehUPFDC9ONd2+WlwH6rNQ==, - } - engines: { node: '>=12' } - peerDependencies: - '@vitejs/plugin-vue': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-beta.0 - quasar: ^2.8.0 - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-beta.0 - vue: ^3.0.0 - dependencies: - '@vitejs/plugin-vue': 2.3.4(vite@5.1.4)(vue@3.4.19) - quasar: 2.14.5 - vite: 2.9.17(sass@1.71.1) - vue: 3.4.19 - dev: true - - /@rollup/pluginutils@4.2.1: - resolution: - { - integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==, - } - engines: { node: '>= 8.0.0' } - dependencies: - estree-walker: 2.0.2 - picomatch: 2.3.1 - dev: true - - /@rollup/rollup-android-arm-eabi@4.12.0: - resolution: - { - integrity: sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==, - } - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + dev: false + + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + + /forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: true + + /form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + dev: false + + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + /fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + dev: true + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + /fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + dev: true + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.1 + + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: false + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + + /getos@3.2.1: + resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} + dependencies: + async: 3.2.5 + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + dependencies: + assert-plus: 1.0.0 + dev: true + + /git-raw-commits@4.0.0: + resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} + engines: {node: '>=16'} + hasBin: true + dependencies: + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-regex@0.3.2: + resolution: {integrity: sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==} + dev: true + + /glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.3 + minipass: 7.0.4 + path-scurry: 1.10.1 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + /global-directory@4.0.1: + resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} + engines: {node: '>=18'} + dependencies: + ini: 4.1.1 + dev: true + + /global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + dependencies: + ini: 2.0.0 + + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + + /got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + dev: false + + /got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + dev: false + + /graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: false + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /happy-dom@11.2.0: + resolution: {integrity: sha512-z4PshcYIIH6SkymSNRcDFwYUJOENe+FOQDx5BbHgg/wQUgxF5p9I9/BN45Jff34bbhXV8yJgkC5N99eyOzXK3w==} + dependencies: + css.escape: 1.5.1 + entities: 4.5.0 + iconv-lite: 0.6.3 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + /has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /html-minifier@4.0.0: + resolution: {integrity: sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==} + engines: {node: '>=6'} + hasBin: true + dependencies: + camel-case: 3.0.0 + clean-css: 4.2.4 + commander: 2.20.3 + he: 1.2.0 + param-case: 2.1.1 + relateurl: 0.2.7 + uglify-js: 3.17.4 + dev: true + + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: false + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + /http-proxy-middleware@2.0.6: + resolution: {integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': optional: true - - /@rollup/rollup-android-arm64@4.12.0: - resolution: - { - integrity: sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==, - } - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + dependencies: + '@types/http-proxy': 1.17.14 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.5 + transitivePeerDependencies: + - debug + dev: false + + /http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.5 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: false + + /http-signature@1.3.6: + resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + jsprim: 2.0.2 + sshpk: 1.18.0 + dev: true + + /http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: false + + /http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: false + + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: false + + /human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + dev: false + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + + /husky@8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + dev: true + + /immutable@4.3.5: + resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + dev: false + + /import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + /ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + /ini@4.1.1: + resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + + /inquirer@8.2.6: + resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} + engines: {node: '>=12.0.0'} + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + dev: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + dependencies: + ci-info: 3.9.0 + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.1 + dev: true + + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + /is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dev: false + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + + /is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + dependencies: + is-docker: 3.0.0 + dev: false + + /is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: true + + /is-npm@6.0.0: + resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + /is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + /is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + dev: false + + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + /is-text-path@2.0.0: + resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==} + engines: {node: '>=8'} + dependencies: + text-extensions: 2.4.0 + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + + /is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + dev: false + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + /isbinaryfile@5.0.2: + resolution: {integrity: sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==} + engines: {node: '>= 18.0.0'} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: true + + /jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + + /jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + dev: true + + /js-beautify@1.15.1: + resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} + engines: {node: '>=14'} + hasBin: true + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.4 + glob: 10.3.10 + js-cookie: 3.0.5 + nopt: 7.2.0 + dev: true + + /js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + dev: true + + /js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonc-eslint-parser@1.4.1: + resolution: {integrity: sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==} + engines: {node: '>=8.10.0'} + dependencies: + acorn: 7.4.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 1.3.0 + espree: 6.2.1 + semver: 6.3.1 + dev: true + + /jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /jsprim@2.0.2: + resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + /latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + dependencies: + package-json: 8.1.1 + dev: false + + /lazy-ass@1.6.0: + resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} + engines: {node: '> 0.8'} + dev: true + + /lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + dependencies: + readable-stream: 2.3.8 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /listr2@3.14.0(enquirer@2.4.1): + resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} + engines: {node: '>=10.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: optional: true - - /@rollup/rollup-darwin-arm64@4.12.0: - resolution: - { - integrity: sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==, - } - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.20 + enquirer: 2.4.1 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.1 + rxjs: 7.8.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-locate: 6.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: true + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: true + + /lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + dev: true + + /lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + dev: true + + /lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.kebabcase@4.1.1: + resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + dev: true + + /lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + dev: true + + /lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + dev: true + + /lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + dev: true + + /lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + dev: true + + /lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + dev: true + + /lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + dev: true + + /lodash.upperfirst@4.3.1: + resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + dev: true + + /lower-case@1.1.4: + resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} + dev: true + + /lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + dev: false + + /lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: true + + /lru-cache@4.0.1: + resolution: {integrity: sha512-MX0ZnRoVTWXBiNe9dysqKXjvhmQgHsOirh/2rerIVJ8sbQeMxc5OPj0HDpVV3bYjdE6GTHrPf8BEHJqWHFkjHA==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: false + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + + /magic-string@0.30.7: + resolution: {integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + /md5-hex@3.0.1: + resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} + engines: {node: '>=8'} + dependencies: + blueimp-md5: 2.19.0 + dev: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + /meow@12.1.1: + resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} + engines: {node: '>=16.10'} + dev: true + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + /mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + dev: false + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + + /mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + /minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: false + + /mlly@1.5.0: + resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.4.0 + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + /mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + dev: true + + /mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + dev: true + + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + /no-case@2.3.2: + resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} + dependencies: + lower-case: 1.1.4 + dev: true + + /node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + dev: false + + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + + /nopt@7.2.0: + resolution: {integrity: sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + dependencies: + abbrev: 2.0.0 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + dev: false + + /normalize-url@8.0.0: + resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==} + engines: {node: '>=14.16'} + dev: false + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + + /npm-run-path@5.2.0: + resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + + /on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + + /open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /open@9.1.0: + resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} + engines: {node: '>=14.16'} + dependencies: + default-browser: 4.0.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 2.2.0 + dev: false + + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + /ospath@1.2.2: + resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} + dev: true + + /p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + dev: false + + /p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + dev: false + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-limit: 4.0.0 + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + dependencies: + got: 12.6.1 + registry-auth-token: 5.0.2 + registry-url: 6.0.1 + semver: 7.6.0 + dev: false + + /param-case@2.1.1: + resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} + dependencies: + no-case: 2.3.2 + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + + /pinia@2.1.7(typescript@5.5.4)(vue@3.4.19): + resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==} + peerDependencies: + '@vue/composition-api': ^1.4.0 + typescript: '>=4.4.4' + vue: ^2.6.14 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': optional: true - - /@rollup/rollup-darwin-x64@4.12.0: - resolution: - { - integrity: sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==, - } - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + typescript: optional: true - - /@rollup/rollup-linux-arm-gnueabihf@4.12.0: - resolution: - { - integrity: sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==, - } - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + dependencies: + '@vue/devtools-api': 6.6.1 + typescript: 5.5.4 + vue: 3.4.19(typescript@5.5.4) + vue-demi: 0.14.7(vue@3.4.19) + + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + dev: true + + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.1 + mlly: 1.5.0 + pathe: 1.1.2 + dev: true + + /postcss-selector-parser@6.0.15: + resolution: {integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + + /pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: false + + /proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + /proxy-from-env@1.0.0: + resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + dev: false + + /psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true + + /pupa@3.1.0: + resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} + engines: {node: '>=12.20'} + dependencies: + escape-goat: 4.0.0 + dev: false + + /qs@6.10.4: + resolution: {integrity: sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.5 + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.5 + + /quasar@2.14.5: + resolution: {integrity: sha512-N+iRYoby09P9l+R5nKfA0tCPXdXJJHCPifjP8CkL/JASX5yHEjuwh7KoNiWzYLZPbsYXVuQKqwtDy0qXuXTv2g==} + engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'} + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: false + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + dev: false + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + dependencies: + minimatch: 5.1.6 + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /recrawl-sync@2.2.3: + resolution: {integrity: sha512-vSaTR9t+cpxlskkdUFrsEpnf67kSmPk66yAGT1fZPrDudxQjoMzPgQhSMImQ0pAw5k0NPirefQfhopSjhdUtpQ==} + dependencies: + '@cush/relative': 1.0.0 + glob-regex: 0.3.2 + slash: 3.0.0 + sucrase: 3.35.0 + tslib: 1.14.1 + dev: true + + /register-service-worker@1.7.2: + resolution: {integrity: sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A==} + dev: true + + /registry-auth-token@5.0.2: + resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + engines: {node: '>=14'} + dependencies: + '@pnpm/npm-conf': 2.2.2 + dev: false + + /registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + dependencies: + rc: 1.2.8 + dev: false + + /relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + dev: true + + /request-progress@3.0.0: + resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} + dependencies: + throttleit: 1.0.1 + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: false + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + dependencies: + lowercase-keys: 2.0.0 + dev: false + + /responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + dependencies: + lowercase-keys: 3.0.0 + dev: false + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: false + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup-plugin-visualizer@5.12.0: + resolution: {integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + rollup: 2.x || 3.x || 4.x + peerDependenciesMeta: + rollup: optional: true - - /@rollup/rollup-linux-arm64-gnu@4.12.0: - resolution: - { - integrity: sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==, - } - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + dependencies: + open: 8.4.2 + picomatch: 2.3.1 + source-map: 0.7.4 + yargs: 17.7.2 + dev: true + + /rollup@2.77.3: + resolution: {integrity: sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /rollup@4.12.0: + resolution: {integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.12.0 + '@rollup/rollup-android-arm64': 4.12.0 + '@rollup/rollup-darwin-arm64': 4.12.0 + '@rollup/rollup-darwin-x64': 4.12.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.12.0 + '@rollup/rollup-linux-arm64-gnu': 4.12.0 + '@rollup/rollup-linux-arm64-musl': 4.12.0 + '@rollup/rollup-linux-riscv64-gnu': 4.12.0 + '@rollup/rollup-linux-x64-gnu': 4.12.0 + '@rollup/rollup-linux-x64-musl': 4.12.0 + '@rollup/rollup-win32-arm64-msvc': 4.12.0 + '@rollup/rollup-win32-ia32-msvc': 4.12.0 + '@rollup/rollup-win32-x64-msvc': 4.12.0 + fsevents: 2.3.3 + dev: true + + /route-cache@0.5.0: + resolution: {integrity: sha512-7FzV+1O4q7XeerbyG8aEeDH+1bk/Vxp2sDJdEZE0KcbTP0C6IucKSQUCTwB3F0IkhpF4rYluLLENEfUQ6LH/ng==} + dependencies: + debug: 3.1.0 + lru-cache: 4.0.1 + transitivePeerDependencies: + - supports-color + dev: false + + /run-applescript@5.0.0: + resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} + engines: {node: '>=12'} + dependencies: + execa: 5.1.1 + dev: false + + /run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.2 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + /sass@1.71.1: + resolution: {integrity: sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + chokidar: 3.6.0 + immutable: 4.3.5 + source-map-js: 1.0.2 + dev: true + + /sax@1.1.4: + resolution: {integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==} + dev: true + + /selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + dependencies: + '@types/node-forge': 1.3.11 + node-forge: 1.3.1 + dev: false + + /semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + dependencies: + semver: 7.6.0 + dev: false + + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + dev: true + + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + /set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + /shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + /side-channel@1.0.5: + resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + dev: true + + /sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + + /stack-trace@1.0.0-pre2: + resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} + engines: {node: '>=16'} + dev: true + + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: false + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + dependencies: + acorn: 8.11.3 + dev: true + + /sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + commander: 4.1.1 + glob: 10.3.10 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /table@6.8.1: + resolution: {integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==} + engines: {node: '>=10.0.0'} + dependencies: + ajv: 8.12.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /text-extensions@2.4.0: + resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==} + engines: {node: '>=8'} + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + dependencies: + thenify: 3.3.1 + dev: true + + /thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + dependencies: + any-promise: 1.3.0 + dev: true + + /throttleit@1.0.1: + resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /time-zone@1.0.0: + resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} + engines: {node: '>=4'} + dev: true + + /tinybench@2.6.0: + resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + dev: true + + /tinypool@0.5.0: + resolution: {integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + dev: true + + /titleize@3.0.0: + resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} + engines: {node: '>=12'} + dev: false + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + + /tmp@0.2.1: + resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} + engines: {node: '>=8.17.0'} + dependencies: + rimraf: 3.0.2 + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + /tough-cookie@4.1.3: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} + engines: {node: '>=6'} + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + dev: true + + /ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + dev: true + + /tsconfck@3.0.2(typescript@5.5.4): + resolution: {integrity: sha512-6lWtFjwuhS3XI4HsX4Zg0izOI3FU/AI9EGVlPEUMDIhvLPMD4wkiof0WCoDgW7qY+Dy198g4d9miAqUHWHFH6Q==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: optional: true - - /@rollup/rollup-linux-arm64-musl@4.12.0: - resolution: - { - integrity: sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==, - } - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + dependencies: + typescript: 5.5.4 + dev: true + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + dev: true + + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + dev: false + + /tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + dev: false + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: false + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + dependencies: + is-typedarray: 1.0.0 + dev: false + + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: false + + /typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + /ufo@1.4.0: + resolution: {integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==} + dev: true + + /uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + dev: true + + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + /unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + dev: true + + /unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + dependencies: + crypto-random-string: 4.0.0 + dev: false + + /universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + + /universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + /unplugin@1.7.1: + resolution: {integrity: sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==} + dependencies: + acorn: 8.11.3 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.1 + dev: true + + /untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + /update-browserslist-db@1.0.13(browserslist@4.23.0): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.23.0 + escalade: 3.1.2 + picocolors: 1.0.0 + dev: true + + /update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + dependencies: + boxen: 7.1.1 + chalk: 5.3.0 + configstore: 6.0.0 + has-yarn: 3.0.0 + import-lazy: 4.0.0 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + is-npm: 6.0.0 + is-yarn-global: 0.4.1 + latest-version: 7.0.0 + pupa: 3.1.0 + semver: 7.6.0 + semver-diff: 4.0.0 + xdg-basedir: 5.1.0 + dev: false + + /upper-case@1.1.3: + resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.1 + dev: true + + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + + /validator@13.11.0: + resolution: {integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==} + engines: {node: '>= 0.10'} + dev: false + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + /verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + + /vite-jsconfig-paths@2.0.1(vite@5.1.4): + resolution: {integrity: sha512-rabcTTfKs0MdAsQWcZjbIMo5fcp6jthZce7uFEPgVPgpSY+RNOwjzIJOPES6cB/GJZLSoLGfHM9kt5HNmJvp7A==} + peerDependencies: + vite: '>2.0.0-0' + dependencies: + debug: 4.3.4(supports-color@8.1.1) + globrex: 0.1.2 + recrawl-sync: 2.2.3 + tsconfig-paths: 3.15.0 + vite: 5.1.4(@types/node@20.11.19) + transitivePeerDependencies: + - supports-color + dev: true + + /vite-node@0.31.4(@types/node@20.11.19): + resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4(supports-color@8.1.1) + mlly: 1.5.0 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 4.5.2(@types/node@20.11.19) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite-tsconfig-paths@4.3.1(typescript@5.5.4)(vite@5.1.4): + resolution: {integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: optional: true - - /@rollup/rollup-linux-riscv64-gnu@4.12.0: - resolution: - { - integrity: sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==, - } - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + globrex: 0.1.2 + tsconfck: 3.0.2(typescript@5.5.4) + vite: 5.1.4(@types/node@20.11.19) + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /vite@2.9.17(sass@1.71.1): + resolution: {integrity: sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==} + engines: {node: '>=12.2.0'} + hasBin: true + peerDependencies: + less: '*' + sass: '*' + stylus: '*' + peerDependenciesMeta: + less: optional: true - - /@rollup/rollup-linux-x64-gnu@4.12.0: - resolution: - { - integrity: sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==, - } - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + sass: optional: true - - /@rollup/rollup-linux-x64-musl@4.12.0: - resolution: - { - integrity: sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==, - } - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + stylus: optional: true - - /@rollup/rollup-win32-arm64-msvc@4.12.0: - resolution: - { - integrity: sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==, - } - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + dependencies: + esbuild: 0.14.51 + postcss: 8.4.35 + resolve: 1.22.8 + rollup: 2.77.3 + sass: 1.71.1 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vite@4.5.2(@types/node@20.11.19): + resolution: {integrity: sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': optional: true - - /@rollup/rollup-win32-ia32-msvc@4.12.0: - resolution: - { - integrity: sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==, - } - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + less: optional: true - - /@rollup/rollup-win32-x64-msvc@4.12.0: - resolution: - { - integrity: sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==, - } - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + lightningcss: optional: true - - /@sindresorhus/is@4.6.0: - resolution: - { - integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==, - } - engines: { node: '>=10' } - dev: false - - /@sindresorhus/is@5.6.0: - resolution: - { - integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==, - } - engines: { node: '>=14.16' } - dev: false - - /@szmarczak/http-timer@4.0.6: - resolution: - { - integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==, - } - engines: { node: '>=10' } - dependencies: - defer-to-connect: 2.0.1 - dev: false - - /@szmarczak/http-timer@5.0.1: - resolution: - { - integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==, - } - engines: { node: '>=14.16' } - dependencies: - defer-to-connect: 2.0.1 - dev: false - - /@types/body-parser@1.19.5: - resolution: - { - integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==, - } - dependencies: - '@types/connect': 3.4.38 - '@types/node': 20.11.19 - dev: true - - /@types/cacheable-request@6.0.3: - resolution: - { - integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==, - } - dependencies: - '@types/http-cache-semantics': 4.0.4 - '@types/keyv': 3.1.4 - '@types/node': 20.11.19 - '@types/responselike': 1.0.3 - dev: false - - /@types/chai-subset@1.3.5: - resolution: - { - integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==, - } - dependencies: - '@types/chai': 4.3.12 - dev: true - - /@types/chai@4.3.12: - resolution: - { - integrity: sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==, - } - dev: true - - /@types/chrome@0.0.208: - resolution: - { - integrity: sha512-VDU/JnXkF5qaI7WBz14Azpa2VseZTgML0ia/g/B1sr9OfdOnHiH/zZ7P7qCDqxSlkqJh76/bPc8jLFcx8rHJmw==, - } - dependencies: - '@types/filesystem': 0.0.35 - '@types/har-format': 1.2.15 - dev: true - - /@types/compression@1.7.5: - resolution: - { - integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==, - } - dependencies: - '@types/express': 4.17.21 - dev: true - - /@types/connect@3.4.38: - resolution: - { - integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==, - } - dependencies: - '@types/node': 20.11.19 - dev: true - - /@types/cordova@0.0.34: - resolution: - { - integrity: sha512-rkiiTuf/z2wTd4RxFOb+clE7PF4AEJU0hsczbUdkHHBtkUmpWQpEddynNfJYKYtZFJKbq4F+brfekt1kx85IZA==, - } - dev: true - - /@types/estree@1.0.5: - resolution: - { - integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==, - } - dev: true - - /@types/express-serve-static-core@4.17.43: - resolution: - { - integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==, - } - dependencies: - '@types/node': 20.11.19 - '@types/qs': 6.9.11 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - dev: true - - /@types/express@4.17.21: - resolution: - { - integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==, - } - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.43 - '@types/qs': 6.9.11 - '@types/serve-static': 1.15.5 - dev: true - - /@types/filesystem@0.0.35: - resolution: - { - integrity: sha512-1eKvCaIBdrD2mmMgy5dwh564rVvfEhZTWVQQGRNn0Nt4ZEnJ0C8oSUCzvMKRA4lGde5oEVo+q2MrTTbV/GHDCQ==, - } - dependencies: - '@types/filewriter': 0.0.33 - dev: true - - /@types/filewriter@0.0.33: - resolution: - { - integrity: sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==, - } - dev: true - - /@types/har-format@1.2.15: - resolution: - { - integrity: sha512-RpQH4rXLuvTXKR0zqHq3go0RVXYv/YVqv4TnPH95VbwUxZdQlK1EtcMvQvMpDngHbt13Csh9Z4qT9AbkiQH5BA==, - } - dev: true - - /@types/http-cache-semantics@4.0.4: - resolution: - { - integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==, - } - dev: false - - /@types/http-errors@2.0.4: - resolution: - { - integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==, - } - dev: true - - /@types/http-proxy@1.17.14: - resolution: - { - integrity: sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==, - } - dependencies: - '@types/node': 20.11.19 - dev: false - - /@types/json5@0.0.29: - resolution: - { - integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==, - } - dev: true - - /@types/keyv@3.1.4: - resolution: - { - integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==, - } - dependencies: - '@types/node': 20.11.19 - dev: false - - /@types/mime@1.3.5: - resolution: - { - integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==, - } - dev: true - - /@types/mime@3.0.4: - resolution: - { - integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==, - } - dev: true - - /@types/node-forge@1.3.11: - resolution: - { - integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==, - } - dependencies: - '@types/node': 20.11.19 - dev: false - - /@types/node@20.11.19: - resolution: - { - integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==, - } - dependencies: - undici-types: 5.26.5 - - /@types/qs@6.9.11: - resolution: - { - integrity: sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==, - } - dev: true - - /@types/range-parser@1.2.7: - resolution: - { - integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==, - } - dev: true - - /@types/responselike@1.0.3: - resolution: - { - integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==, - } - dependencies: - '@types/node': 20.11.19 - dev: false - - /@types/send@0.17.4: - resolution: - { - integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==, - } - dependencies: - '@types/mime': 1.3.5 - '@types/node': 20.11.19 - dev: true - - /@types/serve-static@1.15.5: - resolution: - { - integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==, - } - dependencies: - '@types/http-errors': 2.0.4 - '@types/mime': 3.0.4 - '@types/node': 20.11.19 - dev: true - - /@types/sinonjs__fake-timers@8.1.1: - resolution: - { - integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==, - } - dev: true - - /@types/sizzle@2.3.8: - resolution: - { - integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==, - } - dev: true - - /@types/yauzl@2.10.3: - resolution: - { - integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==, - } - requiresBuild: true - dependencies: - '@types/node': 20.11.19 - dev: true + sass: optional: true - - /@ungap/structured-clone@1.2.0: - resolution: - { - integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==, - } - dev: true - - /@vitejs/plugin-vue@2.3.4(vite@5.1.4)(vue@3.4.19): - resolution: - { - integrity: sha512-IfFNbtkbIm36O9KB8QodlwwYvTEsJb4Lll4c2IwB3VHc2gie2mSPtSzL0eYay7X2jd/2WX02FjSGTWR6OPr/zg==, - } - engines: { node: '>=12.0.0' } - peerDependencies: - vite: ^2.5.10 - vue: ^3.2.25 - dependencies: - vite: 5.1.4 - vue: 3.4.19 - dev: true - - /@vitest/expect@0.31.4: - resolution: - { - integrity: sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==, - } - dependencies: - '@vitest/spy': 0.31.4 - '@vitest/utils': 0.31.4 - chai: 4.4.1 - dev: true - - /@vitest/runner@0.31.4: - resolution: - { - integrity: sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==, - } - dependencies: - '@vitest/utils': 0.31.4 - concordance: 5.0.4 - p-limit: 4.0.0 - pathe: 1.1.2 - dev: true - - /@vitest/snapshot@0.31.4: - resolution: - { - integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==, - } - dependencies: - magic-string: 0.30.7 - pathe: 1.1.2 - pretty-format: 27.5.1 - dev: true - - /@vitest/spy@0.31.4: - resolution: - { - integrity: sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==, - } - dependencies: - tinyspy: 2.2.1 - dev: true - - /@vitest/utils@0.31.4: - resolution: - { - integrity: sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==, - } - dependencies: - concordance: 5.0.4 - loupe: 2.3.7 - pretty-format: 27.5.1 - dev: true - - /@vue/compiler-core@3.4.19: - resolution: - { - integrity: sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==, - } - dependencies: - '@babel/parser': 7.23.9 - '@vue/shared': 3.4.19 - entities: 4.5.0 - estree-walker: 2.0.2 - source-map-js: 1.0.2 - - /@vue/compiler-dom@3.4.19: - resolution: - { - integrity: sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==, - } - dependencies: - '@vue/compiler-core': 3.4.19 - '@vue/shared': 3.4.19 - - /@vue/compiler-sfc@3.4.19: - resolution: - { - integrity: sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==, - } - dependencies: - '@babel/parser': 7.23.9 - '@vue/compiler-core': 3.4.19 - '@vue/compiler-dom': 3.4.19 - '@vue/compiler-ssr': 3.4.19 - '@vue/shared': 3.4.19 - estree-walker: 2.0.2 - magic-string: 0.30.7 - postcss: 8.4.35 - source-map-js: 1.0.2 - - /@vue/compiler-ssr@3.4.19: - resolution: - { - integrity: sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==, - } - dependencies: - '@vue/compiler-dom': 3.4.19 - '@vue/shared': 3.4.19 - - /@vue/devtools-api@6.6.1: - resolution: - { - integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==, - } - - /@vue/reactivity@3.4.19: - resolution: - { - integrity: sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==, - } - dependencies: - '@vue/shared': 3.4.19 - - /@vue/runtime-core@3.4.19: - resolution: - { - integrity: sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==, - } - dependencies: - '@vue/reactivity': 3.4.19 - '@vue/shared': 3.4.19 - - /@vue/runtime-dom@3.4.19: - resolution: - { - integrity: sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==, - } - dependencies: - '@vue/runtime-core': 3.4.19 - '@vue/shared': 3.4.19 - csstype: 3.1.3 - - /@vue/server-renderer@3.4.19(vue@3.4.19): - resolution: - { - integrity: sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==, - } - peerDependencies: - vue: 3.4.19 - dependencies: - '@vue/compiler-ssr': 3.4.19 - '@vue/shared': 3.4.19 - vue: 3.4.19 - - /@vue/shared@3.4.19: - resolution: - { - integrity: sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==, - } - - /@vue/test-utils@2.4.4(vue@3.4.19): - resolution: - { - integrity: sha512-8jkRxz8pNhClAf4Co4ZrpAoFISdvT3nuSkUlY6Ys6rmTpw3DMWG/X3mw3gQ7QJzgCZO9f+zuE2kW57fi09MW7Q==, - } - peerDependencies: - '@vue/server-renderer': ^3.0.1 - vue: ^3.0.1 - peerDependenciesMeta: - '@vue/server-renderer': - optional: true - dependencies: - js-beautify: 1.15.1 - vue: 3.4.19 - vue-component-type-helpers: 1.8.27 - dev: true - - /abbrev@2.0.0: - resolution: - { - integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==, - } - engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } - dev: true - - /accepts@1.3.8: - resolution: - { - integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==, - } - engines: { node: '>= 0.6' } - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - /acorn-jsx@5.3.2(acorn@7.4.1): - resolution: - { - integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, - } - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 7.4.1 - dev: true - - /acorn-jsx@5.3.2(acorn@8.11.3): - resolution: - { - integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, - } - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.11.3 - dev: true - - /acorn-walk@8.3.2: - resolution: - { - integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==, - } - engines: { node: '>=0.4.0' } - dev: true - - /acorn@7.4.1: - resolution: - { - integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==, - } - engines: { node: '>=0.4.0' } - hasBin: true - dev: true - - /acorn@8.11.3: - resolution: - { - integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==, - } - engines: { node: '>=0.4.0' } - hasBin: true - dev: true - - /aggregate-error@3.1.0: - resolution: - { - integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==, - } - engines: { node: '>=8' } - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: true - - /ajv@6.12.6: - resolution: - { - integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, - } - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - - /ajv@8.12.0: - resolution: - { - integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==, - } - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: true - - /ansi-align@3.0.1: - resolution: - { - integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==, - } - dependencies: - string-width: 4.2.3 - dev: false - - /ansi-colors@4.1.3: - resolution: - { - integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==, - } - engines: { node: '>=6' } - dev: true - - /ansi-escapes@4.3.2: - resolution: - { - integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, - } - engines: { node: '>=8' } - dependencies: - type-fest: 0.21.3 - dev: true - - /ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: '>=8' } - - /ansi-regex@6.0.1: - resolution: - { - integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==, - } - engines: { node: '>=12' } - - /ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: '>=8' } - dependencies: - color-convert: 2.0.1 - dev: true - - /ansi-styles@5.2.0: - resolution: - { - integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, - } - engines: { node: '>=10' } - dev: true - - /ansi-styles@6.2.1: - resolution: - { - integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, - } - engines: { node: '>=12' } - - /any-promise@1.3.0: - resolution: - { - integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==, - } - dev: true - - /anymatch@3.1.3: - resolution: - { - integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, - } - engines: { node: '>= 8' } - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - dev: true - - /arch@2.2.0: - resolution: - { - integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==, - } - dev: true - - /archiver-utils@2.1.0: - resolution: - { - integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==, - } - engines: { node: '>= 6' } - dependencies: - glob: 7.2.3 - graceful-fs: 4.2.11 - lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 - normalize-path: 3.0.0 - readable-stream: 2.3.8 - dev: true - - /archiver-utils@3.0.4: - resolution: - { - integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==, - } - engines: { node: '>= 10' } - dependencies: - glob: 7.2.3 - graceful-fs: 4.2.11 - lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 - normalize-path: 3.0.0 - readable-stream: 3.6.2 - dev: true - - /archiver@5.3.2: - resolution: - { - integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==, - } - engines: { node: '>= 10' } - dependencies: - archiver-utils: 2.1.0 - async: 3.2.5 - buffer-crc32: 0.2.13 - readable-stream: 3.6.2 - readdir-glob: 1.1.3 - tar-stream: 2.2.0 - zip-stream: 4.1.1 - dev: true - - /argparse@2.0.1: - resolution: - { - integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, - } - dev: true - - /array-flatten@1.1.1: - resolution: - { - integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==, - } - - /asn1@0.2.6: - resolution: - { - integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==, - } - dependencies: - safer-buffer: 2.1.2 - dev: true - - /assert-plus@1.0.0: - resolution: - { - integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==, - } - engines: { node: '>=0.8' } - dev: true - - /assertion-error@1.1.0: - resolution: - { - integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==, - } - dev: true - - /astral-regex@2.0.0: - resolution: - { - integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==, - } - engines: { node: '>=8' } - dev: true - - /async@3.2.5: - resolution: - { - integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==, - } - dev: true - - /asynckit@0.4.0: - resolution: - { - integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, - } - - /at-least-node@1.0.0: - resolution: - { - integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==, - } - engines: { node: '>= 4.0.0' } - dev: true - - /autoprefixer@10.4.17(postcss@8.4.35): - resolution: - { - integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==, - } - engines: { node: ^10 || ^12 || >=14 } - hasBin: true - peerDependencies: - postcss: ^8.1.0 - dependencies: - browserslist: 4.23.0 - caniuse-lite: 1.0.30001588 - fraction.js: 4.3.7 - normalize-range: 0.1.2 - picocolors: 1.0.0 - postcss: 8.4.35 - postcss-value-parser: 4.2.0 - dev: true - - /aws-sign2@0.7.0: - resolution: - { - integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==, - } - dev: true - - /aws4@1.12.0: - resolution: - { - integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==, - } - dev: true - - /axios@1.6.7: - resolution: - { - integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==, - } - dependencies: - follow-redirects: 1.15.5 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false - - /balanced-match@1.0.2: - resolution: - { - integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, - } - - /base64-js@1.5.1: - resolution: - { - integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, - } - dev: true - - /bcrypt-pbkdf@1.0.2: - resolution: - { - integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==, - } - dependencies: - tweetnacl: 0.14.5 - dev: true - - /big-integer@1.6.52: - resolution: - { - integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==, - } - engines: { node: '>=0.6' } - dev: false - - /binary-extensions@2.2.0: - resolution: - { - integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==, - } - engines: { node: '>=8' } - dev: true - - /bl@4.1.0: - resolution: - { - integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==, - } - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: true - - /blob-util@2.0.2: - resolution: - { - integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==, - } - dev: true - - /bluebird@3.7.2: - resolution: - { - integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==, - } - dev: true - - /blueimp-md5@2.19.0: - resolution: - { - integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==, - } - dev: true - - /body-parser@1.20.1: - resolution: - { - integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==, - } - engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.1 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - /boolbase@1.0.0: - resolution: - { - integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==, - } - dev: true - - /boxen@7.1.1: - resolution: - { - integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==, - } - engines: { node: '>=14.16' } - dependencies: - ansi-align: 3.0.1 - camelcase: 7.0.1 - chalk: 5.3.0 - cli-boxes: 3.0.0 - string-width: 5.1.2 - type-fest: 2.19.0 - widest-line: 4.0.1 - wrap-ansi: 8.1.0 - dev: false - - /bplist-parser@0.2.0: - resolution: - { - integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==, - } - engines: { node: '>= 5.10.0' } - dependencies: - big-integer: 1.6.52 - dev: false - - /brace-expansion@1.1.11: - resolution: - { - integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==, - } - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - /brace-expansion@2.0.1: - resolution: - { - integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==, - } - dependencies: - balanced-match: 1.0.2 - dev: true - - /braces@3.0.2: - resolution: - { - integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==, - } - engines: { node: '>=8' } - dependencies: - fill-range: 7.0.1 - - /browserslist@4.23.0: - resolution: - { - integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==, - } - engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } - hasBin: true - dependencies: - caniuse-lite: 1.0.30001588 - electron-to-chromium: 1.4.677 - node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.23.0) - dev: true - - /buffer-crc32@0.2.13: - resolution: - { - integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==, - } - - /buffer-from@1.1.2: - resolution: - { - integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, - } - dev: false - - /buffer@5.7.1: - resolution: - { - integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==, - } - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: true - - /bundle-name@3.0.0: - resolution: - { - integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==, - } - engines: { node: '>=12' } - dependencies: - run-applescript: 5.0.0 - dev: false - - /bytes@3.0.0: - resolution: - { - integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==, - } - engines: { node: '>= 0.8' } - - /bytes@3.1.2: - resolution: - { - integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==, - } - engines: { node: '>= 0.8' } - - /cac@6.7.14: - resolution: - { - integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, - } - engines: { node: '>=8' } - dev: true - - /cacheable-lookup@5.0.4: - resolution: - { - integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==, - } - engines: { node: '>=10.6.0' } - dev: false - - /cacheable-lookup@7.0.0: - resolution: - { - integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==, - } - engines: { node: '>=14.16' } - dev: false - - /cacheable-request@10.2.14: - resolution: - { - integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==, - } - engines: { node: '>=14.16' } - dependencies: - '@types/http-cache-semantics': 4.0.4 - get-stream: 6.0.1 - http-cache-semantics: 4.1.1 - keyv: 4.5.4 - mimic-response: 4.0.0 - normalize-url: 8.0.0 - responselike: 3.0.0 - dev: false - - /cacheable-request@7.0.4: - resolution: - { - integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==, - } - engines: { node: '>=8' } - dependencies: - clone-response: 1.0.3 - get-stream: 5.2.0 - http-cache-semantics: 4.1.1 - keyv: 4.5.4 - lowercase-keys: 2.0.0 - normalize-url: 6.1.0 - responselike: 2.0.1 - dev: false - - /cachedir@2.4.0: - resolution: - { - integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==, - } - engines: { node: '>=6' } - - /call-bind@1.0.7: - resolution: - { - integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==, - } - engines: { node: '>= 0.4' } - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - set-function-length: 1.2.1 - - /callsites@3.1.0: - resolution: - { - integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, - } - engines: { node: '>=6' } - dev: true - - /camel-case@3.0.0: - resolution: - { - integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==, - } - dependencies: - no-case: 2.3.2 - upper-case: 1.1.3 - dev: true - - /camelcase@7.0.1: - resolution: - { - integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==, - } - engines: { node: '>=14.16' } - dev: false - - /caniuse-lite@1.0.30001588: - resolution: - { - integrity: sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==, - } - dev: true - - /caseless@0.12.0: - resolution: - { - integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==, - } - dev: true - - /chai@4.4.1: - resolution: - { - integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==, - } - engines: { node: '>=4' } - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - dev: true - - /chalk@4.1.2: - resolution: - { - integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, - } - engines: { node: '>=10' } - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /chalk@5.3.0: - resolution: - { - integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==, - } - engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 } - dev: false - - /chardet@0.7.0: - resolution: - { - integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==, - } - dev: true - - /check-error@1.0.3: - resolution: - { - integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==, - } - dependencies: - get-func-name: 2.0.2 - dev: true - - /check-more-types@2.24.0: - resolution: - { - integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==, - } - engines: { node: '>= 0.8.0' } - dev: true - - /chokidar@3.6.0: - resolution: - { - integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, - } - engines: { node: '>= 8.10.0' } - dependencies: - anymatch: 3.1.3 - braces: 3.0.2 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /chromium@3.0.3: - resolution: - { - integrity: sha512-TfbzP/3t38Us5xrbb9x87M/y5I/j3jx0zeJhhQ72gjp6dwJuhVP6hBZnBH4wEg7512VVXk9zCfTuPFOdw7bQqg==, - } - os: [darwin, linux, win32] - requiresBuild: true - dependencies: - cachedir: 2.4.0 - debug: 4.3.4(supports-color@8.1.1) - extract-zip: 1.7.0 - got: 11.8.6 - progress: 2.0.3 - rimraf: 2.7.1 - tmp: 0.0.33 - tunnel: 0.0.6 - transitivePeerDependencies: - - supports-color - dev: false - - /ci-info@3.9.0: - resolution: - { - integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, - } - engines: { node: '>=8' } - - /clean-css@4.2.4: - resolution: - { - integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==, - } - engines: { node: '>= 4.0' } - dependencies: - source-map: 0.6.1 - dev: true - - /clean-stack@2.2.0: - resolution: - { - integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==, - } - engines: { node: '>=6' } - dev: true - - /cli-boxes@3.0.0: - resolution: - { - integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==, - } - engines: { node: '>=10' } - dev: false - - /cli-cursor@3.1.0: - resolution: - { - integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==, - } - engines: { node: '>=8' } - dependencies: - restore-cursor: 3.1.0 - dev: true - - /cli-spinners@2.9.2: - resolution: - { - integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==, - } - engines: { node: '>=6' } - dev: true - - /cli-table3@0.6.3: - resolution: - { - integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==, - } - engines: { node: 10.* || >= 12.* } - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.0 - dev: true - - /cli-truncate@2.1.0: - resolution: - { - integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==, - } - engines: { node: '>=8' } - dependencies: - slice-ansi: 3.0.0 - string-width: 4.2.3 - dev: true - - /cli-width@3.0.0: - resolution: - { - integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==, - } - engines: { node: '>= 10' } - dev: true - - /cliui@8.0.1: - resolution: - { - integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, - } - engines: { node: '>=12' } - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /clone-deep@4.0.1: - resolution: - { - integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==, - } - engines: { node: '>=6' } - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - dev: true - - /clone-response@1.0.3: - resolution: - { - integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==, - } - dependencies: - mimic-response: 1.0.1 - dev: false - - /clone@1.0.4: - resolution: - { - integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==, - } - engines: { node: '>=0.8' } - dev: true - - /color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: '>=7.0.0' } - dependencies: - color-name: 1.1.4 - dev: true - - /color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } - dev: true - - /colorette@2.0.20: - resolution: - { - integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, - } - dev: true - - /combined-stream@1.0.8: - resolution: - { - integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, - } - engines: { node: '>= 0.8' } - dependencies: - delayed-stream: 1.0.0 - - /commander@10.0.1: - resolution: - { - integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==, - } - engines: { node: '>=14' } - dev: true - - /commander@2.20.3: - resolution: - { - integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, - } - dev: true - - /commander@4.1.1: - resolution: - { - integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==, - } - engines: { node: '>= 6' } - dev: true - - /commander@6.2.1: - resolution: - { - integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==, - } - engines: { node: '>= 6' } - dev: true - - /common-tags@1.8.2: - resolution: - { - integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==, - } - engines: { node: '>=4.0.0' } - dev: true - - /compress-commons@4.1.2: - resolution: - { - integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==, - } - engines: { node: '>= 10' } - dependencies: - buffer-crc32: 0.2.13 - crc32-stream: 4.0.3 - normalize-path: 3.0.0 - readable-stream: 3.6.2 - dev: true - - /compressible@2.0.18: - resolution: - { - integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==, - } - engines: { node: '>= 0.6' } - dependencies: - mime-db: 1.52.0 - - /compression@1.7.4: - resolution: - { - integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==, - } - engines: { node: '>= 0.8.0' } - dependencies: - accepts: 1.3.8 - bytes: 3.0.0 - compressible: 2.0.18 - debug: 2.6.9 - on-headers: 1.0.2 - safe-buffer: 5.1.2 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - /concat-map@0.0.1: - resolution: - { - integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, - } - - /concat-stream@1.6.2: - resolution: - { - integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==, - } - engines: { '0': node >= 0.8 } - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.8 - typedarray: 0.0.6 - dev: false - - /concordance@5.0.4: - resolution: - { - integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==, - } - engines: { node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14' } - dependencies: - date-time: 3.1.0 - esutils: 2.0.3 - fast-diff: 1.3.0 - js-string-escape: 1.0.1 - lodash: 4.17.21 - md5-hex: 3.0.1 - semver: 7.6.0 - well-known-symbols: 2.0.0 - dev: true - - /config-chain@1.1.13: - resolution: - { - integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==, - } - dependencies: - ini: 1.3.8 - proto-list: 1.2.4 - - /configstore@6.0.0: - resolution: - { - integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==, - } - engines: { node: '>=12' } - dependencies: - dot-prop: 6.0.1 - graceful-fs: 4.2.11 - unique-string: 3.0.0 - write-file-atomic: 3.0.3 - xdg-basedir: 5.1.0 - dev: false - - /connect-history-api-fallback@2.0.0: - resolution: - { - integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==, - } - engines: { node: '>=0.8' } - dev: false - - /content-disposition@0.5.4: - resolution: - { - integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==, - } - engines: { node: '>= 0.6' } - dependencies: - safe-buffer: 5.2.1 - - /content-type@1.0.5: - resolution: - { - integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==, - } - engines: { node: '>= 0.6' } - - /cookie-signature@1.0.6: - resolution: - { - integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==, - } - - /cookie@0.5.0: - resolution: - { - integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==, - } - engines: { node: '>= 0.6' } - - /core-util-is@1.0.2: - resolution: - { - integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==, - } - dev: true - - /core-util-is@1.0.3: - resolution: - { - integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, - } - - /cors@2.8.5: - resolution: - { - integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==, - } - engines: { node: '>= 0.10' } - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - dev: false - - /crc-32@1.2.2: - resolution: - { - integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==, - } - engines: { node: '>=0.8' } - hasBin: true - dev: true - - /crc32-stream@4.0.3: - resolution: - { - integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==, - } - engines: { node: '>= 10' } - dependencies: - crc-32: 1.2.2 - readable-stream: 3.6.2 - dev: true - - /croppie@2.6.5: - resolution: - { - integrity: sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ==, - } - dev: false - - /cross-spawn@7.0.3: - resolution: - { - integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==, - } - engines: { node: '>= 8' } - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - /crypto-random-string@4.0.0: - resolution: - { - integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==, - } - engines: { node: '>=12' } - dependencies: - type-fest: 1.4.0 - dev: false - - /css.escape@1.5.1: - resolution: - { - integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==, - } - dev: true - - /cssesc@3.0.0: - resolution: - { - integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==, - } - engines: { node: '>=4' } - hasBin: true - dev: true - - /csstype@3.1.3: - resolution: - { - integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==, - } - - /cypress@13.6.6: - resolution: - { - integrity: sha512-S+2S9S94611hXimH9a3EAYt81QM913ZVA03pUmGDfLTFa5gyp85NJ8dJGSlEAEmyRsYkioS1TtnWtbv/Fzt11A==, - } - engines: { node: ^16.0.0 || ^18.0.0 || >=20.0.0 } - hasBin: true - requiresBuild: true - dependencies: - '@cypress/request': 3.0.1 - '@cypress/xvfb': 1.2.4(supports-color@8.1.1) - '@types/sinonjs__fake-timers': 8.1.1 - '@types/sizzle': 2.3.8 - arch: 2.2.0 - blob-util: 2.0.2 - bluebird: 3.7.2 - buffer: 5.7.1 - cachedir: 2.4.0 - chalk: 4.1.2 - check-more-types: 2.24.0 - cli-cursor: 3.1.0 - cli-table3: 0.6.3 - commander: 6.2.1 - common-tags: 1.8.2 - dayjs: 1.11.10 - debug: 4.3.4(supports-color@8.1.1) - enquirer: 2.4.1 - eventemitter2: 6.4.7 - execa: 4.1.0 - executable: 4.1.1 - extract-zip: 2.0.1(supports-color@8.1.1) - figures: 3.2.0 - fs-extra: 9.1.0 - getos: 3.2.1 - is-ci: 3.0.1 - is-installed-globally: 0.4.0 - lazy-ass: 1.6.0 - listr2: 3.14.0(enquirer@2.4.1) - lodash: 4.17.21 - log-symbols: 4.1.0 - minimist: 1.2.8 - ospath: 1.2.2 - pretty-bytes: 5.6.0 - process: 0.11.10 - proxy-from-env: 1.0.0 - request-progress: 3.0.0 - semver: 7.6.0 - supports-color: 8.1.1 - tmp: 0.2.1 - untildify: 4.0.0 - yauzl: 2.10.0 - dev: true - - /dashdash@1.14.1: - resolution: - { - integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==, - } - engines: { node: '>=0.10' } - dependencies: - assert-plus: 1.0.0 - dev: true - - /date-time@3.1.0: - resolution: - { - integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==, - } - engines: { node: '>=6' } - dependencies: - time-zone: 1.0.0 - dev: true - - /dayjs@1.11.10: - resolution: - { - integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==, - } - dev: true - - /debug@2.6.9: - resolution: - { - integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==, - } - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - - /debug@3.1.0: - resolution: - { - integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==, - } - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: false - - /debug@3.2.7(supports-color@8.1.1): - resolution: - { - integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==, - } - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - supports-color: 8.1.1 - dev: true - - /debug@4.3.4(supports-color@8.1.1): - resolution: - { - integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==, - } - engines: { node: '>=6.0' } - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - supports-color: 8.1.1 - - /decompress-response@6.0.0: - resolution: - { - integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==, - } - engines: { node: '>=10' } - dependencies: - mimic-response: 3.1.0 - dev: false - - /deep-eql@4.1.3: - resolution: - { - integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==, - } - engines: { node: '>=6' } - dependencies: - type-detect: 4.0.8 - dev: true - - /deep-extend@0.6.0: - resolution: - { - integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==, - } - engines: { node: '>=4.0.0' } - dev: false - - /deep-is@0.1.4: - resolution: - { - integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, - } - dev: true - - /default-browser-id@3.0.0: - resolution: - { - integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==, - } - engines: { node: '>=12' } - dependencies: - bplist-parser: 0.2.0 - untildify: 4.0.0 - dev: false - - /default-browser@4.0.0: - resolution: - { - integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==, - } - engines: { node: '>=14.16' } - dependencies: - bundle-name: 3.0.0 - default-browser-id: 3.0.0 - execa: 7.2.0 - titleize: 3.0.0 - dev: false - - /defaults@1.0.4: - resolution: - { - integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==, - } - dependencies: - clone: 1.0.4 - dev: true - - /defer-to-connect@2.0.1: - resolution: - { - integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==, - } - engines: { node: '>=10' } - dev: false - - /define-data-property@1.1.4: - resolution: - { - integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==, - } - engines: { node: '>= 0.4' } - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 - - /define-lazy-prop@2.0.0: - resolution: - { - integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==, - } - engines: { node: '>=8' } - dev: true - - /define-lazy-prop@3.0.0: - resolution: - { - integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==, - } - engines: { node: '>=12' } - dev: false - - /delayed-stream@1.0.0: - resolution: - { - integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, - } - engines: { node: '>=0.4.0' } - - /depd@2.0.0: - resolution: - { - integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==, - } - engines: { node: '>= 0.8' } - - /destroy@1.2.0: - resolution: - { - integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==, - } - engines: { node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16 } - - /doctrine@3.0.0: - resolution: - { - integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==, - } - engines: { node: '>=6.0.0' } - dependencies: - esutils: 2.0.3 - dev: true - - /dot-prop@6.0.1: - resolution: - { - integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==, - } - engines: { node: '>=10' } - dependencies: - is-obj: 2.0.0 - - /eastasianwidth@0.2.0: - resolution: - { - integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, - } - - /ecc-jsbn@0.1.2: - resolution: - { - integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==, - } - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: true - - /editorconfig@1.0.4: - resolution: - { - integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==, - } - engines: { node: '>=14' } - hasBin: true - dependencies: - '@one-ini/wasm': 0.1.1 - commander: 10.0.1 - minimatch: 9.0.1 - semver: 7.6.0 - dev: true - - /ee-first@1.1.1: - resolution: - { - integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, - } - - /electron-to-chromium@1.4.677: - resolution: - { - integrity: sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q==, - } - dev: true - - /elementtree@0.1.7: - resolution: - { - integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==, - } - engines: { node: '>= 0.4.0' } - dependencies: - sax: 1.1.4 - dev: true - - /emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } - - /emoji-regex@9.2.2: - resolution: - { - integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, - } - - /encodeurl@1.0.2: - resolution: - { - integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==, - } - engines: { node: '>= 0.8' } - - /end-of-stream@1.4.4: - resolution: - { - integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==, - } - dependencies: - once: 1.4.0 - - /enquirer@2.4.1: - resolution: - { - integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==, - } - engines: { node: '>=8.6' } - dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - dev: true - - /entities@4.5.0: - resolution: - { - integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==, - } - engines: { node: '>=0.12' } - - /es-define-property@1.0.0: - resolution: - { - integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==, - } - engines: { node: '>= 0.4' } - dependencies: - get-intrinsic: 1.2.4 - - /es-errors@1.3.0: - resolution: - { - integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, - } - engines: { node: '>= 0.4' } - - /esbuild-android-64@0.14.51: - resolution: - { - integrity: sha512-6FOuKTHnC86dtrKDmdSj2CkcKF8PnqkaIXqvgydqfJmqBazCPdw+relrMlhGjkvVdiiGV70rpdnyFmA65ekBCQ==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [android] - requiresBuild: true - dev: true + stylus: optional: true - - /esbuild-android-arm64@0.14.51: - resolution: - { - integrity: sha512-vBtp//5VVkZWmYYvHsqBRCMMi1MzKuMIn5XDScmnykMTu9+TD9v0NMEDqQxvtFToeYmojdo5UCV2vzMQWJcJ4A==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + sugarss: optional: true - - /esbuild-darwin-64@0.14.51: - resolution: - { - integrity: sha512-YFmXPIOvuagDcwCejMRtCDjgPfnDu+bNeh5FU2Ryi68ADDVlWEpbtpAbrtf/lvFTWPexbgyKgzppNgsmLPr8PA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + terser: optional: true - - /esbuild-darwin-arm64@0.14.51: - resolution: - { - integrity: sha512-juYD0QnSKwAMfzwKdIF6YbueXzS6N7y4GXPDeDkApz/1RzlT42mvX9jgNmyOlWKN7YzQAYbcUEJmZJYQGdf2ow==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + dependencies: + '@types/node': 20.11.19 + esbuild: 0.18.20 + postcss: 8.4.35 + rollup: 3.29.4 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vite@5.1.4(@types/node@20.11.19): + resolution: {integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': optional: true - - /esbuild-freebsd-64@0.14.51: - resolution: - { - integrity: sha512-cLEI/aXjb6vo5O2Y8rvVSQ7smgLldwYY5xMxqh/dQGfWO+R1NJOFsiax3IS4Ng300SVp7Gz3czxT6d6qf2cw0g==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true + less: optional: true - - /esbuild-freebsd-arm64@0.14.51: - resolution: - { - integrity: sha512-TcWVw/rCL2F+jUgRkgLa3qltd5gzKjIMGhkVybkjk6PJadYInPtgtUBp1/hG+mxyigaT7ib+od1Xb84b+L+1Mg==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true + lightningcss: optional: true - - /esbuild-linux-32@0.14.51: - resolution: - { - integrity: sha512-RFqpyC5ChyWrjx8Xj2K0EC1aN0A37H6OJfmUXIASEqJoHcntuV3j2Efr9RNmUhMfNE6yEj2VpYuDteZLGDMr0w==, - } - engines: { node: '>=12' } - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true + sass: optional: true - - /esbuild-linux-64@0.14.51: - resolution: - { - integrity: sha512-dxjhrqo5i7Rq6DXwz5v+MEHVs9VNFItJmHBe1CxROWNf4miOGoQhqSG8StStbDkQ1Mtobg6ng+4fwByOhoQoeA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true + stylus: optional: true - - /esbuild-linux-arm64@0.14.51: - resolution: - { - integrity: sha512-D9rFxGutoqQX3xJPxqd6o+kvYKeIbM0ifW2y0bgKk5HPgQQOo2k9/2Vpto3ybGYaFPCE5qTGtqQta9PoP6ZEzw==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + sugarss: optional: true - - /esbuild-linux-arm@0.14.51: - resolution: - { - integrity: sha512-LsJynDxYF6Neg7ZC7748yweCDD+N8ByCv22/7IAZglIEniEkqdF4HCaa49JNDLw1UQGlYuhOB8ZT/MmcSWzcWg==, - } - engines: { node: '>=12' } - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + terser: optional: true - - /esbuild-linux-mips64le@0.14.51: - resolution: - { - integrity: sha512-vS54wQjy4IinLSlb5EIlLoln8buh1yDgliP4CuEHumrPk4PvvP4kTRIG4SzMXm6t19N0rIfT4bNdAxzJLg2k6A==, - } - engines: { node: '>=12' } - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true + dependencies: + '@types/node': 20.11.19 + esbuild: 0.19.12 + postcss: 8.4.35 + rollup: 4.12.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /vitest@0.31.4: + resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': optional: true - - /esbuild-linux-ppc64le@0.14.51: - resolution: - { - integrity: sha512-xcdd62Y3VfGoyphNP/aIV9LP+RzFw5M5Z7ja+zdpQHHvokJM7d0rlDRMN+iSSwvUymQkqZO+G/xjb4/75du8BQ==, - } - engines: { node: '>=12' } - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true + '@vitest/browser': optional: true - - /esbuild-linux-riscv64@0.14.51: - resolution: - { - integrity: sha512-syXHGak9wkAnFz0gMmRBoy44JV0rp4kVCEA36P5MCeZcxFq8+fllBC2t6sKI23w3qd8Vwo9pTADCgjTSf3L3rA==, - } - engines: { node: '>=12' } - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true + '@vitest/ui': optional: true - - /esbuild-linux-s390x@0.14.51: - resolution: - { - integrity: sha512-kFAJY3dv+Wq8o28K/C7xkZk/X34rgTwhknSsElIqoEo8armCOjMJ6NsMxm48KaWY2h2RUYGtQmr+RGuUPKBhyw==, - } - engines: { node: '>=12' } - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true + happy-dom: optional: true - - /esbuild-netbsd-64@0.14.51: - resolution: - { - integrity: sha512-ZZBI7qrR1FevdPBVHz/1GSk1x5GDL/iy42Zy8+neEm/HA7ma+hH/bwPEjeHXKWUDvM36CZpSL/fn1/y9/Hb+1A==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true + jsdom: optional: true - - /esbuild-openbsd-64@0.14.51: - resolution: - { - integrity: sha512-7R1/p39M+LSVQVgDVlcY1KKm6kFKjERSX1lipMG51NPcspJD1tmiZSmmBXoY5jhHIu6JL1QkFDTx94gMYK6vfA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true + playwright: optional: true - - /esbuild-sunos-64@0.14.51: - resolution: - { - integrity: sha512-HoHaCswHxLEYN8eBTtyO0bFEWvA3Kdb++hSQ/lLG7TyKF69TeSG0RNoBRAs45x/oCeWaTDntEZlYwAfQlhEtJA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true + safaridriver: optional: true - - /esbuild-windows-32@0.14.51: - resolution: - { - integrity: sha512-4rtwSAM35A07CBt1/X8RWieDj3ZUHQqUOaEo5ZBs69rt5WAFjP4aqCIobdqOy4FdhYw1yF8Z0xFBTyc9lgPtEg==, - } - engines: { node: '>=12' } - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /esbuild-windows-64@0.14.51: - resolution: - { - integrity: sha512-HoN/5HGRXJpWODprGCgKbdMvrC3A2gqvzewu2eECRw2sYxOUoh2TV1tS+G7bHNapPGI79woQJGV6pFH7GH7qnA==, - } - engines: { node: '>=12' } - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + webdriverio: optional: true - - /esbuild-windows-arm64@0.14.51: - resolution: - { - integrity: sha512-JQDqPjuOH7o+BsKMSddMfmVJXrnYZxXDHsoLHc0xgmAZkOOCflRmC43q31pk79F9xuyWY45jDBPolb5ZgGOf9g==, - } - engines: { node: '>=12' } - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + dependencies: + '@types/chai': 4.3.12 + '@types/chai-subset': 1.3.5 + '@types/node': 20.11.19 + '@vitest/expect': 0.31.4 + '@vitest/runner': 0.31.4 + '@vitest/snapshot': 0.31.4 + '@vitest/spy': 0.31.4 + '@vitest/utils': 0.31.4 + acorn: 8.11.3 + acorn-walk: 8.3.2 + cac: 6.7.14 + chai: 4.4.1 + concordance: 5.0.4 + debug: 4.3.4(supports-color@8.1.1) + local-pkg: 0.4.3 + magic-string: 0.30.7 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 1.3.0 + tinybench: 2.6.0 + tinypool: 0.5.0 + vite: 4.5.2(@types/node@20.11.19) + vite-node: 0.31.4(@types/node@20.11.19) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vue-component-type-helpers@1.8.27: + resolution: {integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==} + dev: true + + /vue-demi@0.14.7(vue@3.4.19): + resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': optional: true - - /esbuild@0.14.51: - resolution: - { - integrity: sha512-+CvnDitD7Q5sT7F+FM65sWkF8wJRf+j9fPcprxYV4j+ohmzVj2W7caUqH2s5kCaCJAfcAICjSlKhDCcvDpU7nw==, - } - engines: { node: '>=12' } - hasBin: true - requiresBuild: true - optionalDependencies: - esbuild-android-64: 0.14.51 - esbuild-android-arm64: 0.14.51 - esbuild-darwin-64: 0.14.51 - esbuild-darwin-arm64: 0.14.51 - esbuild-freebsd-64: 0.14.51 - esbuild-freebsd-arm64: 0.14.51 - esbuild-linux-32: 0.14.51 - esbuild-linux-64: 0.14.51 - esbuild-linux-arm: 0.14.51 - esbuild-linux-arm64: 0.14.51 - esbuild-linux-mips64le: 0.14.51 - esbuild-linux-ppc64le: 0.14.51 - esbuild-linux-riscv64: 0.14.51 - esbuild-linux-s390x: 0.14.51 - esbuild-netbsd-64: 0.14.51 - esbuild-openbsd-64: 0.14.51 - esbuild-sunos-64: 0.14.51 - esbuild-windows-32: 0.14.51 - esbuild-windows-64: 0.14.51 - esbuild-windows-arm64: 0.14.51 - dev: true - - /esbuild@0.18.20: - resolution: - { - integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==, - } - engines: { node: '>=12' } - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.18.20 - '@esbuild/android-arm64': 0.18.20 - '@esbuild/android-x64': 0.18.20 - '@esbuild/darwin-arm64': 0.18.20 - '@esbuild/darwin-x64': 0.18.20 - '@esbuild/freebsd-arm64': 0.18.20 - '@esbuild/freebsd-x64': 0.18.20 - '@esbuild/linux-arm': 0.18.20 - '@esbuild/linux-arm64': 0.18.20 - '@esbuild/linux-ia32': 0.18.20 - '@esbuild/linux-loong64': 0.18.20 - '@esbuild/linux-mips64el': 0.18.20 - '@esbuild/linux-ppc64': 0.18.20 - '@esbuild/linux-riscv64': 0.18.20 - '@esbuild/linux-s390x': 0.18.20 - '@esbuild/linux-x64': 0.18.20 - '@esbuild/netbsd-x64': 0.18.20 - '@esbuild/openbsd-x64': 0.18.20 - '@esbuild/sunos-x64': 0.18.20 - '@esbuild/win32-arm64': 0.18.20 - '@esbuild/win32-ia32': 0.18.20 - '@esbuild/win32-x64': 0.18.20 - dev: true - - /esbuild@0.19.12: - resolution: - { - integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==, - } - engines: { node: '>=12' } - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - dev: true - - /escalade@3.1.2: - resolution: - { - integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==, - } - engines: { node: '>=6' } - dev: true - - /escape-goat@4.0.0: - resolution: - { - integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==, - } - engines: { node: '>=12' } - dev: false - - /escape-html@1.0.3: - resolution: - { - integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==, - } - - /escape-string-regexp@1.0.5: - resolution: - { - integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, - } - engines: { node: '>=0.8.0' } - dev: true - - /escape-string-regexp@4.0.0: - resolution: - { - integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, - } - engines: { node: '>=10' } - dev: true - - /eslint-config-prettier@8.10.0(eslint@8.56.0): - resolution: - { - integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==, - } - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.56.0 - dev: true - - /eslint-plugin-cypress@2.15.1(eslint@8.56.0): - resolution: - { - integrity: sha512-eLHLWP5Q+I4j2AWepYq0PgFEei9/s5LvjuSqWrxurkg1YZ8ltxdvMNmdSf0drnsNo57CTgYY/NIHHLRSWejR7w==, - } - peerDependencies: - eslint: '>= 3.2.1' - dependencies: - eslint: 8.56.0 - globals: 13.24.0 - dev: true - - /eslint-plugin-vue@9.21.1(eslint@8.56.0): - resolution: - { - integrity: sha512-XVtI7z39yOVBFJyi8Ljbn7kY9yHzznKXL02qQYn+ta63Iy4A9JFBw6o4OSB9hyD2++tVT+su9kQqetUyCCwhjw==, - } - engines: { node: ^14.17.0 || >=16.0.0 } - peerDependencies: - eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - eslint: 8.56.0 - natural-compare: 1.4.0 - nth-check: 2.1.1 - postcss-selector-parser: 6.0.15 - semver: 7.6.0 - vue-eslint-parser: 9.4.2(eslint@8.56.0) - xml-name-validator: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-scope@7.2.2: - resolution: - { - integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true - - /eslint-utils@2.1.0: - resolution: - { - integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==, - } - engines: { node: '>=6' } - dependencies: - eslint-visitor-keys: 1.3.0 - dev: true - - /eslint-visitor-keys@1.3.0: - resolution: - { - integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==, - } - engines: { node: '>=4' } - dev: true - - /eslint-visitor-keys@3.4.3: - resolution: - { - integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - dev: true - - /eslint@8.56.0: - resolution: - { - integrity: sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0) - '@eslint-community/regexpp': 4.10.0 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.56.0 - '@humanwhocodes/config-array': 0.11.14 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.1 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /espree@6.2.1: - resolution: - { - integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==, - } - engines: { node: '>=6.0.0' } - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2(acorn@7.4.1) - eslint-visitor-keys: 1.3.0 - dev: true - - /espree@9.6.1: - resolution: - { - integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - dependencies: - acorn: 8.11.3 - acorn-jsx: 5.3.2(acorn@8.11.3) - eslint-visitor-keys: 3.4.3 - dev: true - - /esquery@1.5.0: - resolution: - { - integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==, - } - engines: { node: '>=0.10' } - dependencies: - estraverse: 5.3.0 - dev: true - - /esrecurse@4.3.0: - resolution: - { - integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, - } - engines: { node: '>=4.0' } - dependencies: - estraverse: 5.3.0 - dev: true - - /estraverse@5.3.0: - resolution: - { - integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, - } - engines: { node: '>=4.0' } - dev: true - - /estree-walker@2.0.2: - resolution: - { - integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==, - } - - /esutils@2.0.3: - resolution: - { - integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, - } - engines: { node: '>=0.10.0' } - dev: true - - /etag@1.8.1: - resolution: - { - integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==, - } - engines: { node: '>= 0.6' } - - /eventemitter2@6.4.7: - resolution: - { - integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==, - } - dev: true - - /eventemitter3@4.0.7: - resolution: - { - integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==, - } - dev: false - - /execa@4.1.0: - resolution: - { - integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==, - } - engines: { node: '>=10' } - dependencies: - cross-spawn: 7.0.3 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /execa@5.1.1: - resolution: - { - integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, - } - engines: { node: '>=10' } - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: false - - /execa@7.2.0: - resolution: - { - integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==, - } - engines: { node: ^14.18.0 || ^16.14.0 || >=18.0.0 } - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.2.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - dev: false - - /executable@4.1.1: - resolution: - { - integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==, - } - engines: { node: '>=4' } - dependencies: - pify: 2.3.0 - dev: true - - /express@4.18.2: - resolution: - { - integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==, - } - engines: { node: '>= 0.10.0' } - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.1 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - /extend@3.0.2: - resolution: - { - integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==, - } - dev: true - - /external-editor@3.1.0: - resolution: - { - integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==, - } - engines: { node: '>=4' } - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - - /extract-zip@1.7.0: - resolution: - { - integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==, - } - hasBin: true - dependencies: - concat-stream: 1.6.2 - debug: 2.6.9 - mkdirp: 0.5.6 - yauzl: 2.10.0 - transitivePeerDependencies: - - supports-color - dev: false - - /extract-zip@2.0.1(supports-color@8.1.1): - resolution: - { - integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==, - } - engines: { node: '>= 10.17.0' } - hasBin: true - dependencies: - debug: 4.3.4(supports-color@8.1.1) - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - dev: true - - /extsprintf@1.3.0: - resolution: - { - integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==, - } - engines: { '0': node >=0.6.0 } - dev: true - - /fast-deep-equal@3.1.3: - resolution: - { - integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, - } - dev: true - - /fast-diff@1.3.0: - resolution: - { - integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==, - } - dev: true - - /fast-glob@3.2.12: - resolution: - { - integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==, - } - engines: { node: '>=8.6.0' } - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-glob@3.3.2: - resolution: - { - integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==, - } - engines: { node: '>=8.6.0' } - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: - { - integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, - } - dev: true - - /fast-levenshtein@2.0.6: - resolution: - { - integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, - } - dev: true - - /fastq@1.17.1: - resolution: - { - integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==, - } - dependencies: - reusify: 1.0.4 - dev: true - - /fd-slicer@1.1.0: - resolution: - { - integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==, - } - dependencies: - pend: 1.2.0 - - /figures@3.2.0: - resolution: - { - integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==, - } - engines: { node: '>=8' } - dependencies: - escape-string-regexp: 1.0.5 - dev: true - - /file-entry-cache@6.0.1: - resolution: - { - integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==, - } - engines: { node: ^10.12.0 || >=12.0.0 } - dependencies: - flat-cache: 3.2.0 - dev: true - - /fill-range@7.0.1: - resolution: - { - integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, - } - engines: { node: '>=8' } - dependencies: - to-regex-range: 5.0.1 - - /finalhandler@1.2.0: - resolution: - { - integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==, - } - engines: { node: '>= 0.8' } - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - /find-up@5.0.0: - resolution: - { - integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, - } - engines: { node: '>=10' } - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - - /flat-cache@3.2.0: - resolution: - { - integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==, - } - engines: { node: ^10.12.0 || >=12.0.0 } - dependencies: - flatted: 3.3.1 - keyv: 4.5.4 - rimraf: 3.0.2 - dev: true - - /flat@5.0.2: - resolution: - { - integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==, - } - hasBin: true - dev: true - - /flatted@3.3.1: - resolution: - { - integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==, - } - dev: true - - /follow-redirects@1.15.5: - resolution: - { - integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==, - } - engines: { node: '>=4.0' } - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /foreground-child@3.1.1: - resolution: - { - integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==, - } - engines: { node: '>=14' } - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - dev: true - - /forever-agent@0.6.1: - resolution: - { - integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==, - } - dev: true - - /form-data-encoder@2.1.4: - resolution: - { - integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==, - } - engines: { node: '>= 14.17' } - dev: false - - /form-data@2.3.3: - resolution: - { - integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==, - } - engines: { node: '>= 0.12' } - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: true - - /form-data@4.0.0: - resolution: - { - integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==, - } - engines: { node: '>= 6' } - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /forwarded@0.2.0: - resolution: - { - integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==, - } - engines: { node: '>= 0.6' } - - /fraction.js@4.3.7: - resolution: - { - integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==, - } - dev: true - - /fresh@0.5.2: - resolution: - { - integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==, - } - engines: { node: '>= 0.6' } - - /fs-constants@1.0.0: - resolution: - { - integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==, - } - dev: true - - /fs-extra@11.2.0: - resolution: - { - integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==, - } - engines: { node: '>=14.14' } - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - /fs-extra@9.1.0: - resolution: - { - integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==, - } - engines: { node: '>=10' } - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - dev: true - - /fs.realpath@1.0.0: - resolution: - { - integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, - } - - /fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } - os: [darwin] - requiresBuild: true - dev: true + dependencies: + vue: 3.4.19(typescript@5.5.4) + + /vue-eslint-parser@9.4.2(eslint@8.56.0): + resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4(supports-color@8.1.1) + eslint: 8.56.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + dev: true + + /vue-i18n@9.9.1(vue@3.4.19): + resolution: {integrity: sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==} + engines: {node: '>= 16'} + peerDependencies: + vue: ^3.0.0 + dependencies: + '@intlify/core-base': 9.9.1 + '@intlify/shared': 9.9.1 + '@vue/devtools-api': 6.6.1 + vue: 3.4.19(typescript@5.5.4) + + /vue-router@4.2.5(vue@3.4.19): + resolution: {integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==} + peerDependencies: + vue: ^3.2.0 + dependencies: + '@vue/devtools-api': 6.6.1 + vue: 3.4.19(typescript@5.5.4) + + /vue@3.4.19(typescript@5.5.4): + resolution: {integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: optional: true - - /function-bind@1.1.2: - resolution: - { - integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, - } - - /get-caller-file@2.0.5: - resolution: - { - integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, - } - engines: { node: 6.* || 8.* || >= 10.* } - dev: true - - /get-func-name@2.0.2: - resolution: - { - integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==, - } - dev: true - - /get-intrinsic@1.2.4: - resolution: - { - integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==, - } - engines: { node: '>= 0.4' } - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 - hasown: 2.0.1 - - /get-stream@5.2.0: - resolution: - { - integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==, - } - engines: { node: '>=8' } - dependencies: - pump: 3.0.0 - - /get-stream@6.0.1: - resolution: - { - integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, - } - engines: { node: '>=10' } - dev: false - - /getos@3.2.1: - resolution: - { - integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==, - } - dependencies: - async: 3.2.5 - dev: true - - /getpass@0.1.7: - resolution: - { - integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==, - } - dependencies: - assert-plus: 1.0.0 - dev: true - - /glob-parent@5.1.2: - resolution: - { - integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, - } - engines: { node: '>= 6' } - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-parent@6.0.2: - resolution: - { - integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, - } - engines: { node: '>=10.13.0' } - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-regex@0.3.2: - resolution: - { - integrity: sha512-m5blUd3/OqDTWwzBBtWBPrGlAzatRywHameHeekAZyZrskYouOGdNB8T/q6JucucvJXtOuyHIn0/Yia7iDasDw==, - } - dev: true - - /glob@10.3.10: - resolution: - { - integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==, - } - engines: { node: '>=16 || 14 >=14.17' } - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.3 - minipass: 7.0.4 - path-scurry: 1.10.1 - dev: true - - /glob@7.2.3: - resolution: - { - integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, - } - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - /global-dirs@3.0.1: - resolution: - { - integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==, - } - engines: { node: '>=10' } - dependencies: - ini: 2.0.0 - - /globals@13.24.0: - resolution: - { - integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==, - } - engines: { node: '>=8' } - dependencies: - type-fest: 0.20.2 - dev: true - - /globrex@0.1.2: - resolution: - { - integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==, - } - dev: true - - /gopd@1.0.1: - resolution: - { - integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==, - } - dependencies: - get-intrinsic: 1.2.4 - - /got@11.8.6: - resolution: - { - integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==, - } - engines: { node: '>=10.19.0' } - dependencies: - '@sindresorhus/is': 4.6.0 - '@szmarczak/http-timer': 4.0.6 - '@types/cacheable-request': 6.0.3 - '@types/responselike': 1.0.3 - cacheable-lookup: 5.0.4 - cacheable-request: 7.0.4 - decompress-response: 6.0.0 - http2-wrapper: 1.0.3 - lowercase-keys: 2.0.0 - p-cancelable: 2.1.1 - responselike: 2.0.1 - dev: false - - /got@12.6.1: - resolution: - { - integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==, - } - engines: { node: '>=14.16' } - dependencies: - '@sindresorhus/is': 5.6.0 - '@szmarczak/http-timer': 5.0.1 - cacheable-lookup: 7.0.0 - cacheable-request: 10.2.14 - decompress-response: 6.0.0 - form-data-encoder: 2.1.4 - get-stream: 6.0.1 - http2-wrapper: 2.2.1 - lowercase-keys: 3.0.0 - p-cancelable: 3.0.0 - responselike: 3.0.0 - dev: false - - /graceful-fs@4.2.10: - resolution: - { - integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==, - } - dev: false - - /graceful-fs@4.2.11: - resolution: - { - integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, - } - - /graphemer@1.4.0: - resolution: - { - integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, - } - dev: true - - /happy-dom@11.2.0: - resolution: - { - integrity: sha512-z4PshcYIIH6SkymSNRcDFwYUJOENe+FOQDx5BbHgg/wQUgxF5p9I9/BN45Jff34bbhXV8yJgkC5N99eyOzXK3w==, - } - dependencies: - css.escape: 1.5.1 - entities: 4.5.0 - iconv-lite: 0.6.3 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - dev: true - - /has-flag@4.0.0: - resolution: - { - integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, - } - engines: { node: '>=8' } - - /has-property-descriptors@1.0.2: - resolution: - { - integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==, - } - dependencies: - es-define-property: 1.0.0 - - /has-proto@1.0.3: - resolution: - { - integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==, - } - engines: { node: '>= 0.4' } - - /has-symbols@1.0.3: - resolution: - { - integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==, - } - engines: { node: '>= 0.4' } - - /has-yarn@3.0.0: - resolution: - { - integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dev: false - - /hasown@2.0.1: - resolution: - { - integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==, - } - engines: { node: '>= 0.4' } - dependencies: - function-bind: 1.1.2 - - /he@1.2.0: - resolution: - { - integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, - } - hasBin: true - dev: true - - /html-minifier@4.0.0: - resolution: - { - integrity: sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==, - } - engines: { node: '>=6' } - hasBin: true - dependencies: - camel-case: 3.0.0 - clean-css: 4.2.4 - commander: 2.20.3 - he: 1.2.0 - param-case: 2.1.1 - relateurl: 0.2.7 - uglify-js: 3.17.4 - dev: true - - /http-cache-semantics@4.1.1: - resolution: - { - integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==, - } - dev: false - - /http-errors@2.0.0: - resolution: - { - integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==, - } - engines: { node: '>= 0.8' } - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - /http-proxy-middleware@2.0.6: - resolution: - { - integrity: sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==, - } - engines: { node: '>=12.0.0' } - peerDependencies: - '@types/express': ^4.17.13 - peerDependenciesMeta: - '@types/express': - optional: true - dependencies: - '@types/http-proxy': 1.17.14 - http-proxy: 1.18.1 - is-glob: 4.0.3 - is-plain-obj: 3.0.0 - micromatch: 4.0.5 - transitivePeerDependencies: - - debug - dev: false - - /http-proxy@1.18.1: - resolution: - { - integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==, - } - engines: { node: '>=8.0.0' } - dependencies: - eventemitter3: 4.0.7 - follow-redirects: 1.15.5 - requires-port: 1.0.0 - transitivePeerDependencies: - - debug - dev: false - - /http-signature@1.3.6: - resolution: - { - integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==, - } - engines: { node: '>=0.10' } - dependencies: - assert-plus: 1.0.0 - jsprim: 2.0.2 - sshpk: 1.18.0 - dev: true - - /http2-wrapper@1.0.3: - resolution: - { - integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==, - } - engines: { node: '>=10.19.0' } - dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.2.1 - dev: false - - /http2-wrapper@2.2.1: - resolution: - { - integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==, - } - engines: { node: '>=10.19.0' } - dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.2.1 - dev: false - - /human-signals@1.1.1: - resolution: - { - integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==, - } - engines: { node: '>=8.12.0' } - dev: true - - /human-signals@2.1.0: - resolution: - { - integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, - } - engines: { node: '>=10.17.0' } - dev: false - - /human-signals@4.3.1: - resolution: - { - integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==, - } - engines: { node: '>=14.18.0' } - dev: false - - /iconv-lite@0.4.24: - resolution: - { - integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==, - } - engines: { node: '>=0.10.0' } - dependencies: - safer-buffer: 2.1.2 - - /iconv-lite@0.6.3: - resolution: - { - integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==, - } - engines: { node: '>=0.10.0' } - dependencies: - safer-buffer: 2.1.2 - dev: true - - /ieee754@1.2.1: - resolution: - { - integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, - } - dev: true - - /ignore@5.3.1: - resolution: - { - integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==, - } - engines: { node: '>= 4' } - dev: true - - /immutable@4.3.5: - resolution: - { - integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==, - } - dev: true - - /import-fresh@3.3.0: - resolution: - { - integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==, - } - engines: { node: '>=6' } - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - /import-lazy@4.0.0: - resolution: - { - integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==, - } - engines: { node: '>=8' } - dev: false - - /imurmurhash@0.1.4: - resolution: - { - integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, - } - engines: { node: '>=0.8.19' } - - /indent-string@4.0.0: - resolution: - { - integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, - } - engines: { node: '>=8' } - dev: true - - /inflight@1.0.6: - resolution: - { - integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, - } - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - /inherits@2.0.4: - resolution: - { - integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, - } - - /ini@1.3.8: - resolution: - { - integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, - } - - /ini@2.0.0: - resolution: - { - integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==, - } - engines: { node: '>=10' } - - /inquirer@8.2.6: - resolution: - { - integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==, - } - engines: { node: '>=12.0.0' } - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - ora: 5.4.1 - run-async: 2.4.1 - rxjs: 7.8.1 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - wrap-ansi: 6.2.0 - dev: true - - /ipaddr.js@1.9.1: - resolution: - { - integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==, - } - engines: { node: '>= 0.10' } - - /is-binary-path@2.1.0: - resolution: - { - integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, - } - engines: { node: '>=8' } - dependencies: - binary-extensions: 2.2.0 - dev: true - - /is-ci@3.0.1: - resolution: - { - integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==, - } - hasBin: true - dependencies: - ci-info: 3.9.0 - - /is-core-module@2.13.1: - resolution: - { - integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==, - } - dependencies: - hasown: 2.0.1 - dev: true - - /is-docker@2.2.1: - resolution: - { - integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==, - } - engines: { node: '>=8' } - hasBin: true - - /is-docker@3.0.0: - resolution: - { - integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - hasBin: true - dev: false - - /is-extglob@2.1.1: - resolution: - { - integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, - } - engines: { node: '>=0.10.0' } - - /is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: '>=8' } - - /is-glob@4.0.3: - resolution: - { - integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, - } - engines: { node: '>=0.10.0' } - dependencies: - is-extglob: 2.1.1 - - /is-inside-container@1.0.0: - resolution: - { - integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==, - } - engines: { node: '>=14.16' } - hasBin: true - dependencies: - is-docker: 3.0.0 - dev: false - - /is-installed-globally@0.4.0: - resolution: - { - integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==, - } - engines: { node: '>=10' } - dependencies: - global-dirs: 3.0.1 - is-path-inside: 3.0.3 - - /is-interactive@1.0.0: - resolution: - { - integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==, - } - engines: { node: '>=8' } - dev: true - - /is-npm@6.0.0: - resolution: - { - integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dev: false - - /is-number@7.0.0: - resolution: - { - integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, - } - engines: { node: '>=0.12.0' } - - /is-obj@2.0.0: - resolution: - { - integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==, - } - engines: { node: '>=8' } - - /is-path-inside@3.0.3: - resolution: - { - integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, - } - engines: { node: '>=8' } - - /is-plain-obj@3.0.0: - resolution: - { - integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==, - } - engines: { node: '>=10' } - dev: false - - /is-plain-object@2.0.4: - resolution: - { - integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==, - } - engines: { node: '>=0.10.0' } - dependencies: - isobject: 3.0.1 - dev: true - - /is-stream@2.0.1: - resolution: - { - integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, - } - engines: { node: '>=8' } - - /is-stream@3.0.0: - resolution: - { - integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dev: false - - /is-typedarray@1.0.0: - resolution: - { - integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==, - } - - /is-unicode-supported@0.1.0: - resolution: - { - integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==, - } - engines: { node: '>=10' } - dev: true - - /is-wsl@2.2.0: - resolution: - { - integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==, - } - engines: { node: '>=8' } - dependencies: - is-docker: 2.2.1 - - /is-yarn-global@0.4.1: - resolution: - { - integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==, - } - engines: { node: '>=12' } - dev: false - - /isarray@1.0.0: - resolution: - { - integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==, - } - - /isbinaryfile@5.0.2: - resolution: - { - integrity: sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==, - } - engines: { node: '>= 18.0.0' } - dev: true - - /isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } - - /isobject@3.0.1: - resolution: - { - integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==, - } - engines: { node: '>=0.10.0' } - dev: true - - /isstream@0.1.2: - resolution: - { - integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==, - } - dev: true - - /jackspeak@2.3.6: - resolution: - { - integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==, - } - engines: { node: '>=14' } - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - dev: true - - /js-beautify@1.15.1: - resolution: - { - integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==, - } - engines: { node: '>=14' } - hasBin: true - dependencies: - config-chain: 1.1.13 - editorconfig: 1.0.4 - glob: 10.3.10 - js-cookie: 3.0.5 - nopt: 7.2.0 - dev: true - - /js-cookie@3.0.5: - resolution: - { - integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==, - } - engines: { node: '>=14' } - dev: true - - /js-string-escape@1.0.1: - resolution: - { - integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==, - } - engines: { node: '>= 0.8' } - dev: true - - /js-yaml@4.1.0: - resolution: - { - integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, - } - hasBin: true - dependencies: - argparse: 2.0.1 - dev: true - - /jsbn@0.1.1: - resolution: - { - integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==, - } - dev: true - - /json-buffer@3.0.1: - resolution: - { - integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, - } - - /json-schema-traverse@0.4.1: - resolution: - { - integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, - } - dev: true - - /json-schema-traverse@1.0.0: - resolution: - { - integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, - } - dev: true - - /json-schema@0.4.0: - resolution: - { - integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==, - } - dev: true - - /json-stable-stringify-without-jsonify@1.0.1: - resolution: - { - integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, - } - dev: true - - /json-stringify-safe@5.0.1: - resolution: - { - integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==, - } - dev: true - - /json5@1.0.2: - resolution: - { - integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==, - } - hasBin: true - dependencies: - minimist: 1.2.8 - dev: true - - /json5@2.2.3: - resolution: - { - integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, - } - engines: { node: '>=6' } - hasBin: true - dev: true - - /jsonc-eslint-parser@1.4.1: - resolution: - { - integrity: sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==, - } - engines: { node: '>=8.10.0' } - dependencies: - acorn: 7.4.1 - eslint-utils: 2.1.0 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - semver: 6.3.1 - dev: true - - /jsonc-parser@3.2.1: - resolution: - { - integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==, - } - dev: true - - /jsonfile@6.1.0: - resolution: - { - integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, - } - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - /jsprim@2.0.2: - resolution: - { - integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==, - } - engines: { '0': node >=0.6.0 } - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - dev: true - - /keyv@4.5.4: - resolution: - { - integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, - } - dependencies: - json-buffer: 3.0.1 - - /kind-of@6.0.3: - resolution: - { - integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, - } - engines: { node: '>=0.10.0' } - dev: true - - /kolorist@1.8.0: - resolution: - { - integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==, - } - - /latest-version@7.0.0: - resolution: - { - integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==, - } - engines: { node: '>=14.16' } - dependencies: - package-json: 8.1.1 - dev: false - - /lazy-ass@1.6.0: - resolution: - { - integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==, - } - engines: { node: '> 0.8' } - dev: true - - /lazystream@1.0.1: - resolution: - { - integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==, - } - engines: { node: '>= 0.6.3' } - dependencies: - readable-stream: 2.3.8 - dev: true - - /levn@0.4.1: - resolution: - { - integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, - } - engines: { node: '>= 0.8.0' } - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - /lines-and-columns@1.2.4: - resolution: - { - integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, - } - dev: true - - /listr2@3.14.0(enquirer@2.4.1): - resolution: - { - integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==, - } - engines: { node: '>=10.0.0' } - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true - dependencies: - cli-truncate: 2.1.0 - colorette: 2.0.20 - enquirer: 2.4.1 - log-update: 4.0.0 - p-map: 4.0.0 - rfdc: 1.3.1 - rxjs: 7.8.1 - through: 2.3.8 - wrap-ansi: 7.0.0 - dev: true - - /local-pkg@0.4.3: - resolution: - { - integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==, - } - engines: { node: '>=14' } - dev: true - - /locate-path@6.0.0: - resolution: - { - integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, - } - engines: { node: '>=10' } - dependencies: - p-locate: 5.0.0 - dev: true - - /lodash-es@4.17.21: - resolution: - { - integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==, - } - dev: true - - /lodash.defaults@4.2.0: - resolution: - { - integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==, - } - dev: true - - /lodash.difference@4.5.0: - resolution: - { - integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==, - } - dev: true - - /lodash.flatten@4.4.0: - resolution: - { - integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==, - } - dev: true - - /lodash.isplainobject@4.0.6: - resolution: - { - integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, - } - dev: true - - /lodash.merge@4.6.2: - resolution: - { - integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, - } - dev: true - - /lodash.once@4.1.1: - resolution: - { - integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==, - } - dev: true - - /lodash.truncate@4.4.2: - resolution: - { - integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==, - } - dev: true - - /lodash.union@4.6.0: - resolution: - { - integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==, - } - dev: true - - /lodash@4.17.21: - resolution: - { - integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, - } - dev: true - - /log-symbols@4.1.0: - resolution: - { - integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==, - } - engines: { node: '>=10' } - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - dev: true - - /log-update@4.0.0: - resolution: - { - integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==, - } - engines: { node: '>=10' } - dependencies: - ansi-escapes: 4.3.2 - cli-cursor: 3.1.0 - slice-ansi: 4.0.0 - wrap-ansi: 6.2.0 - dev: true - - /loupe@2.3.7: - resolution: - { - integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==, - } - dependencies: - get-func-name: 2.0.2 - dev: true - - /lower-case@1.1.4: - resolution: - { - integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==, - } - dev: true - - /lowercase-keys@2.0.0: - resolution: - { - integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==, - } - engines: { node: '>=8' } - dev: false - - /lowercase-keys@3.0.0: - resolution: - { - integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dev: false - - /lru-cache@10.2.0: - resolution: - { - integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==, - } - engines: { node: 14 || >=16.14 } - dev: true - - /lru-cache@4.0.1: - resolution: - { - integrity: sha512-MX0ZnRoVTWXBiNe9dysqKXjvhmQgHsOirh/2rerIVJ8sbQeMxc5OPj0HDpVV3bYjdE6GTHrPf8BEHJqWHFkjHA==, - } - dependencies: - pseudomap: 1.0.2 - yallist: 2.1.2 - dev: false - - /lru-cache@6.0.0: - resolution: - { - integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, - } - engines: { node: '>=10' } - dependencies: - yallist: 4.0.0 - - /magic-string@0.30.7: - resolution: - { - integrity: sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==, - } - engines: { node: '>=12' } - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - - /md5-hex@3.0.1: - resolution: - { - integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==, - } - engines: { node: '>=8' } - dependencies: - blueimp-md5: 2.19.0 - dev: true - - /media-typer@0.3.0: - resolution: - { - integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==, - } - engines: { node: '>= 0.6' } - - /merge-descriptors@1.0.1: - resolution: - { - integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==, - } - - /merge-stream@2.0.0: - resolution: - { - integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, - } - - /merge2@1.4.1: - resolution: - { - integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, - } - engines: { node: '>= 8' } - dev: true - - /methods@1.1.2: - resolution: - { - integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==, - } - engines: { node: '>= 0.6' } - - /micromatch@4.0.5: - resolution: - { - integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==, - } - engines: { node: '>=8.6' } - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - - /mime-db@1.52.0: - resolution: - { - integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, - } - engines: { node: '>= 0.6' } - - /mime-types@2.1.35: - resolution: - { - integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, - } - engines: { node: '>= 0.6' } - dependencies: - mime-db: 1.52.0 - - /mime@1.6.0: - resolution: - { - integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==, - } - engines: { node: '>=4' } - hasBin: true - - /mimic-fn@2.1.0: - resolution: - { - integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, - } - engines: { node: '>=6' } - - /mimic-fn@4.0.0: - resolution: - { - integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==, - } - engines: { node: '>=12' } - dev: false - - /mimic-response@1.0.1: - resolution: - { - integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==, - } - engines: { node: '>=4' } - dev: false - - /mimic-response@3.1.0: - resolution: - { - integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==, - } - engines: { node: '>=10' } - dev: false - - /mimic-response@4.0.0: - resolution: - { - integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dev: false - - /minimatch@3.1.2: - resolution: - { - integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, - } - dependencies: - brace-expansion: 1.1.11 - - /minimatch@5.1.6: - resolution: - { - integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, - } - engines: { node: '>=10' } - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimatch@9.0.1: - resolution: - { - integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==, - } - engines: { node: '>=16 || 14 >=14.17' } - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimatch@9.0.3: - resolution: - { - integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==, - } - engines: { node: '>=16 || 14 >=14.17' } - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimist@1.2.8: - resolution: - { - integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, - } - - /minipass@7.0.4: - resolution: - { - integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==, - } - engines: { node: '>=16 || 14 >=14.17' } - dev: true - - /mkdirp@0.5.6: - resolution: - { - integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==, - } - hasBin: true - dependencies: - minimist: 1.2.8 - dev: false - - /mlly@1.5.0: - resolution: - { - integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==, - } - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.0.3 - ufo: 1.4.0 - dev: true - - /ms@2.0.0: - resolution: - { - integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, - } - - /ms@2.1.2: - resolution: - { - integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, - } - - /ms@2.1.3: - resolution: - { - integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, - } - - /mute-stream@0.0.8: - resolution: - { - integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==, - } - dev: true - - /mz@2.7.0: - resolution: - { - integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==, - } - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - dev: true - - /nanoid@3.3.7: - resolution: - { - integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==, - } - engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } - hasBin: true - - /natural-compare@1.4.0: - resolution: - { - integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, - } - dev: true - - /negotiator@0.6.3: - resolution: - { - integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==, - } - engines: { node: '>= 0.6' } - - /no-case@2.3.2: - resolution: - { - integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==, - } - dependencies: - lower-case: 1.1.4 - dev: true - - /node-forge@1.3.1: - resolution: - { - integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==, - } - engines: { node: '>= 6.13.0' } - dev: false - - /node-releases@2.0.14: - resolution: - { - integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==, - } - dev: true - - /nopt@7.2.0: - resolution: - { - integrity: sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==, - } - engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } - hasBin: true - dependencies: - abbrev: 2.0.0 - dev: true - - /normalize-path@3.0.0: - resolution: - { - integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, - } - engines: { node: '>=0.10.0' } - dev: true - - /normalize-range@0.1.2: - resolution: - { - integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==, - } - engines: { node: '>=0.10.0' } - dev: true - - /normalize-url@6.1.0: - resolution: - { - integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==, - } - engines: { node: '>=10' } - dev: false - - /normalize-url@8.0.0: - resolution: - { - integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==, - } - engines: { node: '>=14.16' } - dev: false - - /npm-run-path@4.0.1: - resolution: - { - integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, - } - engines: { node: '>=8' } - dependencies: - path-key: 3.1.1 - - /npm-run-path@5.2.0: - resolution: - { - integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dependencies: - path-key: 4.0.0 - dev: false - - /nth-check@2.1.1: - resolution: - { - integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==, - } - dependencies: - boolbase: 1.0.0 - dev: true - - /object-assign@4.1.1: - resolution: - { - integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==, - } - engines: { node: '>=0.10.0' } - - /object-inspect@1.13.1: - resolution: - { - integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==, - } - - /on-finished@2.4.1: - resolution: - { - integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==, - } - engines: { node: '>= 0.8' } - dependencies: - ee-first: 1.1.1 - - /on-headers@1.0.2: - resolution: - { - integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==, - } - engines: { node: '>= 0.8' } - - /once@1.4.0: - resolution: - { - integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, - } - dependencies: - wrappy: 1.0.2 - - /onetime@5.1.2: - resolution: - { - integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, - } - engines: { node: '>=6' } - dependencies: - mimic-fn: 2.1.0 - - /onetime@6.0.0: - resolution: - { - integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==, - } - engines: { node: '>=12' } - dependencies: - mimic-fn: 4.0.0 - dev: false - - /open@8.4.2: - resolution: - { - integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==, - } - engines: { node: '>=12' } - dependencies: - define-lazy-prop: 2.0.0 - is-docker: 2.2.1 - is-wsl: 2.2.0 - dev: true - - /open@9.1.0: - resolution: - { - integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==, - } - engines: { node: '>=14.16' } - dependencies: - default-browser: 4.0.0 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - is-wsl: 2.2.0 - dev: false - - /optionator@0.9.3: - resolution: - { - integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==, - } - engines: { node: '>= 0.8.0' } - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - /ora@5.4.1: - resolution: - { - integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==, - } - engines: { node: '>=10' } - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - dev: true - - /os-tmpdir@1.0.2: - resolution: - { - integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==, - } - engines: { node: '>=0.10.0' } - - /ospath@1.2.2: - resolution: - { - integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==, - } - dev: true - - /p-cancelable@2.1.1: - resolution: - { - integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==, - } - engines: { node: '>=8' } - dev: false - - /p-cancelable@3.0.0: - resolution: - { - integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==, - } - engines: { node: '>=12.20' } - dev: false - - /p-limit@3.1.0: - resolution: - { - integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, - } - engines: { node: '>=10' } - dependencies: - yocto-queue: 0.1.0 - dev: true - - /p-limit@4.0.0: - resolution: - { - integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==, - } - engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } - dependencies: - yocto-queue: 1.0.0 - dev: true - - /p-locate@5.0.0: - resolution: - { - integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, - } - engines: { node: '>=10' } - dependencies: - p-limit: 3.1.0 - dev: true - - /p-map@4.0.0: - resolution: - { - integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==, - } - engines: { node: '>=10' } - dependencies: - aggregate-error: 3.1.0 - dev: true - - /package-json@8.1.1: - resolution: - { - integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==, - } - engines: { node: '>=14.16' } - dependencies: - got: 12.6.1 - registry-auth-token: 5.0.2 - registry-url: 6.0.1 - semver: 7.6.0 - dev: false - - /param-case@2.1.1: - resolution: - { - integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==, - } - dependencies: - no-case: 2.3.2 - dev: true - - /parent-module@1.0.1: - resolution: - { - integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, - } - engines: { node: '>=6' } - dependencies: - callsites: 3.1.0 - dev: true - - /parseurl@1.3.3: - resolution: - { - integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==, - } - engines: { node: '>= 0.8' } - - /path-exists@4.0.0: - resolution: - { - integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, - } - engines: { node: '>=8' } - dev: true - - /path-is-absolute@1.0.1: - resolution: - { - integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, - } - engines: { node: '>=0.10.0' } - - /path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: '>=8' } - - /path-key@4.0.0: - resolution: - { - integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==, - } - engines: { node: '>=12' } - dev: false - - /path-parse@1.0.7: - resolution: - { - integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, - } - dev: true - - /path-scurry@1.10.1: - resolution: - { - integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==, - } - engines: { node: '>=16 || 14 >=14.17' } - dependencies: - lru-cache: 10.2.0 - minipass: 7.0.4 - dev: true - - /path-to-regexp@0.1.7: - resolution: - { - integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==, - } - - /pathe@1.1.2: - resolution: - { - integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==, - } - dev: true - - /pathval@1.1.1: - resolution: - { - integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==, - } - dev: true - - /pend@1.2.0: - resolution: - { - integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==, - } - - /performance-now@2.1.0: - resolution: - { - integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==, - } - dev: true - - /picocolors@1.0.0: - resolution: - { - integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==, - } - - /picomatch@2.3.1: - resolution: - { - integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, - } - engines: { node: '>=8.6' } - - /pify@2.3.0: - resolution: - { - integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==, - } - engines: { node: '>=0.10.0' } - dev: true - - /pinia@2.1.7(vue@3.4.19): - resolution: - { - integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==, - } - peerDependencies: - '@vue/composition-api': ^1.4.0 - typescript: '>=4.4.4' - vue: ^2.6.14 || ^3.3.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - typescript: - optional: true - dependencies: - '@vue/devtools-api': 6.6.1 - vue: 3.4.19 - vue-demi: 0.14.7(vue@3.4.19) - - /pirates@4.0.6: - resolution: - { - integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==, - } - engines: { node: '>= 6' } - dev: true - - /pkg-types@1.0.3: - resolution: - { - integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==, - } - dependencies: - jsonc-parser: 3.2.1 - mlly: 1.5.0 - pathe: 1.1.2 - dev: true - - /postcss-selector-parser@6.0.15: - resolution: - { - integrity: sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==, - } - engines: { node: '>=4' } - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - dev: true - - /postcss-value-parser@4.2.0: - resolution: - { - integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==, - } - dev: true - - /postcss@8.4.35: - resolution: - { - integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==, - } - engines: { node: ^10 || ^12 || >=14 } - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.0.2 - - /prelude-ls@1.2.1: - resolution: - { - integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, - } - engines: { node: '>= 0.8.0' } - dev: true - - /prettier@2.8.8: - resolution: - { - integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==, - } - engines: { node: '>=10.13.0' } - hasBin: true - dev: true - - /pretty-bytes@5.6.0: - resolution: - { - integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==, - } - engines: { node: '>=6' } - dev: true - - /pretty-format@27.5.1: - resolution: - { - integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==, - } - engines: { node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0 } - dependencies: - ansi-regex: 5.0.1 - ansi-styles: 5.2.0 - react-is: 17.0.2 - dev: true - - /process-nextick-args@2.0.1: - resolution: - { - integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==, - } - - /process@0.11.10: - resolution: - { - integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==, - } - engines: { node: '>= 0.6.0' } - dev: true - - /progress@2.0.3: - resolution: - { - integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==, - } - engines: { node: '>=0.4.0' } - dev: false - - /proto-list@1.2.4: - resolution: - { - integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==, - } - - /proxy-addr@2.0.7: - resolution: - { - integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==, - } - engines: { node: '>= 0.10' } - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - /proxy-from-env@1.0.0: - resolution: - { - integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==, - } - dev: true - - /proxy-from-env@1.1.0: - resolution: - { - integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==, - } - dev: false - - /pseudomap@1.0.2: - resolution: - { - integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==, - } - dev: false - - /psl@1.9.0: - resolution: - { - integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==, - } - dev: true - - /pump@3.0.0: - resolution: - { - integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==, - } - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - - /punycode@2.3.1: - resolution: - { - integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, - } - engines: { node: '>=6' } - dev: true - - /pupa@3.1.0: - resolution: - { - integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==, - } - engines: { node: '>=12.20' } - dependencies: - escape-goat: 4.0.0 - dev: false - - /qs@6.10.4: - resolution: - { - integrity: sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==, - } - engines: { node: '>=0.6' } - dependencies: - side-channel: 1.0.5 - dev: true - - /qs@6.11.0: - resolution: - { - integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==, - } - engines: { node: '>=0.6' } - dependencies: - side-channel: 1.0.5 - - /quasar@2.14.5: - resolution: - { - integrity: sha512-N+iRYoby09P9l+R5nKfA0tCPXdXJJHCPifjP8CkL/JASX5yHEjuwh7KoNiWzYLZPbsYXVuQKqwtDy0qXuXTv2g==, - } - engines: { node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1' } - - /querystringify@2.2.0: - resolution: - { - integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==, - } - dev: true - - /queue-microtask@1.2.3: - resolution: - { - integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, - } - dev: true - - /quick-lru@5.1.1: - resolution: - { - integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==, - } - engines: { node: '>=10' } - dev: false - - /randombytes@2.1.0: - resolution: - { - integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==, - } - dependencies: - safe-buffer: 5.2.1 - dev: true - - /range-parser@1.2.1: - resolution: - { - integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==, - } - engines: { node: '>= 0.6' } - - /raw-body@2.5.1: - resolution: - { - integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==, - } - engines: { node: '>= 0.8' } - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - /rc@1.2.8: - resolution: - { - integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==, - } - hasBin: true - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - dev: false - - /react-is@17.0.2: - resolution: - { - integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==, - } - dev: true - - /readable-stream@2.3.8: - resolution: - { - integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==, - } - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - /readable-stream@3.6.2: - resolution: - { - integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, - } - engines: { node: '>= 6' } - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: true - - /readdir-glob@1.1.3: - resolution: - { - integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==, - } - dependencies: - minimatch: 5.1.6 - dev: true - - /readdirp@3.6.0: - resolution: - { - integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, - } - engines: { node: '>=8.10.0' } - dependencies: - picomatch: 2.3.1 - dev: true - - /recrawl-sync@2.2.3: - resolution: - { - integrity: sha512-vSaTR9t+cpxlskkdUFrsEpnf67kSmPk66yAGT1fZPrDudxQjoMzPgQhSMImQ0pAw5k0NPirefQfhopSjhdUtpQ==, - } - dependencies: - '@cush/relative': 1.0.0 - glob-regex: 0.3.2 - slash: 3.0.0 - sucrase: 3.35.0 - tslib: 1.14.1 - dev: true - - /register-service-worker@1.7.2: - resolution: - { - integrity: sha512-CiD3ZSanZqcMPRhtfct5K9f7i3OLCcBBWsJjLh1gW9RO/nS94sVzY59iS+fgYBOBqaBpf4EzfqUF3j9IG+xo8A==, - } - dev: true - - /registry-auth-token@5.0.2: - resolution: - { - integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==, - } - engines: { node: '>=14' } - dependencies: - '@pnpm/npm-conf': 2.2.2 - dev: false - - /registry-url@6.0.1: - resolution: - { - integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==, - } - engines: { node: '>=12' } - dependencies: - rc: 1.2.8 - dev: false - - /relateurl@0.2.7: - resolution: - { - integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==, - } - engines: { node: '>= 0.10' } - dev: true - - /request-progress@3.0.0: - resolution: - { - integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==, - } - dependencies: - throttleit: 1.0.1 - dev: true - - /require-directory@2.1.1: - resolution: - { - integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, - } - engines: { node: '>=0.10.0' } - dev: true - - /require-from-string@2.0.2: - resolution: - { - integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, - } - engines: { node: '>=0.10.0' } - dev: true - - /requires-port@1.0.0: - resolution: - { - integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, - } - - /resolve-alpn@1.2.1: - resolution: - { - integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==, - } - dev: false - - /resolve-from@4.0.0: - resolution: - { - integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, - } - engines: { node: '>=4' } - dev: true - - /resolve@1.22.8: - resolution: - { - integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==, - } - hasBin: true - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /responselike@2.0.1: - resolution: - { - integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==, - } - dependencies: - lowercase-keys: 2.0.0 - dev: false - - /responselike@3.0.0: - resolution: - { - integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==, - } - engines: { node: '>=14.16' } - dependencies: - lowercase-keys: 3.0.0 - dev: false - - /restore-cursor@3.1.0: - resolution: - { - integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==, - } - engines: { node: '>=8' } - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - - /reusify@1.0.4: - resolution: - { - integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==, - } - engines: { iojs: '>=1.0.0', node: '>=0.10.0' } - dev: true - - /rfdc@1.3.1: - resolution: - { - integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==, - } - dev: true - - /rimraf@2.7.1: - resolution: - { - integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==, - } - hasBin: true - dependencies: - glob: 7.2.3 - dev: false - - /rimraf@3.0.2: - resolution: - { - integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, - } - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - /rollup-plugin-visualizer@5.12.0: - resolution: - { - integrity: sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==, - } - engines: { node: '>=14' } - hasBin: true - peerDependencies: - rollup: 2.x || 3.x || 4.x - peerDependenciesMeta: - rollup: - optional: true - dependencies: - open: 8.4.2 - picomatch: 2.3.1 - source-map: 0.7.4 - yargs: 17.7.2 - dev: true - - /rollup@2.77.3: - resolution: - { - integrity: sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==, - } - engines: { node: '>=10.0.0' } - hasBin: true - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /rollup@3.29.4: - resolution: - { - integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==, - } - engines: { node: '>=14.18.0', npm: '>=8.0.0' } - hasBin: true - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /rollup@4.12.0: - resolution: - { - integrity: sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==, - } - engines: { node: '>=18.0.0', npm: '>=8.0.0' } - hasBin: true - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.12.0 - '@rollup/rollup-android-arm64': 4.12.0 - '@rollup/rollup-darwin-arm64': 4.12.0 - '@rollup/rollup-darwin-x64': 4.12.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.12.0 - '@rollup/rollup-linux-arm64-gnu': 4.12.0 - '@rollup/rollup-linux-arm64-musl': 4.12.0 - '@rollup/rollup-linux-riscv64-gnu': 4.12.0 - '@rollup/rollup-linux-x64-gnu': 4.12.0 - '@rollup/rollup-linux-x64-musl': 4.12.0 - '@rollup/rollup-win32-arm64-msvc': 4.12.0 - '@rollup/rollup-win32-ia32-msvc': 4.12.0 - '@rollup/rollup-win32-x64-msvc': 4.12.0 - fsevents: 2.3.3 - dev: true - - /route-cache@0.5.0: - resolution: - { - integrity: sha512-7FzV+1O4q7XeerbyG8aEeDH+1bk/Vxp2sDJdEZE0KcbTP0C6IucKSQUCTwB3F0IkhpF4rYluLLENEfUQ6LH/ng==, - } - dependencies: - debug: 3.1.0 - lru-cache: 4.0.1 - transitivePeerDependencies: - - supports-color - dev: false - - /run-applescript@5.0.0: - resolution: - { - integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==, - } - engines: { node: '>=12' } - dependencies: - execa: 5.1.1 - dev: false - - /run-async@2.4.1: - resolution: - { - integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==, - } - engines: { node: '>=0.12.0' } - dev: true - - /run-parallel@1.2.0: - resolution: - { - integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, - } - dependencies: - queue-microtask: 1.2.3 - dev: true - - /rxjs@7.8.1: - resolution: - { - integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==, - } - dependencies: - tslib: 2.6.2 - dev: true - - /safe-buffer@5.1.2: - resolution: - { - integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, - } - - /safe-buffer@5.2.1: - resolution: - { - integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, - } - - /safer-buffer@2.1.2: - resolution: - { - integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, - } - - /sass@1.71.1: - resolution: - { - integrity: sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==, - } - engines: { node: '>=14.0.0' } - hasBin: true - dependencies: - chokidar: 3.6.0 - immutable: 4.3.5 - source-map-js: 1.0.2 - dev: true - - /sax@1.1.4: - resolution: - { - integrity: sha512-5f3k2PbGGp+YtKJjOItpg3P99IMD84E4HOvcfleTb5joCHNXYLsR9yWFPOYGgaeMPDubQILTCMdsFb2OMeOjtg==, - } - dev: true - - /selfsigned@2.4.1: - resolution: - { - integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==, - } - engines: { node: '>=10' } - dependencies: - '@types/node-forge': 1.3.11 - node-forge: 1.3.1 - dev: false - - /semver-diff@4.0.0: - resolution: - { - integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==, - } - engines: { node: '>=12' } - dependencies: - semver: 7.6.0 - dev: false - - /semver@6.3.1: - resolution: - { - integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, - } - hasBin: true - dev: true - - /semver@7.6.0: - resolution: - { - integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==, - } - engines: { node: '>=10' } - hasBin: true - dependencies: - lru-cache: 6.0.0 - - /send@0.18.0: - resolution: - { - integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==, - } - engines: { node: '>= 0.8.0' } - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - /serialize-javascript@6.0.2: - resolution: - { - integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==, - } - dependencies: - randombytes: 2.1.0 - dev: true - - /serve-static@1.15.0: - resolution: - { - integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==, - } - engines: { node: '>= 0.8.0' } - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - - /set-function-length@1.2.1: - resolution: - { - integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==, - } - engines: { node: '>= 0.4' } - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 - - /setprototypeof@1.2.0: - resolution: - { - integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==, - } - - /shallow-clone@3.0.1: - resolution: - { - integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==, - } - engines: { node: '>=8' } - dependencies: - kind-of: 6.0.3 - dev: true - - /shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: '>=8' } - dependencies: - shebang-regex: 3.0.0 - - /shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: '>=8' } - - /side-channel@1.0.5: - resolution: - { - integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==, - } - engines: { node: '>= 0.4' } - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.1 - - /siginfo@2.0.0: - resolution: - { - integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==, - } - dev: true - - /signal-exit@3.0.7: - resolution: - { - integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, - } - - /signal-exit@4.1.0: - resolution: - { - integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, - } - engines: { node: '>=14' } - dev: true - - /slash@3.0.0: - resolution: - { - integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, - } - engines: { node: '>=8' } - dev: true - - /slice-ansi@3.0.0: - resolution: - { - integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==, - } - engines: { node: '>=8' } - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true - - /slice-ansi@4.0.0: - resolution: - { - integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==, - } - engines: { node: '>=10' } - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true - - /source-map-js@1.0.2: - resolution: - { - integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, - } - engines: { node: '>=0.10.0' } - - /source-map@0.6.1: - resolution: - { - integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, - } - engines: { node: '>=0.10.0' } - dev: true - - /source-map@0.7.4: - resolution: - { - integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==, - } - engines: { node: '>= 8' } - dev: true - - /sshpk@1.18.0: - resolution: - { - integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==, - } - engines: { node: '>=0.10.0' } - hasBin: true - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: true - - /stack-trace@1.0.0-pre2: - resolution: - { - integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==, - } - engines: { node: '>=16' } - dev: true - - /stackback@0.0.2: - resolution: - { - integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==, - } - dev: true - - /statuses@2.0.1: - resolution: - { - integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==, - } - engines: { node: '>= 0.8' } - - /std-env@3.7.0: - resolution: - { - integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==, - } - dev: true - - /string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: '>=8' } - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - /string-width@5.1.2: - resolution: - { - integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, - } - engines: { node: '>=12' } - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - /string_decoder@1.1.1: - resolution: - { - integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==, - } - dependencies: - safe-buffer: 5.1.2 - - /string_decoder@1.3.0: - resolution: - { - integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, - } - dependencies: - safe-buffer: 5.2.1 - dev: true - - /strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: '>=8' } - dependencies: - ansi-regex: 5.0.1 - - /strip-ansi@7.1.0: - resolution: - { - integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==, - } - engines: { node: '>=12' } - dependencies: - ansi-regex: 6.0.1 - - /strip-bom@3.0.0: - resolution: - { - integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, - } - engines: { node: '>=4' } - dev: true - - /strip-final-newline@2.0.0: - resolution: - { - integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, - } - engines: { node: '>=6' } - - /strip-final-newline@3.0.0: - resolution: - { - integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==, - } - engines: { node: '>=12' } - dev: false - - /strip-json-comments@2.0.1: - resolution: - { - integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==, - } - engines: { node: '>=0.10.0' } - dev: false - - /strip-json-comments@3.1.1: - resolution: - { - integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, - } - engines: { node: '>=8' } - dev: true - - /strip-literal@1.3.0: - resolution: - { - integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==, - } - dependencies: - acorn: 8.11.3 - dev: true - - /sucrase@3.35.0: - resolution: - { - integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==, - } - engines: { node: '>=16 || 14 >=14.17' } - hasBin: true - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - commander: 4.1.1 - glob: 10.3.10 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.6 - ts-interface-checker: 0.1.13 - dev: true - - /supports-color@7.2.0: - resolution: - { - integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, - } - engines: { node: '>=8' } - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-color@8.1.1: - resolution: - { - integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, - } - engines: { node: '>=10' } - dependencies: - has-flag: 4.0.0 - - /supports-preserve-symlinks-flag@1.0.0: - resolution: - { - integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, - } - engines: { node: '>= 0.4' } - dev: true - - /table@6.8.1: - resolution: - { - integrity: sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==, - } - engines: { node: '>=10.0.0' } - dependencies: - ajv: 8.12.0 - lodash.truncate: 4.4.2 - slice-ansi: 4.0.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /tar-stream@2.2.0: - resolution: - { - integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==, - } - engines: { node: '>=6' } - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - dev: true - - /text-table@0.2.0: - resolution: - { - integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, - } - dev: true - - /thenify-all@1.6.0: - resolution: - { - integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==, - } - engines: { node: '>=0.8' } - dependencies: - thenify: 3.3.1 - dev: true - - /thenify@3.3.1: - resolution: - { - integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==, - } - dependencies: - any-promise: 1.3.0 - dev: true - - /throttleit@1.0.1: - resolution: - { - integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==, - } - dev: true - - /through@2.3.8: - resolution: - { - integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, - } - dev: true - - /time-zone@1.0.0: - resolution: - { - integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==, - } - engines: { node: '>=4' } - dev: true - - /tinybench@2.6.0: - resolution: - { - integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==, - } - dev: true - - /tinypool@0.5.0: - resolution: - { - integrity: sha512-paHQtnrlS1QZYKF/GnLoOM/DN9fqaGOFbCbxzAhwniySnzl9Ebk8w73/dd34DAhe/obUbPAOldTyYXQZxnPBPQ==, - } - engines: { node: '>=14.0.0' } - dev: true - - /tinyspy@2.2.1: - resolution: - { - integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==, - } - engines: { node: '>=14.0.0' } - dev: true - - /titleize@3.0.0: - resolution: - { - integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==, - } - engines: { node: '>=12' } - dev: false - - /tmp@0.0.33: - resolution: - { - integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==, - } - engines: { node: '>=0.6.0' } - dependencies: - os-tmpdir: 1.0.2 - - /tmp@0.2.1: - resolution: - { - integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==, - } - engines: { node: '>=8.17.0' } - dependencies: - rimraf: 3.0.2 - dev: true - - /to-fast-properties@2.0.0: - resolution: - { - integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, - } - engines: { node: '>=4' } - - /to-regex-range@5.0.1: - resolution: - { - integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, - } - engines: { node: '>=8.0' } - dependencies: - is-number: 7.0.0 - - /toidentifier@1.0.1: - resolution: - { - integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==, - } - engines: { node: '>=0.6' } - - /tough-cookie@4.1.3: - resolution: - { - integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==, - } - engines: { node: '>=6' } - dependencies: - psl: 1.9.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - dev: true - - /ts-interface-checker@0.1.13: - resolution: - { - integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==, - } - dev: true - - /tsconfck@3.0.2: - resolution: - { - integrity: sha512-6lWtFjwuhS3XI4HsX4Zg0izOI3FU/AI9EGVlPEUMDIhvLPMD4wkiof0WCoDgW7qY+Dy198g4d9miAqUHWHFH6Q==, - } - engines: { node: ^18 || >=20 } - hasBin: true - peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true - dev: true - - /tsconfig-paths@3.15.0: - resolution: - { - integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==, - } - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: true - - /tslib@1.14.1: - resolution: - { - integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==, - } - dev: true - - /tslib@2.6.2: - resolution: - { - integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==, - } - dev: true - - /tunnel-agent@0.6.0: - resolution: - { - integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==, - } - dependencies: - safe-buffer: 5.2.1 - dev: true - - /tunnel@0.0.6: - resolution: - { - integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==, - } - engines: { node: '>=0.6.11 <=0.7.0 || >=0.7.3' } - dev: false - - /tweetnacl@0.14.5: - resolution: - { - integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==, - } - dev: true - - /type-check@0.4.0: - resolution: - { - integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, - } - engines: { node: '>= 0.8.0' } - dependencies: - prelude-ls: 1.2.1 - dev: true - - /type-detect@4.0.8: - resolution: - { - integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, - } - engines: { node: '>=4' } - dev: true - - /type-fest@0.20.2: - resolution: - { - integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==, - } - engines: { node: '>=10' } - dev: true - - /type-fest@0.21.3: - resolution: - { - integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, - } - engines: { node: '>=10' } - dev: true - - /type-fest@1.4.0: - resolution: - { - integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==, - } - engines: { node: '>=10' } - dev: false - - /type-fest@2.19.0: - resolution: - { - integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==, - } - engines: { node: '>=12.20' } - dev: false - - /type-is@1.6.18: - resolution: - { - integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==, - } - engines: { node: '>= 0.6' } - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - /typedarray-to-buffer@3.1.5: - resolution: - { - integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==, - } - dependencies: - is-typedarray: 1.0.0 - dev: false - - /typedarray@0.0.6: - resolution: - { - integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==, - } - dev: false - - /ufo@1.4.0: - resolution: - { - integrity: sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==, - } - dev: true - - /uglify-js@3.17.4: - resolution: - { - integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==, - } - engines: { node: '>=0.8.0' } - hasBin: true - dev: true - - /undici-types@5.26.5: - resolution: - { - integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, - } - - /unique-string@3.0.0: - resolution: - { - integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==, - } - engines: { node: '>=12' } - dependencies: - crypto-random-string: 4.0.0 - dev: false - - /universalify@0.2.0: - resolution: - { - integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==, - } - engines: { node: '>= 4.0.0' } - dev: true - - /universalify@2.0.1: - resolution: - { - integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, - } - engines: { node: '>= 10.0.0' } - - /unpipe@1.0.0: - resolution: - { - integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==, - } - engines: { node: '>= 0.8' } - - /unplugin@1.7.1: - resolution: - { - integrity: sha512-JqzORDAPxxs8ErLV4x+LL7bk5pk3YlcWqpSNsIkAZj972KzFZLClc/ekppahKkOczGkwIG6ElFgdOgOlK4tXZw==, - } - dependencies: - acorn: 8.11.3 - chokidar: 3.6.0 - webpack-sources: 3.2.3 - webpack-virtual-modules: 0.6.1 - dev: true - - /untildify@4.0.0: - resolution: - { - integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==, - } - engines: { node: '>=8' } - - /update-browserslist-db@1.0.13(browserslist@4.23.0): - resolution: - { - integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==, - } - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.0.0 - dev: true - - /update-notifier@6.0.2: - resolution: - { - integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==, - } - engines: { node: '>=14.16' } - dependencies: - boxen: 7.1.1 - chalk: 5.3.0 - configstore: 6.0.0 - has-yarn: 3.0.0 - import-lazy: 4.0.0 - is-ci: 3.0.1 - is-installed-globally: 0.4.0 - is-npm: 6.0.0 - is-yarn-global: 0.4.1 - latest-version: 7.0.0 - pupa: 3.1.0 - semver: 7.6.0 - semver-diff: 4.0.0 - xdg-basedir: 5.1.0 - dev: false - - /upper-case@1.1.3: - resolution: - { - integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==, - } - dev: true - - /uri-js@4.4.1: - resolution: - { - integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, - } - dependencies: - punycode: 2.3.1 - dev: true - - /url-parse@1.5.10: - resolution: - { - integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==, - } - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - dev: true - - /util-deprecate@1.0.2: - resolution: - { - integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, - } - - /utils-merge@1.0.1: - resolution: - { - integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==, - } - engines: { node: '>= 0.4.0' } - - /uuid@8.3.2: - resolution: - { - integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==, - } - hasBin: true - dev: true - - /validator@13.11.0: - resolution: - { - integrity: sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==, - } - engines: { node: '>= 0.10' } - dev: false - - /vary@1.1.2: - resolution: - { - integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==, - } - engines: { node: '>= 0.8' } - - /verror@1.10.0: - resolution: - { - integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==, - } - engines: { '0': node >=0.6.0 } - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: true - - /vite-jsconfig-paths@2.0.1(vite@5.1.4): - resolution: - { - integrity: sha512-rabcTTfKs0MdAsQWcZjbIMo5fcp6jthZce7uFEPgVPgpSY+RNOwjzIJOPES6cB/GJZLSoLGfHM9kt5HNmJvp7A==, - } - peerDependencies: - vite: '>2.0.0-0' - dependencies: - debug: 4.3.4(supports-color@8.1.1) - globrex: 0.1.2 - recrawl-sync: 2.2.3 - tsconfig-paths: 3.15.0 - vite: 5.1.4 - transitivePeerDependencies: - - supports-color - dev: true - - /vite-node@0.31.4(@types/node@20.11.19): - resolution: - { - integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==, - } - engines: { node: '>=v14.18.0' } - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4(supports-color@8.1.1) - mlly: 1.5.0 - pathe: 1.1.2 - picocolors: 1.0.0 - vite: 4.5.2(@types/node@20.11.19) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vite-tsconfig-paths@4.3.1(vite@5.1.4): - resolution: - { - integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==, - } - peerDependencies: - vite: '*' - peerDependenciesMeta: - vite: - optional: true - dependencies: - debug: 4.3.4(supports-color@8.1.1) - globrex: 0.1.2 - tsconfck: 3.0.2 - vite: 5.1.4 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /vite@2.9.17(sass@1.71.1): - resolution: - { - integrity: sha512-XxcRzra6d7xrKXH66jZUgb+srThoPu+TLJc06GifUyKq9JmjHkc1Numc8ra0h56rju2jfVWw3B3fs5l3OFMvUw==, - } - engines: { node: '>=12.2.0' } - hasBin: true - peerDependencies: - less: '*' - sass: '*' - stylus: '*' - peerDependenciesMeta: - less: - optional: true - sass: - optional: true - stylus: - optional: true - dependencies: - esbuild: 0.14.51 - postcss: 8.4.35 - resolve: 1.22.8 - rollup: 2.77.3 - sass: 1.71.1 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vite@4.5.2(@types/node@20.11.19): - resolution: - { - integrity: sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==, - } - engines: { node: ^14.18.0 || >=16.0.0 } - hasBin: true - peerDependencies: - '@types/node': '>= 14' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - '@types/node': 20.11.19 - esbuild: 0.18.20 - postcss: 8.4.35 - rollup: 3.29.4 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vite@5.1.4: - resolution: - { - integrity: sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==, - } - engines: { node: ^18.0.0 || >=20.0.0 } - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - dependencies: - esbuild: 0.19.12 - postcss: 8.4.35 - rollup: 4.12.0 - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /vitest@0.31.4: - resolution: - { - integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==, - } - engines: { node: '>=v14.18.0' } - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' - happy-dom: '*' - jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true - dependencies: - '@types/chai': 4.3.12 - '@types/chai-subset': 1.3.5 - '@types/node': 20.11.19 - '@vitest/expect': 0.31.4 - '@vitest/runner': 0.31.4 - '@vitest/snapshot': 0.31.4 - '@vitest/spy': 0.31.4 - '@vitest/utils': 0.31.4 - acorn: 8.11.3 - acorn-walk: 8.3.2 - cac: 6.7.14 - chai: 4.4.1 - concordance: 5.0.4 - debug: 4.3.4(supports-color@8.1.1) - local-pkg: 0.4.3 - magic-string: 0.30.7 - pathe: 1.1.2 - picocolors: 1.0.0 - std-env: 3.7.0 - strip-literal: 1.3.0 - tinybench: 2.6.0 - tinypool: 0.5.0 - vite: 4.5.2(@types/node@20.11.19) - vite-node: 0.31.4(@types/node@20.11.19) - why-is-node-running: 2.2.2 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: true - - /vue-component-type-helpers@1.8.27: - resolution: - { - integrity: sha512-0vOfAtI67UjeO1G6UiX5Kd76CqaQ67wrRZiOe7UAb9Jm6GzlUr/fC7CV90XfwapJRjpCMaZFhv1V0ajWRmE9Dg==, - } - dev: true - - /vue-demi@0.14.7(vue@3.4.19): - resolution: - { - integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==, - } - engines: { node: '>=12' } - hasBin: true - requiresBuild: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - dependencies: - vue: 3.4.19 - - /vue-eslint-parser@9.4.2(eslint@8.56.0): - resolution: - { - integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==, - } - engines: { node: ^14.17.0 || >=16.0.0 } - peerDependencies: - eslint: '>=6.0.0' - dependencies: - debug: 4.3.4(supports-color@8.1.1) - eslint: 8.56.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.5.0 - lodash: 4.17.21 - semver: 7.6.0 - transitivePeerDependencies: - - supports-color - dev: true - - /vue-i18n@9.9.1(vue@3.4.19): - resolution: - { - integrity: sha512-xyQ4VspLdNSPTKBFBPWa1tvtj+9HuockZwgFeD2OhxxXuC2CWeNvV4seu2o9+vbQOyQbhAM5Ez56oxUrrnTWdw==, - } - engines: { node: '>= 16' } - peerDependencies: - vue: ^3.0.0 - dependencies: - '@intlify/core-base': 9.9.1 - '@intlify/shared': 9.9.1 - '@vue/devtools-api': 6.6.1 - vue: 3.4.19 - - /vue-router@4.2.5(vue@3.4.19): - resolution: - { - integrity: sha512-DIUpKcyg4+PTQKfFPX88UWhlagBEBEfJ5A8XDXRJLUnZOvcpMF8o/dnL90vpVkGaPbjvXazV/rC1qBKrZlFugw==, - } - peerDependencies: - vue: ^3.2.0 - dependencies: - '@vue/devtools-api': 6.6.1 - vue: 3.4.19 - - /vue@3.4.19: - resolution: - { - integrity: sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==, - } - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@vue/compiler-dom': 3.4.19 - '@vue/compiler-sfc': 3.4.19 - '@vue/runtime-dom': 3.4.19 - '@vue/server-renderer': 3.4.19(vue@3.4.19) - '@vue/shared': 3.4.19 - - /wcwidth@1.0.1: - resolution: - { - integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, - } - dependencies: - defaults: 1.0.4 - dev: true - - /webidl-conversions@7.0.0: - resolution: - { - integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==, - } - engines: { node: '>=12' } - dev: true - - /webpack-merge@5.10.0: - resolution: - { - integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==, - } - engines: { node: '>=10.0.0' } - dependencies: - clone-deep: 4.0.1 - flat: 5.0.2 - wildcard: 2.0.1 - dev: true - - /webpack-sources@3.2.3: - resolution: - { - integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==, - } - engines: { node: '>=10.13.0' } - dev: true - - /webpack-virtual-modules@0.6.1: - resolution: - { - integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==, - } - dev: true - - /well-known-symbols@2.0.0: - resolution: - { - integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==, - } - engines: { node: '>=6' } - dev: true - - /whatwg-encoding@2.0.0: - resolution: - { - integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==, - } - engines: { node: '>=12' } - dependencies: - iconv-lite: 0.6.3 - dev: true - - /whatwg-mimetype@3.0.0: - resolution: - { - integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==, - } - engines: { node: '>=12' } - dev: true - - /which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: '>= 8' } - hasBin: true - dependencies: - isexe: 2.0.0 - - /why-is-node-running@2.2.2: - resolution: - { - integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==, - } - engines: { node: '>=8' } - hasBin: true - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - dev: true - - /widest-line@4.0.1: - resolution: - { - integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==, - } - engines: { node: '>=12' } - dependencies: - string-width: 5.1.2 - dev: false - - /wildcard@2.0.1: - resolution: - { - integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==, - } - dev: true - - /wrap-ansi@6.2.0: - resolution: - { - integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==, - } - engines: { node: '>=8' } - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: '>=10' } - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrap-ansi@8.1.0: - resolution: - { - integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, - } - engines: { node: '>=12' } - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - /wrappy@1.0.2: - resolution: - { - integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, - } - - /write-file-atomic@3.0.3: - resolution: - { - integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==, - } - dependencies: - imurmurhash: 0.1.4 - is-typedarray: 1.0.0 - signal-exit: 3.0.7 - typedarray-to-buffer: 3.1.5 - dev: false - - /xdg-basedir@5.1.0: - resolution: - { - integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==, - } - engines: { node: '>=12' } - dev: false - - /xml-name-validator@4.0.0: - resolution: - { - integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==, - } - engines: { node: '>=12' } - dev: true - - /y18n@5.0.8: - resolution: - { - integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, - } - engines: { node: '>=10' } - dev: true - - /yallist@2.1.2: - resolution: - { - integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==, - } - dev: false - - /yallist@4.0.0: - resolution: - { - integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, - } - - /yaml-eslint-parser@0.3.2: - resolution: - { - integrity: sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==, - } - dependencies: - eslint-visitor-keys: 1.3.0 - lodash: 4.17.21 - yaml: 1.10.2 - dev: true - - /yaml@1.10.2: - resolution: - { - integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, - } - engines: { node: '>= 6' } - dev: true - - /yargs-parser@21.1.1: - resolution: - { - integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, - } - engines: { node: '>=12' } - dev: true - - /yargs@17.7.2: - resolution: - { - integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, - } - engines: { node: '>=12' } - dependencies: - cliui: 8.0.1 - escalade: 3.1.2 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - dev: true - - /yauzl@2.10.0: - resolution: - { - integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==, - } - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - - /yocto-queue@0.1.0: - resolution: - { - integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, - } - engines: { node: '>=10' } - dev: true - - /yocto-queue@1.0.0: - resolution: - { - integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==, - } - engines: { node: '>=12.20' } - dev: true - - /zip-stream@4.1.1: - resolution: - { - integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==, - } - engines: { node: '>= 10' } - dependencies: - archiver-utils: 3.0.4 - compress-commons: 4.1.2 - readable-stream: 3.6.2 - dev: true + dependencies: + '@vue/compiler-dom': 3.4.19 + '@vue/compiler-sfc': 3.4.19 + '@vue/runtime-dom': 3.4.19 + '@vue/server-renderer': 3.4.19(vue@3.4.19) + '@vue/shared': 3.4.19 + typescript: 5.5.4 + + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: true + + /webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + dev: true + + /webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack-virtual-modules@0.6.1: + resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} + dev: true + + /well-known-symbols@2.0.0: + resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} + engines: {node: '>=6'} + dev: true + + /whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + dependencies: + iconv-lite: 0.6.3 + dev: true + + /whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + + /widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + dev: false + + /wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + /write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: false + + /xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + dev: false + + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + dev: false + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + /yaml-eslint-parser@0.3.2: + resolution: {integrity: sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==} + dependencies: + eslint-visitor-keys: 1.3.0 + lodash: 4.17.21 + yaml: 1.10.2 + dev: true + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + + /zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + dependencies: + archiver-utils: 3.0.4 + compress-commons: 4.1.2 + readable-stream: 3.6.2 + dev: true diff --git a/src/boot/axios.js b/src/boot/axios.js index fa8a08003..9b32275bd 100644 --- a/src/boot/axios.js +++ b/src/boot/axios.js @@ -43,6 +43,15 @@ const onResponseError = (error) => { } switch (response?.status) { + case 422: + if (error.name == 'ValidationError') + message += + ' "' + + responseError.details.context + + '.' + + Object.keys(responseError.details.codes).join(',') + + '"'; + break; case 500: message = 'errors.statusInternalServerError'; break; diff --git a/src/boot/qformMixin.js b/src/boot/qformMixin.js index 0bf1f9795..fc7852369 100644 --- a/src/boot/qformMixin.js +++ b/src/boot/qformMixin.js @@ -1,28 +1,11 @@ import { getCurrentInstance } from 'vue'; -const filterAvailableInput = (element) => { - return element.classList.contains('q-field__native') && !element.disabled; -}; -const filterAvailableText = (element) => { - return ( - element.__vueParentComponent.type.name === 'QInput' && - element.__vueParentComponent?.attrs?.class !== 'vn-input-date' - ); -}; - export default { mounted: function () { const vm = getCurrentInstance(); if (vm.type.name === 'QForm') { if (!['searchbarForm', 'filterPanelForm'].includes(this.$el?.id)) { - // AUTOFOCUS - const elementsArray = Array.from(this.$el.elements); - const availableInputs = elementsArray.filter(filterAvailableInput); - const firstInputElement = availableInputs.find(filterAvailableText); - - if (firstInputElement) { - firstInputElement.focus(); - } + // TODO: AUTOFOCUS IS NOT FOCUSING const that = this; this.$el.addEventListener('keyup', function (evt) { if (evt.key === 'Enter') { diff --git a/src/components/CreateBankEntityForm.vue b/src/components/CreateBankEntityForm.vue index d5a5f38b1..c0a421206 100644 --- a/src/components/CreateBankEntityForm.vue +++ b/src/components/CreateBankEntityForm.vue @@ -52,7 +52,7 @@ onMounted(async () => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('name')" v-model="data.name" @@ -65,7 +65,7 @@ onMounted(async () => { :rules="validate('bankEntity.bic')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('country')" diff --git a/src/components/CreateManualInvoiceForm.vue b/src/components/CreateManualInvoiceForm.vue index 1aa95011f..da006e024 100644 --- a/src/components/CreateManualInvoiceForm.vue +++ b/src/components/CreateManualInvoiceForm.vue @@ -59,7 +59,7 @@ const onDataSaved = async (formData, requestResponse) => { <QIcon name="warning" class="fill-icon q-mr-sm" size="md" /> {{ t('Invoicing in progress...') }} </span> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Ticket')" :options="ticketsOptions" @@ -99,7 +99,7 @@ const onDataSaved = async (formData, requestResponse) => { /> <VnInputDate :label="t('Max date')" v-model="data.maxShipped" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Serial')" :options="invoiceOutSerialsOptions" @@ -117,7 +117,7 @@ const onDataSaved = async (formData, requestResponse) => { v-model="data.taxArea" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Reference')" type="textarea" diff --git a/src/components/CreateNewCityForm.vue b/src/components/CreateNewCityForm.vue index 45fa61dff..9a7d8666c 100644 --- a/src/components/CreateNewCityForm.vue +++ b/src/components/CreateNewCityForm.vue @@ -4,8 +4,8 @@ import { useI18n } from 'vue-i18n'; import FetchData from 'components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import VnInput from 'src/components/common/VnInput.vue'; +import VnSelectProvince from 'components/VnSelectProvince.vue'; +import VnInput from 'components/common/VnInput.vue'; import FormModelPopup from './FormModelPopup.vue'; const emit = defineEmits(['onDataSaved']); @@ -19,8 +19,8 @@ const cityFormData = reactive({ const provincesOptions = ref([]); -const onDataSaved = (dataSaved) => { - emit('onDataSaved', dataSaved); +const onDataSaved = (...args) => { + emit('onDataSaved', ...args); }; </script> @@ -36,24 +36,16 @@ const onDataSaved = (dataSaved) => { :form-initial-data="cityFormData" url-create="towns" model="city" - @on-data-saved="onDataSaved($event)" + @on-data-saved="onDataSaved" > <template #form-inputs="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Name')" v-model="data.name" :rules="validate('city.name')" /> - <VnSelect - :label="t('Province')" - :options="provincesOptions" - hide-selected - option-label="name" - option-value="id" - v-model="data.provinceFk" - :rules="validate('city.provinceFk')" - /> + <VnSelectProvince v-model="data.provinceFk" /> </VnRow> </template> </FormModelPopup> diff --git a/src/components/CreateNewPostcodeForm.vue b/src/components/CreateNewPostcodeForm.vue index 25a61a0ca..a426ac2b4 100644 --- a/src/components/CreateNewPostcodeForm.vue +++ b/src/components/CreateNewPostcodeForm.vue @@ -5,9 +5,9 @@ import { useI18n } from 'vue-i18n'; import FetchData from 'components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; +import VnSelectProvince from 'src/components/VnSelectProvince.vue'; import VnInput from 'src/components/common/VnInput.vue'; import CreateNewCityForm from './CreateNewCityForm.vue'; -import CreateNewProvinceForm from './CreateNewProvinceForm.vue'; import VnSelectDialog from 'components/common/VnSelectDialog.vue'; import FormModelPopup from './FormModelPopup.vue'; @@ -22,20 +22,17 @@ const postcodeFormData = reactive({ townFk: null, }); -const townsFetchDataRef = ref(null); const provincesFetchDataRef = ref(null); const countriesOptions = ref([]); const provincesOptions = ref([]); -const townsLocationOptions = ref([]); +const town = ref({}); -const onDataSaved = (formData) => { +function onDataSaved(formData) { const newPostcode = { ...formData, }; - const townObject = townsLocationOptions.value.find( - ({ id }) => id === formData.townFk - ); - newPostcode.town = townObject?.name; + newPostcode.town = town.value.name; + newPostcode.townFk = town.value.id; const provinceObject = provincesOptions.value.find( ({ id }) => id === formData.provinceFk ); @@ -43,39 +40,41 @@ const onDataSaved = (formData) => { const countryObject = countriesOptions.value.find( ({ id }) => id === formData.countryFk ); - newPostcode.country = countryObject?.country; + newPostcode.country = countryObject?.name; emit('onDataSaved', newPostcode); -}; +} -const onCityCreated = async ({ name, provinceFk }, formData) => { - await townsFetchDataRef.value.fetch(); - formData.townFk = townsLocationOptions.value.find((town) => town.name === name).id; - formData.provinceFk = provinceFk; - formData.countryFk = provincesOptions.value.find( - (province) => province.id === provinceFk - ).countryFk; -}; - -const onProvinceCreated = async ({ name }, formData) => { +async function onCityCreated(newTown, formData) { await provincesFetchDataRef.value.fetch(); - formData.provinceFk = provincesOptions.value.find( - (province) => province.name === name - ).id; -}; + newTown.province = provincesOptions.value.find( + (province) => province.id === newTown.provinceFk + ); + formData.townFk = newTown; + setTown(newTown, formData); +} + +function setTown(newTown, data) { + if (!newTown) return; + town.value = newTown; + data.provinceFk = newTown.provinceFk; + data.countryFk = newTown.province.countryFk; +} + +async function setProvince(id, data) { + await provincesFetchDataRef.value.fetch(); + const newProvince = provincesOptions.value.find((province) => province.id == id); + if (!newProvince) return; + + data.countryFk = newProvince.countryFk; +} </script> <template> - <FetchData - ref="townsFetchDataRef" - @on-fetch="(data) => (townsLocationOptions = data)" - auto-load - url="Towns/location" - /> <FetchData ref="provincesFetchDataRef" @on-fetch="(data) => (provincesOptions = data)" auto-load - url="Provinces" + url="Provinces/location" /> <FetchData @on-fetch="(data) => (countriesOptions = data)" @@ -88,10 +87,11 @@ const onProvinceCreated = async ({ name }, formData) => { :title="t('New postcode')" :subtitle="t('Please, ensure you put the correct data!')" :form-initial-data="postcodeFormData" + :mapper="(data) => (data.townFk = data.townFk.id) && data" @on-data-saved="onDataSaved" > <template #form-inputs="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Postcode')" v-model="data.code" @@ -99,38 +99,43 @@ const onProvinceCreated = async ({ name }, formData) => { /> <VnSelectDialog :label="t('City')" - :options="townsLocationOptions" + url="Towns/location" + @update:model-value="(value) => setTown(value, data)" v-model="data.townFk" - hide-selected option-label="name" option-value="id" :rules="validate('postcode.city')" :roles-allowed-to-create="['deliveryAssistant']" + :emit-value="false" + clearable > + <template #option="{ itemProps, opt }"> + <QItem v-bind="itemProps"> + <QItemSection> + <QItemLabel>{{ opt.name }}</QItemLabel> + <QItemLabel caption> + {{ opt.province.name }}, + {{ opt.province.country.name }} + </QItemLabel> + </QItemSection> + </QItem> + </template> <template #form> - <CreateNewCityForm @on-data-saved="onCityCreated($event, data)" /> + <CreateNewCityForm + @on-data-saved=" + (_, requestResponse) => + onCityCreated(requestResponse, data) + " + /> </template> </VnSelectDialog> </VnRow> - <VnRow class="row q-gutter-md q-mb-xl"> - <VnSelectDialog - :label="t('Province')" - :options="provincesOptions" - hide-selected - option-label="name" - option-value="id" + <VnRow> + <VnSelectProvince + @update:model-value="(value) => setProvince(value, data)" v-model="data.provinceFk" - :rules="validate('postcode.provinceFk')" - :roles-allowed-to-create="['deliveryAssistant']" - > - <template #form> - <CreateNewProvinceForm - @on-data-saved="onProvinceCreated($event, data)" - /> - </template> </VnSelectDialog - ></VnRow> - <VnRow class="row q-gutter-md q-mb-xl" - ><VnSelect + /> + <VnSelect :label="t('Country')" :options="countriesOptions" hide-selected diff --git a/src/components/CreateNewProvinceForm.vue b/src/components/CreateNewProvinceForm.vue index 2d626ed99..e32684a98 100644 --- a/src/components/CreateNewProvinceForm.vue +++ b/src/components/CreateNewProvinceForm.vue @@ -19,8 +19,11 @@ const provinceFormData = reactive({ const autonomiesOptions = ref([]); -const onDataSaved = (dataSaved) => { - emit('onDataSaved', dataSaved); +const onDataSaved = (dataSaved, requestResponse) => { + requestResponse.autonomy = autonomiesOptions.value.find( + (autonomy) => autonomy.id == requestResponse.autonomyFk + ); + emit('onDataSaved', dataSaved, requestResponse); }; </script> @@ -28,7 +31,7 @@ const onDataSaved = (dataSaved) => { <FetchData @on-fetch="(data) => (autonomiesOptions = data)" auto-load - url="Autonomies" + url="Autonomies/location" /> <FormModelPopup :title="t('New province')" @@ -36,10 +39,10 @@ const onDataSaved = (dataSaved) => { url-create="provinces" model="province" :form-initial-data="provinceFormData" - @on-data-saved="onDataSaved($event)" + @on-data-saved="onDataSaved" > <template #form-inputs="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Name')" v-model="data.name" @@ -53,7 +56,16 @@ const onDataSaved = (dataSaved) => { option-value="id" v-model="data.autonomyFk" :rules="validate('province.autonomyFk')" - /> + > + <template #option="{ itemProps, opt }"> + <QItem v-bind="itemProps"> + <QItemSection> + <QItemLabel>{{ opt.name }}</QItemLabel> + <QItemLabel caption> {{ opt.country.name }} </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> </VnRow> </template> </FormModelPopup> diff --git a/src/components/CreateThermographForm.vue b/src/components/CreateThermographForm.vue index 061c47712..65a1c2679 100644 --- a/src/components/CreateThermographForm.vue +++ b/src/components/CreateThermographForm.vue @@ -53,7 +53,7 @@ const onDataSaved = (dataSaved) => { @on-data-saved="onDataSaved($event)" > <template #form-inputs="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Identifier')" v-model="data.thermographId" diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue index 74c4a9bc0..33c831e3f 100644 --- a/src/components/CrudModel.vue +++ b/src/components/CrudModel.vue @@ -1,7 +1,7 @@ <script setup> import axios from 'axios'; import { computed, ref, watch } from 'vue'; -import { useRouter } from 'vue-router'; +import { useRouter, onBeforeRouteLeave } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; import { useValidator } from 'src/composables/useValidator'; @@ -97,6 +97,19 @@ defineExpose({ vnPaginateRef, }); +onBeforeRouteLeave((to, from, next) => { + if (hasChanges.value) + quasar.dialog({ + component: VnConfirm, + componentProps: { + title: t('globals.unsavedPopup.title'), + message: t('globals.unsavedPopup.subtitle'), + promise: () => next(), + }, + }); + else next(); +}); + async function fetch(data) { resetData(data); emit('onFetch', data); diff --git a/src/components/EditPictureForm.vue b/src/components/EditPictureForm.vue index 8a22debda..cd6107aca 100644 --- a/src/components/EditPictureForm.vue +++ b/src/components/EditPictureForm.vue @@ -245,14 +245,14 @@ const makeRequest = async () => { </div> <div class="column"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QOptionGroup :options="uploadMethodsOptions" type="radio" v-model="uploadMethodSelected" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QFile v-if="uploadMethodSelected === 'computer'" ref="inputFileRef" @@ -287,7 +287,7 @@ const makeRequest = async () => { placeholder="https://" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Orientation')" :options="viewportTypes" diff --git a/src/components/EditTableCellValueForm.vue b/src/components/EditTableCellValueForm.vue index 9d56ba738..14709e884 100644 --- a/src/components/EditTableCellValueForm.vue +++ b/src/components/EditTableCellValueForm.vue @@ -82,7 +82,7 @@ const closeForm = () => { <span class="title">{{ t('Edit') }}</span> <span class="countLines">{{ ` ${rows.length} ` }}</span> <span class="title">{{ t('buy(s)') }}</span> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Field to edit')" :options="fieldsOptions" diff --git a/src/components/FilterItemForm.vue b/src/components/FilterItemForm.vue index 956acb7ea..1cf36deeb 100644 --- a/src/components/FilterItemForm.vue +++ b/src/components/FilterItemForm.vue @@ -151,7 +151,7 @@ const selectItem = ({ id }) => { <QIcon name="close" size="sm" /> </span> <h1 class="title">{{ t('Filter item') }}</h1> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('entry.buys.name')" v-model="itemFilterParams.name" /> <VnInput :label="t('entry.buys.size')" v-model="itemFilterParams.size" /> <VnSelect diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue index d1d0f5e8f..c84772d9b 100644 --- a/src/components/FilterTravelForm.vue +++ b/src/components/FilterTravelForm.vue @@ -144,7 +144,7 @@ const selectTravel = ({ id }) => { <QIcon name="close" size="sm" /> </span> <h1 class="title">{{ t('Filter travels') }}</h1> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('entry.basicData.agency')" :options="agenciesOptions" diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index 79f8e602b..05f947cf3 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -87,6 +87,10 @@ const $props = defineProps({ type: Boolean, default: false, }, + defaultTrim: { + type: Boolean, + default: true, + }, }); const emit = defineEmits(['onFetch', 'onDataSaved']); const modelValue = computed( @@ -100,7 +104,6 @@ const isResetting = ref(false); const hasChanges = ref(!$props.observeFormChanges); const originalData = ref({}); const formData = computed(() => state.get(modelValue)); -const formUrl = computed(() => $props.url); const defaultButtons = computed(() => ({ save: { color: 'primary', @@ -151,19 +154,22 @@ if (!$props.url) (val) => updateAndEmit('onFetch', val) ); -watch(formUrl, async () => { - originalData.value = null; - reset(); - await fetch(); -}); +watch( + () => [$props.url, $props.filter], + async () => { + originalData.value = null; + reset(); + await fetch(); + } +); onBeforeRouteLeave((to, from, next) => { if (hasChanges.value && $props.observeFormChanges) quasar.dialog({ component: VnConfirm, componentProps: { - title: t('Unsaved changes will be lost'), - message: t('Are you sure exit without saving?'), + title: t('globals.unsavedPopup.title'), + message: t('globals.unsavedPopup.subtitle'), promise: () => next(), }, }); @@ -196,6 +202,7 @@ async function save() { isLoading.value = true; try { + formData.value = trimData(formData.value); const body = $props.mapper ? $props.mapper(formData.value) : formData.value; const method = $props.urlCreate ? 'post' : 'patch'; const url = @@ -254,6 +261,14 @@ function updateAndEmit(evt, val, res) { emit(evt, state.get(modelValue), res); } +function trimData(data) { + if (!$props.defaultTrim) return data; + for (const key in data) { + if (typeof data[key] == 'string') data[key] = data[key].trim(); + } + return data; +} + defineExpose({ save, isLoading, @@ -366,8 +381,3 @@ defineExpose({ padding: 32px; } </style> -<i18n> -es: - Unsaved changes will be lost: Los cambios que no haya guardado se perderán - Are you sure exit without saving?: ¿Seguro que quiere salir sin guardar? -</i18n> diff --git a/src/components/ItemsFilterPanel.vue b/src/components/ItemsFilterPanel.vue index 94adfe0ff..743c2c9d1 100644 --- a/src/components/ItemsFilterPanel.vue +++ b/src/components/ItemsFilterPanel.vue @@ -112,6 +112,7 @@ const getCategoryClass = (category, params) => { const getSelectedTagValues = async (tag) => { try { + if (!tag?.selectedTag?.id) return; tag.value = null; const filter = { fields: ['value'], diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue index 3051e8b99..e80a293c6 100644 --- a/src/components/NavBar.vue +++ b/src/components/NavBar.vue @@ -7,7 +7,7 @@ import { useQuasar } from 'quasar'; import PinnedModules from './PinnedModules.vue'; import UserPanel from 'components/UserPanel.vue'; import VnBreadcrumbs from './common/VnBreadcrumbs.vue'; -import VnImg from 'src/components/ui/VnImg.vue'; +import VnAvatar from './ui/VnAvatar.vue'; const { t } = useI18n(); const stateStore = useStateStore(); @@ -72,22 +72,13 @@ const pinnedModulesRef = ref(); </QTooltip> <PinnedModules ref="pinnedModulesRef" /> </QBtn> - <QBtn - :class="{ 'q-pa-none': quasar.platform.is.mobile }" - rounded - dense - flat - no-wrap - id="user" - > - <QAvatar size="lg"> - <VnImg - :id="user.id" - collection="user" - size="160x160" - :zoom-size="null" - /> - </QAvatar> + <QBtn class="q-pa-none" rounded dense flat no-wrap id="user"> + <VnAvatar + :worker-id="user.id" + :title="user.name" + size="lg" + color="transparent" + /> <QTooltip bottom> {{ t('globals.userPanel') }} </QTooltip> diff --git a/src/components/RegularizeStockForm.vue b/src/components/RegularizeStockForm.vue index 4f97033b3..f34386fc4 100644 --- a/src/components/RegularizeStockForm.vue +++ b/src/components/RegularizeStockForm.vue @@ -15,7 +15,7 @@ const props = defineProps({ default: null, }, warehouseFk: { - type: Boolean, + type: Number, default: null, }, }); @@ -23,7 +23,7 @@ const props = defineProps({ const { t } = useI18n(); const regularizeFormData = reactive({ - itemFk: props.itemFk, + itemFk: Number(props.itemFk), warehouseFk: props.warehouseFk, quantity: null, }); @@ -49,18 +49,19 @@ const onDataSaved = (data) => { @on-data-saved="onDataSaved($event)" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('Type the visible quantity')" v-model.number="data.quantity" + type="number" autofocus /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('Warehouse')" - v-model="data.warehouseFk" + v-model.number="data.warehouseFk" :options="warehousesOptions" option-value="id" option-label="name" diff --git a/src/components/TransferInvoiceForm.vue b/src/components/TransferInvoiceForm.vue index f307aa1f4..17c11d87e 100644 --- a/src/components/TransferInvoiceForm.vue +++ b/src/components/TransferInvoiceForm.vue @@ -118,13 +118,13 @@ const makeInvoice = async () => { /> <QDialog ref="dialogRef"> <FormPopup - @on-submit="makeInvoice()" - :title="t('Transfer invoice')" - :custom-submit-button-label="t('Transfer client')" - :default-cancel-button="false" + @on-submit="makeInvoice()" + :title="t('Transfer invoice')" + :custom-submit-button-label="t('Transfer client')" + :default-cancel-button="false" > - <template #form-inputs> - <VnRow class="row q-gutter-md q-mb-md"> + <template #form-inputs> + <VnRow> <VnSelect :label="t('Client')" :options="clientsOptions" @@ -160,7 +160,7 @@ const makeInvoice = async () => { :required="true" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Class')" :options="siiTypeInvoiceOutsOptions" @@ -191,9 +191,12 @@ const makeInvoice = async () => { :required="true" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div> - <QCheckbox :label="t('Bill destination client')" v-model="checked" /> + <QCheckbox + :label="t('Bill destination client')" + v-model="checked" + /> <QIcon name="info" class="cursor-info q-ml-sm" size="sm"> <QTooltip>{{ t('transferInvoiceInfo') }}</QTooltip> </QIcon> diff --git a/src/components/UserPanel.vue b/src/components/UserPanel.vue index 589524258..98334460a 100644 --- a/src/components/UserPanel.vue +++ b/src/components/UserPanel.vue @@ -11,8 +11,8 @@ import VnSelect from 'src/components/common/VnSelect.vue'; import VnRow from 'components/ui/VnRow.vue'; import FetchData from 'components/FetchData.vue'; import { useClipboard } from 'src/composables/useClipboard'; -import VnImg from 'src/components/ui/VnImg.vue'; import { useRole } from 'src/composables/useRole'; +import VnAvatar from './ui/VnAvatar.vue'; const state = useState(); const session = useSession(); @@ -136,7 +136,7 @@ const isEmployee = computed(() => useRole().isEmployee()); @update:model-value="saveLanguage" :label="t(`globals.lang['${userLocale}']`)" icon="public" - color="orange" + color="primary" false-value="es" true-value="en" /> @@ -145,7 +145,7 @@ const isEmployee = computed(() => useRole().isEmployee()); @update:model-value="saveDarkMode" :label="t(`globals.darkMode`)" checked-icon="dark_mode" - color="orange" + color="primary" unchecked-icon="light_mode" /> </div> @@ -153,10 +153,20 @@ const isEmployee = computed(() => useRole().isEmployee()); <QSeparator vertical inset class="q-mx-lg" /> <div class="col column items-center q-mb-sm"> - <QAvatar size="80px"> - <VnImg :id="user.id" collection="user" size="160x160" /> - </QAvatar> - + <VnAvatar + :worker-id="user.id" + :title="user.name" + size="xxl" + color="transparent" + /> + <QBtn + v-if="isEmployee" + class="q-mt-sm q-px-md" + :to="`/worker/${user.id}`" + color="primary" + :label="t('globals.myAccount')" + dense + /> <div class="text-subtitle1 q-mt-md"> <strong>{{ user.nickname }}</strong> </div> @@ -168,7 +178,7 @@ const isEmployee = computed(() => useRole().isEmployee()); </div> <QBtn id="logout" - color="orange" + color="primary" flat :label="t('globals.logOut')" size="sm" diff --git a/src/components/VnSelectProvince.vue b/src/components/VnSelectProvince.vue new file mode 100644 index 000000000..ea10ace19 --- /dev/null +++ b/src/components/VnSelectProvince.vue @@ -0,0 +1,59 @@ +<script setup> +import { ref, watch } from 'vue'; +import { useValidator } from 'src/composables/useValidator'; +import { useI18n } from 'vue-i18n'; + +import VnSelectDialog from 'components/common/VnSelectDialog.vue'; +import FetchData from 'components/FetchData.vue'; +import CreateNewProvinceForm from './CreateNewProvinceForm.vue'; + +const emit = defineEmits(['onProvinceCreated']); +const provinceFk = defineModel({ type: Number }); +watch(provinceFk, async () => await provincesFetchDataRef.value.fetch()); + +const { validate } = useValidator(); +const { t } = useI18n(); + +const provincesOptions = ref(); +const provincesFetchDataRef = ref(); + +async function onProvinceCreated(_, data) { + await provincesFetchDataRef.value.fetch(); + provinceFk.value = data.id; + emit('onProvinceCreated', data); +} +</script> + +<template> + <FetchData + ref="provincesFetchDataRef" + :filter="{ include: { relation: 'country' } }" + @on-fetch="(data) => (provincesOptions = data)" + auto-load + url="Provinces" + /> + <VnSelectDialog + :label="t('Province')" + :options="provincesOptions" + hide-selected + v-model="provinceFk" + :rules="validate && validate('postcode.provinceFk')" + :roles-allowed-to-create="['deliveryAssistant']" + > + <template #option="{ itemProps, opt }"> + <QItem v-bind="itemProps"> + <QItemSection> + <QItemLabel>{{ opt.name }}</QItemLabel> + <QItemLabel caption> {{ opt.country.name }} </QItemLabel> + </QItemSection> + </QItem> + </template> + <template #form> + <CreateNewProvinceForm @on-data-saved="onProvinceCreated" /> + </template> + </VnSelectDialog> +</template> +<i18n> + es: + Province: Provincia +</i18n> diff --git a/src/components/VnTable/VnChip.vue b/src/components/VnTable/VnChip.vue index 74207b943..f70ba7423 100644 --- a/src/components/VnTable/VnChip.vue +++ b/src/components/VnTable/VnChip.vue @@ -35,7 +35,9 @@ function stopEventPropagation(event) { dense square > - <span v-if="!col.chip.icon">{{ row[col.name] }}</span> + <span v-if="!col.chip.icon"> + {{ col.format ? col.format(row) : row[col.name] }} + </span> <QIcon v-else :name="col.chip.icon" color="primary-light" /> </QChip> </span> diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue index da4687d32..ed34e9eee 100644 --- a/src/components/VnTable/VnColumn.vue +++ b/src/components/VnTable/VnColumn.vue @@ -7,9 +7,11 @@ import { dashIfEmpty } from 'src/filters'; import VnSelect from 'components/common/VnSelect.vue'; import VnSelectCache from 'components/common/VnSelectCache.vue'; import VnInput from 'components/common/VnInput.vue'; +import VnInputNumber from 'components/common/VnInputNumber.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputTime from 'components/common/VnInputTime.vue'; import VnComponent from 'components/common/VnComponent.vue'; +import VnUserLink from 'components/ui/VnUserLink.vue'; const model = defineModel(undefined, { required: true }); const $props = defineProps({ @@ -66,7 +68,7 @@ const defaultComponents = { }, }, number: { - component: markRaw(VnInput), + component: markRaw(VnInputNumber), attrs: { disable: !$props.isEditable, class: 'fit', @@ -78,7 +80,7 @@ const defaultComponents = { date: { component: markRaw(VnInputDate), attrs: { - readonly: true, + readonly: !$props.isEditable, disable: !$props.isEditable, style: 'min-width: 125px', class: 'fit', @@ -98,14 +100,14 @@ const defaultComponents = { }, checkbox: { component: markRaw(QCheckbox), - attrs: (prop) => { + attrs: ({ model }) => { const defaultAttrs = { disable: !$props.isEditable, - 'model-value': Boolean(prop), + 'model-value': Boolean(model), class: 'no-padding fit', }; - if (typeof prop == 'number') { + if (typeof model == 'number') { defaultAttrs['true-value'] = 1; defaultAttrs['false-value'] = 0; } @@ -126,6 +128,9 @@ const defaultComponents = { icon: { component: markRaw(QIcon), }, + userLink: { + component: markRaw(VnUserLink), + }, }; const value = computed(() => { @@ -146,8 +151,8 @@ const col = computed(() => { }; } if ( - (newColumn.name.startsWith('is') || newColumn.name.startsWith('has')) && - !newColumn.component + (/^is[A-Z]/.test(newColumn.name) || /^has[A-Z]/.test(newColumn.name)) && + newColumn.component == null ) newColumn.component = 'checkbox'; if ($props.default && !newColumn.component) newColumn.component = $props.default; @@ -163,14 +168,14 @@ const components = computed(() => $props.components ?? defaultComponents); v-if="col.before" :prop="col.before" :components="components" - :value="model" + :value="{ row, model }" v-model="model" /> <VnComponent v-if="col.component" :prop="col" :components="components" - :value="model" + :value="{ row, model }" v-model="model" /> <span :title="value" v-else>{{ value }}</span> @@ -178,7 +183,7 @@ const components = computed(() => $props.components ?? defaultComponents); v-if="col.after" :prop="col.after" :components="components" - :value="model" + :value="{ row, model }" v-model="model" /> </div> diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue index 15e1cc947..c6d4d8ef2 100644 --- a/src/components/VnTable/VnFilter.vue +++ b/src/components/VnTable/VnFilter.vue @@ -10,6 +10,8 @@ import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputTime from 'components/common/VnInputTime.vue'; import VnTableColumn from 'components/VnTable/VnColumn.vue'; +defineExpose({ addFilter }); + const $props = defineProps({ column: { type: Object, @@ -32,7 +34,7 @@ const model = defineModel(undefined, { required: true }); const arrayData = useArrayData($props.dataKey, { searchUrl: $props.searchUrl }); const columnFilter = computed(() => $props.column?.columnFilter); -const updateEvent = { 'update:modelValue': addFilter }; +const updateEvent = { 'update:modelValue': addFilter, remove: () => addFilter(null) }; const enterEvent = { 'keyup.enter': () => addFilter(model.value), remove: () => addFilter(null), @@ -45,7 +47,18 @@ const defaultAttrs = { }; const forceAttrs = { - label: $props.showTitle ? '' : $props.column.label, + label: $props.showTitle ? '' : columnFilter.value?.label ?? $props.column.label, +}; + +const selectComponent = { + component: markRaw(VnSelect), + event: updateEvent, + attrs: { + class: 'q-px-sm q-pb-xs q-pt-none fit', + dense: true, + filled: !$props.showTitle, + }, + forceAttrs, }; const components = { @@ -64,6 +77,7 @@ const components = { attrs: { ...defaultAttrs, clearable: true, + type: 'number', }, forceAttrs, }, @@ -97,16 +111,8 @@ const components = { }, forceAttrs, }, - select: { - component: markRaw(VnSelect), - event: updateEvent, - attrs: { - class: 'q-px-sm q-pb-xs q-pt-none fit', - dense: true, - filled: !$props.showTitle, - }, - forceAttrs, - }, + select: selectComponent, + rawSelect: selectComponent, }; async function addFilter(value) { diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue index 1e1dc9e01..98c7ab392 100644 --- a/src/components/VnTable/VnOrder.vue +++ b/src/components/VnTable/VnOrder.vue @@ -1,7 +1,7 @@ <script setup> import { ref } from 'vue'; import { useArrayData } from 'composables/useArrayData'; -const model = defineModel({ type: Object, required: true }); +const model = defineModel({ type: Object }); const $props = defineProps({ name: { type: String, @@ -56,7 +56,7 @@ defineExpose({ orderBy }); <span :title="label">{{ label }}</span> <QChip v-if="name" - :label="!vertical && model?.index" + :label="!vertical ? model?.index : ''" :icon=" (model?.index || hover) && !vertical ? model?.direction == 'DESC' diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index dc5410e93..6c77d44df 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -1,5 +1,5 @@ <script setup> -import { ref, onMounted, computed, watch } from 'vue'; +import { ref, onBeforeMount, onMounted, computed, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute, useRouter } from 'vue-router'; import { useQuasar } from 'quasar'; @@ -37,6 +37,10 @@ const $props = defineProps({ type: [Function, Boolean], default: null, }, + rowCtrlClick: { + type: [Function, Boolean], + default: null, + }, redirect: { type: String, default: null, @@ -92,10 +96,11 @@ const route = useRoute(); const router = useRouter(); const quasar = useQuasar(); -const DEFAULT_MODE = 'card'; +const CARD_MODE = 'card'; const TABLE_MODE = 'table'; -const mode = ref(DEFAULT_MODE); +const mode = ref(CARD_MODE); const selected = ref([]); +const hasParams = ref(false); const routeQuery = JSON.parse(route?.query[$props.searchUrl] ?? '{}'); const params = ref({ ...routeQuery, ...routeQuery.filter?.where }); const orders = ref(parseOrder(routeQuery.filter?.order)); @@ -103,6 +108,8 @@ const CrudModelRef = ref({}); const showForm = ref(false); const splittedColumns = ref({ columns: [] }); const columnsVisibilitySkiped = ref(); +const createForm = ref(); + const tableModes = [ { icon: 'view_column', @@ -113,21 +120,35 @@ const tableModes = [ { icon: 'grid_view', title: t('grid view'), - value: DEFAULT_MODE, + value: CARD_MODE, disable: $props.disableOption?.card, }, ]; +onBeforeMount(() => { + setUserParams(route.query[$props.searchUrl]); + hasParams.value = params.value && Object.keys(params.value).length !== 0; +}); onMounted(() => { - mode.value = quasar.platform.is.mobile ? DEFAULT_MODE : $props.defaultMode; + mode.value = + quasar.platform.is.mobile && !$props.disableOption?.card + ? CARD_MODE + : $props.defaultMode; stateStore.rightDrawer = true; - setUserParams(route.query[$props.searchUrl]); columnsVisibilitySkiped.value = [ ...splittedColumns.value.columns .filter((c) => c.visible == false) .map((c) => c.name), ...['tableActions'], ]; + createForm.value = $props.create; + if ($props.create && route?.query?.createForm) { + showForm.value = true; + createForm.value = { + ...createForm.value, + ...{ formInitialData: JSON.parse(route?.query?.createForm) }, + }; + } }); watch( @@ -143,13 +164,16 @@ watch( const isTableMode = computed(() => mode.value == TABLE_MODE); -function setUserParams(watchedParams) { +function setUserParams(watchedParams, watchedOrder) { if (!watchedParams) return; if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams); - const filter = JSON.parse(watchedParams?.filter); + const filter = + typeof watchedParams?.filter == 'string' + ? JSON.parse(watchedParams?.filter ?? '{}') + : watchedParams?.filter; const where = filter?.where; - const order = filter?.order; + const order = watchedOrder ?? filter?.order; watchedParams = { ...watchedParams, ...where }; delete watchedParams.filter; @@ -167,13 +191,17 @@ function splitColumns(columns) { }; for (const col of columns) { - if (col.name == 'tableActions') splittedColumns.value.actions = col; + if (col.name == 'tableActions') { + col.orderBy = false; + splittedColumns.value.actions = col; + } if (col.chip) splittedColumns.value.chips.push(col); if (col.isTitle) splittedColumns.value.title = col; if (col.create) splittedColumns.value.create.push(col); if (col.cardVisible) splittedColumns.value.cardVisible.push(col); if ($props.isEditable && col.disable == null) col.disable = false; - if ($props.useModel) col.columnFilter = { ...col.columnFilter, inWhere: true }; + if ($props.useModel && col.columnFilter != false) + col.columnFilter = { ...col.columnFilter, inWhere: true }; splittedColumns.value.columns.push(col); } // Status column @@ -198,6 +226,16 @@ const rowClickFunction = computed(() => { return () => {}; }); +const rowCtrlClickFunction = computed(() => { + if ($props.rowCtrlClick != undefined) return $props.rowCtrlClick; + if ($props.redirect) + return (evt, { id }) => { + stopEventPropagation(evt); + window.open(`/#/${$props.redirect}/${id}`, '_blank'); + }; + return () => {}; +}); + function redirectFn(id) { router.push({ path: `/${$props.redirect}/${id}` }); } @@ -208,6 +246,7 @@ function stopEventPropagation(event) { } function reload(params) { + selected.value = []; CrudModelRef.value.reload(params); } @@ -255,11 +294,14 @@ defineExpose({ v-model="params" :search-url="searchUrl" :redirect="!!redirect" + @set-user-params="setUserParams" > <template #body> <div class="row no-wrap flex-center" - v-for="col of splittedColumns.columns" + v-for="col of splittedColumns.columns.filter( + (c) => c.columnFilter ?? true + )" :key="col.id" > <VnTableFilter @@ -269,7 +311,11 @@ defineExpose({ :search-url="searchUrl" /> <VnTableOrder - v-model="orders[col.name]" + v-if=" + col?.columnFilter !== false && + col?.name !== 'tableActions' + " + v-model="orders[col.orderBy ?? col.name]" :name="col.orderBy ?? col.name" :data-key="$attrs['data-key']" :search-url="searchUrl" @@ -291,10 +337,12 @@ defineExpose({ v-bind="$attrs" :limit="20" ref="CrudModelRef" + @on-fetch="(...args) => emit('onFetch', ...args)" :search-url="searchUrl" :disable-infinite-scroll="isTableMode" @save-changes="reload" :has-sub-toolbar="$attrs['hasSubToolbar'] ?? isEditable" + :auto-load="hasParams || $attrs['auto-load']" > <template v-for="(_, slotName) in $slots" @@ -327,7 +375,7 @@ defineExpose({ <template #top-left v-if="!$props.withoutHeader"> <slot name="top-left"></slot> </template> - <template #top-right> + <template #top-right v-if="!$props.withoutHeader"> <VnVisibleColumn v-if="isTableMode" v-model="splittedColumns.columns" @@ -344,25 +392,24 @@ defineExpose({ <QBtn v-if="$props.rightSearch" icon="filter_alt" - title="asd" class="bg-vn-section-color q-ml-md" dense @click="stateStore.toggleRightDrawer()" /> </template> <template #header-cell="{ col }"> - <QTh v-if="col.visible ?? true" auto-width> + <QTh v-if="col.visible ?? true"> <div class="column self-start q-ml-xs ellipsis" :class="`text-${col?.align ?? 'left'}`" - style="height: 75px" + :style="$props.columnSearch ? 'height: 75px' : ''" > <div class="row items-center no-wrap" style="height: 30px" > <VnTableOrder - v-model="orders[col.name]" + v-model="orders[col.orderBy ?? col.name]" :name="col.orderBy ?? col.name" :label="col?.label" :data-key="$attrs['data-key']" @@ -376,6 +423,7 @@ defineExpose({ :data-key="$attrs['data-key']" v-model="params[columnName(col)]" :search-url="searchUrl" + class="full-width" /> </div> </QTh> @@ -395,19 +443,29 @@ defineExpose({ </VnTableChip> </QTd> </template> - <template #body-cell="{ col, row }"> + <template #body-cell="{ col, row, rowIndex }"> <!-- Columns --> <QTd auto-width class="no-margin q-px-xs" - :class="[getColAlign(col), col.class, col.columnField?.class]" + :class="[getColAlign(col), col.columnClass]" v-if="col.visible ?? true" + @click.ctrl=" + ($event) => + rowCtrlClickFunction && + rowCtrlClickFunction($event, row) + " > - <slot :name="`column-${col.name}`" :col="col" :row="row"> + <slot + :name="`column-${col.name}`" + :col="col" + :row="row" + :row-index="rowIndex" + > <VnTableColumn :column="col" :row="row" - :is-editable="false" + :is-editable="col.isEditable ?? isEditable" v-model="row[col.name]" component-prop="columnField" /> @@ -433,6 +491,11 @@ defineExpose({ ? 'text-primary-light' : 'color-vn-text ' " + :style="`visibility: ${ + (btn.show && btn.show(row)) ?? true + ? 'visible' + : 'hidden' + }`" @click="btn.action(row)" /> </QTd> @@ -490,7 +553,9 @@ defineExpose({ :class="$props.cardClass" > <div - v-for="col of splittedColumns.cardVisible" + v-for="( + col, index + ) of splittedColumns.cardVisible" :key="col.name" class="fields" > @@ -511,6 +576,7 @@ defineExpose({ :name="`column-${col.name}`" :col="col" :row="row" + :row-index="index" > <VnTableColumn :column="col" @@ -559,27 +625,34 @@ defineExpose({ <QPageSticky v-if="create" :offset="[20, 20]" style="z-index: 2"> <QBtn @click="showForm = !showForm" color="primary" fab icon="add" /> <QTooltip> - {{ create.title }} + {{ createForm.title }} </QTooltip> </QPageSticky> <QDialog v-model="showForm" transition-show="scale" transition-hide="scale"> <FormModelPopup - v-bind="create" + v-bind="createForm" :model="$attrs['data-key'] + 'Create'" - @on-data-saved="(_, res) => create.onDataSaved(res)" + @on-data-saved="(_, res) => createForm.onDataSaved(res)" > <template #form-inputs="{ data }"> <div class="grid-create"> - <VnTableColumn + <slot v-for="column of splittedColumns.create" :key="column.name" - :column="column" - :row="{}" - default="input" - v-model="data[column.name]" - :show-label="true" - component-prop="columnCreate" - /> + :name="`column-create-${column.name}`" + :data="data" + :column-name="column.name" + :label="column.label" + > + <VnTableColumn + :column="column" + :row="{}" + default="input" + v-model="data[column.name]" + :show-label="true" + component-prop="columnCreate" + /> + </slot> <slot name="more-create-dialog" :data="data" /> </div> </template> diff --git a/src/components/VnTable/VnVisibleColumn.vue b/src/components/VnTable/VnVisibleColumn.vue index e3bb52637..36f5ed7de 100644 --- a/src/components/VnTable/VnVisibleColumn.vue +++ b/src/components/VnTable/VnVisibleColumn.vue @@ -65,7 +65,7 @@ async function fetchViewConfigData() { const userConfig = await getConfig('UserConfigViews', { where: { ...defaultFilter.where, - ...{ userFk: user.id }, + ...{ userFk: user.value.id }, }, }); @@ -81,7 +81,7 @@ async function fetchViewConfigData() { return; } } catch (err) { - console.err('Error fetching config view data', err); + console.error('Error fetching config view data', err); } } diff --git a/src/components/common/RightMenu.vue b/src/components/common/RightMenu.vue index f0a95b0df..732e5367d 100644 --- a/src/components/common/RightMenu.vue +++ b/src/components/common/RightMenu.vue @@ -46,7 +46,7 @@ const stateStore = useStateStore(); </div> </Teleport> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> - <QScrollArea class="fit text-grey-8"> + <QScrollArea class="fit"> <div id="right-panel"></div> <slot v-if="!hasContent" name="right-panel" /> </QScrollArea> diff --git a/src/components/common/TableVisibleColumns.vue b/src/components/common/TableVisibleColumns.vue index a4e4afafe..9a6c70ef0 100644 --- a/src/components/common/TableVisibleColumns.vue +++ b/src/components/common/TableVisibleColumns.vue @@ -84,7 +84,7 @@ const fetchViewConfigData = async () => { setUserConfigViewData(defaultColumns); } } catch (err) { - console.err('Error fetching config view data', err); + console.error('Error fetching config view data', err); } }; diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue index 17fa74317..03a7ce7da 100644 --- a/src/components/common/VnCard.vue +++ b/src/components/common/VnCard.vue @@ -17,12 +17,7 @@ const props = defineProps({ descriptor: { type: Object, required: true }, filterPanel: { type: Object, default: undefined }, searchDataKey: { type: String, default: undefined }, - searchUrl: { type: String, default: undefined }, - searchbarLabel: { type: String, default: '' }, - searchbarInfo: { type: String, default: '' }, - searchCustomRouteRedirect: { type: String, default: undefined }, - searchRedirect: { type: Boolean, default: true }, - searchMakeFetch: { type: Boolean, default: true }, + searchbarProps: { type: Object, default: undefined }, }); const stateStore = useStateStore(); @@ -31,7 +26,10 @@ const url = computed(() => { if (props.baseUrl) return `${props.baseUrl}/${route.params.id}`; return props.customUrl; }); - +const searchRightDataKey = computed(() => { + if (!props.searchDataKey) return route.name; + return props.searchDataKey; +}); const arrayData = useArrayData(props.dataKey, { url: url.value, filter: props.filter, @@ -65,19 +63,11 @@ if (props.baseUrl) { </QScrollArea> </QDrawer> <slot name="searchbar" v-if="props.searchDataKey"> - <VnSearchbar - :data-key="props.searchDataKey" - :url="props.searchUrl" - :label="props.searchbarLabel" - :info="props.searchbarInfo" - :custom-route-redirect-name="searchCustomRouteRedirect" - :redirect="searchRedirect" - /> + <VnSearchbar :data-key="props.searchDataKey" v-bind="props.searchbarProps" /> </slot> - <slot v-else name="searchbar" /> <RightMenu> <template #right-panel v-if="props.filterPanel"> - <component :is="props.filterPanel" :data-key="props.searchDataKey" /> + <component :is="props.filterPanel" :data-key="searchRightDataKey" /> </template> </RightMenu> <QPageContainer> diff --git a/src/components/common/VnComponent.vue b/src/components/common/VnComponent.vue index d7719034a..fa99f9892 100644 --- a/src/components/common/VnComponent.vue +++ b/src/components/common/VnComponent.vue @@ -17,15 +17,17 @@ const $props = defineProps({ }, }); +let mixed; const componentArray = computed(() => { if (typeof $props.prop === 'object') return [$props.prop]; return $props.prop; }); function mix(toComponent) { + if (mixed) return mixed; const { component, attrs, event } = toComponent; const customComponent = $props.components[component]; - return { + mixed = { component: customComponent?.component ?? component, attrs: { ...toValueAttrs(attrs), @@ -33,8 +35,9 @@ function mix(toComponent) { ...toComponent, ...toValueAttrs(customComponent?.forceAttrs), }, - event: event ?? customComponent?.event, + event: { ...customComponent?.event, ...event }, }; + return mixed; } function toValueAttrs(attrs) { diff --git a/src/components/common/VnCurrency.vue b/src/components/common/VnCurrency.vue deleted file mode 100644 index b892e5012..000000000 --- a/src/components/common/VnCurrency.vue +++ /dev/null @@ -1,34 +0,0 @@ -<script setup> -import { computed } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useCapitalize } from 'src/composables/useCapitalize'; -import VnInput from 'src/components/common/VnInput.vue'; - -const props = defineProps({ - modelValue: { type: [String, Number], default: '' }, -}); - -const { t } = useI18n(); -const emit = defineEmits(['update:modelValue']); - -const amount = computed({ - get() { - return props.modelValue; - }, - set(val) { - emit('update:modelValue', val); - }, -}); -</script> -<template> - <VnInput - v-model="amount" - type="number" - step="any" - :label="useCapitalize(t('amount'))" - /> -</template> -<i18n> -es: - amount: importe -</i18n> diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue index 05f7c52d1..5bc1d7fd2 100644 --- a/src/components/common/VnInputDate.vue +++ b/src/components/common/VnInputDate.vue @@ -47,15 +47,18 @@ const formattedDate = computed({ let newDate; if (value) { // parse input - if (value.includes('/') && value.length >= 10) { - if (value.at(2) == '/') value = value.split('/').reverse().join('/'); - value = date.formatDate( - new Date(value).toISOString(), - 'YYYY-MM-DDTHH:mm:ss.SSSZ' - ); + if (value.includes('/')) { + if (value.length == 6) value = value + new Date().getFullYear(); + if (value.length >= 10) { + if (value.at(2) == '/') value = value.split('/').reverse().join('/'); + value = date.formatDate( + new Date(value).toISOString(), + 'YYYY-MM-DDTHH:mm:ss.SSSZ' + ); + } } - let ymd = value.split('-').map((e) => parseInt(e)); - newDate = new Date(ymd[0], ymd[1] - 1, ymd[2]); + const [year, month, day] = value.split('-').map((e) => parseInt(e)); + newDate = new Date(year, month - 1, day); if (model.value) { const orgDate = model.value instanceof Date ? model.value : new Date(model.value); @@ -113,7 +116,12 @@ const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; isPopupOpen = false; " /> - <QIcon name="event" class="cursor-pointer" /> + <QIcon + name="event" + class="cursor-pointer" + @click="isPopupOpen = !isPopupOpen" + :title="t('Open date')" + /> </template> <QMenu transition-show="scale" @@ -122,6 +130,7 @@ const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; anchor="bottom left" self="top start" :no-focus="true" + :no-parent-event="true" > <QDate v-model="popupDate" @@ -138,7 +147,6 @@ const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; </QInput> </div> </template> - <style lang="scss"> .vn-input-date.q-field--standard.q-field--readonly .q-field__control:before { border-bottom-style: solid; @@ -148,3 +156,7 @@ const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; border-style: solid; } </style> +<i18n> + es: + Open date: Abrir fecha +</i18n> diff --git a/src/components/common/VnInputNumber.vue b/src/components/common/VnInputNumber.vue new file mode 100644 index 000000000..ef4bb7512 --- /dev/null +++ b/src/components/common/VnInputNumber.vue @@ -0,0 +1,8 @@ +<script setup> +import VnInput from 'src/components/common/VnInput.vue'; +const model = defineModel({ type: [Number, String] }); +</script> + +<template> + <VnInput v-bind="$attrs" v-model.number="model" type="number" /> +</template> diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue index afc1456ae..7c03d91a8 100644 --- a/src/components/common/VnInputTime.vue +++ b/src/components/common/VnInputTime.vue @@ -1,5 +1,6 @@ <script setup> -import { watch, computed, ref } from 'vue'; +import { computed, ref } from 'vue'; +import { useI18n } from 'vue-i18n'; import { date } from 'quasar'; import { useValidator } from 'src/composables/useValidator'; const { validations } = useValidator(); @@ -18,6 +19,8 @@ const props = defineProps({ }); const $attrs = useAttrs(); +const initialDate = ref(model.value); +const { t } = useI18n(); const requiredFieldRule = (val) => validations().required($attrs.required, val); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; @@ -45,11 +48,18 @@ const formattedTime = computed({ let time = value; if (time) { if (time?.length > 5) time = dateToTime(time); + else { + if (time.length == 1 && parseInt(time) > 2) time = time.padStart(2, '0'); + time = time.padEnd(5, '0'); + if (!time.includes(':')) + time = time.substring(0, 2) + ':' + time.substring(3, 5); + } if (!props.timeOnly) { - const hours = time.split(':'); - const date = new Date(model.value); - date.setHours(hours[0], hours[1], 0); - time = date.toISOString(); + const [hh, mm] = time.split(':'); + + const date = new Date(model.value ? model.value : initialDate.value); + date.setHours(hh, mm, 0); + time = date?.toISOString(); } } model.value = time; @@ -59,14 +69,7 @@ const formattedTime = computed({ function dateToTime(newDate) { return date.formatDate(new Date(newDate), dateFormat); } - -watch( - () => model.value, - (val) => (formattedTime.value = val), - { immediate: true } -); </script> - <template> <div @mouseover="hover = true" @mouseleave="hover = false"> <QInput @@ -78,6 +81,8 @@ watch( :class="{ required: $attrs.required }" style="min-width: 100px" :rules="mixinRules" + @click="isPopupOpen = false" + type="time" > <template #append> <QIcon @@ -94,7 +99,12 @@ watch( isPopupOpen = false; " /> - <QIcon name="Schedule" class="cursor-pointer" /> + <QIcon + name="Schedule" + class="cursor-pointer" + @click="isPopupOpen = !isPopupOpen" + :title="t('Open time')" + /> </template> <QMenu transition-show="scale" @@ -103,6 +113,7 @@ watch( anchor="bottom left" self="top start" :no-focus="true" + :no-parent-event="true" > <QTime v-model="formattedTime" mask="HH:mm" landscape now-btn /> </QMenu> @@ -118,3 +129,12 @@ watch( border-style: solid; } </style> +<style lang="scss" scoped> +:deep(input[type='time']::-webkit-calendar-picker-indicator) { + display: none; +} +</style> +<i18n> + es: + Open time: Abrir tiempo +</i18n> diff --git a/src/components/common/VnLocation.vue b/src/components/common/VnLocation.vue index 9ed48ca15..8256ec5b0 100644 --- a/src/components/common/VnLocation.vue +++ b/src/components/common/VnLocation.vue @@ -1,123 +1,33 @@ <script setup> -import { ref, toRefs, computed, watch, onMounted } from 'vue'; import CreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue'; import VnSelectDialog from 'components/common/VnSelectDialog.vue'; -import FetchData from 'components/FetchData.vue'; -const emit = defineEmits(['update:modelValue', 'update:options']); import { useI18n } from 'vue-i18n'; const { t } = useI18n(); -const postcodesOptions = ref([]); -const postcodesRef = ref(null); - -const $props = defineProps({ - modelValue: { - type: [String, Number, Object], - default: null, - }, - options: { - type: Array, - default: () => [], - }, - optionLabel: { - type: String, - default: '', - }, - optionValue: { - type: String, - default: '', - }, - filterOptions: { - type: Array, - default: () => [], - }, - isClearable: { - type: Boolean, - default: true, - }, - defaultFilter: { - type: Boolean, - default: true, - }, -}); - -const { options } = toRefs($props); -const myOptions = ref([]); -const myOptionsOriginal = ref([]); - -const value = computed({ - get() { - return $props.modelValue; - }, - set(value) { - emit( - 'update:modelValue', - postcodesOptions.value.find((p) => p.code === value) - ); - }, -}); - -onMounted(() => { - locationFilter($props.modelValue); -}); - -function setOptions(data) { - myOptions.value = JSON.parse(JSON.stringify(data)); - myOptionsOriginal.value = JSON.parse(JSON.stringify(data)); -} -setOptions(options.value); - -watch(options, (newValue) => { - setOptions(newValue); -}); +const value = defineModel({ type: [String, Number, Object] }); function showLabel(data) { return `${data.code} - ${data.town}(${data.province}), ${data.country}`; } - -function locationFilter(search = '') { - if ( - search && - (search.includes('undefined') || search.startsWith(`${$props.modelValue} - `)) - ) - return; - let where = { search }; - postcodesRef.value.fetch({ filter: { where }, limit: 30 }); -} - -function handleFetch(data) { - postcodesOptions.value = data; -} -function onDataSaved(newPostcode) { - postcodesOptions.value.push(newPostcode); - value.value = newPostcode.code; -} </script> <template> - <FetchData - ref="postcodesRef" - url="Postcodes/filter" - @on-fetch="(data) => handleFetch(data)" - /> <VnSelectDialog - v-if="postcodesRef" - :option-label="(opt) => showLabel(opt) ?? 'code'" - :option-value="(opt) => opt.code" v-model="value" - :options="postcodesOptions" + option-value="code" + option-filter-value="search" + :option-label="(opt) => showLabel(opt)" + url="Postcodes/filter" + :use-like="false" :label="t('Location')" :placeholder="t('search_by_postalcode')" - @input-value="locationFilter" - :default-filter="false" :input-debounce="300" :class="{ required: $attrs.required }" v-bind="$attrs" clearable + :emit-value="false" > <template #form> - <CreateNewPostcode - @on-data-saved="onDataSaved" - /> + <CreateNewPostcode @on-data-saved="(newValue) => (value = newValue)" /> </template> <template #option="{ itemProps, opt }"> <QItem v-bind="itemProps"> diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue index 19765b1f7..2163d54d4 100644 --- a/src/components/common/VnLog.vue +++ b/src/components/common/VnLog.vue @@ -1,7 +1,7 @@ <script setup> -import { ref, onUnmounted } from 'vue'; +import { ref, onUnmounted, watch } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import axios from 'axios'; import { date } from 'quasar'; import { useStateStore } from 'stores/useStateStore'; @@ -19,6 +19,7 @@ const stateStore = useStateStore(); const validationsStore = useValidator(); const { models } = validationsStore; const route = useRoute(); +const router = useRouter(); const { t } = useI18n(); const props = defineProps({ model: { @@ -213,7 +214,7 @@ function getLogTree(data) { } nLogs++; modelLog.logs.push(log); - + modelLog.summaryId = modelLog.logs[0].summaryId; // Changes const notDelete = log.action != 'delete'; const olds = (notDelete ? log.oldInstance : null) || {}; @@ -381,6 +382,13 @@ setLogTree(); onUnmounted(() => { stateStore.rightDrawer = false; }); + +watch( + () => router.currentRoute.value.params.id, + () => { + applyFilter(); + } +); </script> <template> <FetchData @@ -399,9 +407,12 @@ onUnmounted(() => { @on-fetch=" (data) => (actions = data.map((item) => { + const changedModel = item.changedModel; return { - locale: useCapitalize(validations[item.changedModel].locale.name), - value: item.changedModel, + locale: useCapitalize( + validations[changedModel]?.locale?.name ?? changedModel + ), + value: changedModel, }; })) " @@ -464,12 +475,17 @@ onUnmounted(() => { > {{ t(modelLog.modelI18n) }} </QChip> - <span class="model-id" v-if="modelLog.summaryId" - >#{{ modelLog.summaryId }}</span - > - <span class="model-value" :title="modelLog.showValue"> - {{ modelLog.showValue }} - </span> + + <span + class="model-id q-mr-xs" + v-if="modelLog.summaryId" + v-text="`#${modelLog.summaryId}`" + /> + <span + class="model-value" + :title="modelLog.showValue" + v-text="modelLog.showValue" + /> <QBtn flat round diff --git a/src/pages/Ticket/TicketMain.vue b/src/components/common/VnSectionMain.vue similarity index 69% rename from src/pages/Ticket/TicketMain.vue rename to src/components/common/VnSectionMain.vue index f0dc2e500..0c1641ce1 100644 --- a/src/pages/Ticket/TicketMain.vue +++ b/src/components/common/VnSectionMain.vue @@ -1,8 +1,16 @@ <script setup> import { useStateStore } from 'stores/useStateStore'; import LeftMenu from 'components/LeftMenu.vue'; +import { onMounted } from 'vue'; const stateStore = useStateStore(); +const $props = defineProps({ + leftDrawer: { + type: Boolean, + default: true, + }, +}); +onMounted(() => (stateStore.leftDrawer = $props.leftDrawer)); </script> <template> diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 192fead44..0ba056d6f 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -1,11 +1,10 @@ <script setup> -import { ref, toRefs, computed, watch, onMounted } from 'vue'; +import { ref, toRefs, computed, watch, onMounted, useAttrs } from 'vue'; import FetchData from 'src/components/FetchData.vue'; import { useValidator } from 'src/composables/useValidator'; -import { useAttrs } from 'vue'; -const { validations } = useValidator(); -const emit = defineEmits(['update:modelValue', 'update:options']); +const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); + const $props = defineProps({ modelValue: { type: [String, Number, Object], @@ -27,9 +26,13 @@ const $props = defineProps({ type: String, default: null, }, + optionFilterValue: { + type: String, + default: null, + }, url: { type: String, - default: '', + default: null, }, filterOptions: { type: [Array], @@ -47,6 +50,10 @@ const $props = defineProps({ type: Array, default: null, }, + include: { + type: [Object, Array], + default: null, + }, where: { type: Object, default: null, @@ -73,18 +80,21 @@ const requiredFieldRule = (val) => validations().required($attrs.required, val); const $attrs = useAttrs(); const mixinRules = [requiredFieldRule, ...($attrs.rules ?? [])]; -const { optionLabel, optionValue, optionFilter, options, modelValue } = toRefs($props); +const { optionLabel, optionValue, optionFilter, optionFilterValue, options, modelValue } = + toRefs($props); const myOptions = ref([]); const myOptionsOriginal = ref([]); const vnSelectRef = ref(); const dataRef = ref(); const lastVal = ref(); +const { validations } = useValidator(); const value = computed({ get() { return $props.modelValue; }, set(value) { + setOptions(myOptionsOriginal.value); emit('update:modelValue', value); }, }); @@ -121,7 +131,7 @@ onMounted(() => { }); function filter(val, options) { - const search = val.toString().toLowerCase(); + const search = val?.toString()?.toLowerCase(); if (!search) return options; @@ -133,7 +143,8 @@ function filter(val, options) { }); } - const id = row.id; + if (!row) return; + const id = row[$props.optionValue]; const optionLabel = String(row[$props.optionLabel]).toLowerCase(); return id == search || optionLabel.includes(search); @@ -143,17 +154,20 @@ function filter(val, options) { async function fetchFilter(val) { if (!$props.url || !dataRef.value) return; - const { fields, sortBy, limit } = $props; - let key = optionFilter.value ?? optionLabel.value; - - if (new RegExp(/\d/g).test(val)) key = optionValue.value; + const { fields, include, sortBy, limit } = $props; + const key = + optionFilterValue.value ?? + (new RegExp(/\d/g).test(val) + ? optionValue.value + : optionFilter.value ?? optionLabel.value); const defaultWhere = $props.useLike ? { [key]: { like: `%${val}%` } } : { [key]: val }; const where = { ...(val ? defaultWhere : {}), ...$props.where }; - const fetchOptions = { where, order: sortBy, limit }; + const fetchOptions = { where, include, limit }; if (fields) fetchOptions.fields = fields; + if (sortBy) fetchOptions.order = sortBy; return dataRef.value.fetch(fetchOptions); } @@ -166,7 +180,10 @@ async function filterHandler(val, update) { let newOptions; if (!$props.defaultFilter) return update(); - if ($props.url) { + if ( + $props.url && + ($props.limit || (!$props.limit && Object.keys(myOptions.value).length === 0)) + ) { newOptions = await fetchFilter(val); } else newOptions = filter(val, myOptionsOriginal.value); update( @@ -182,13 +199,9 @@ async function filterHandler(val, update) { ); } -watch(options, (newValue) => { - setOptions(newValue); -}); -watch(modelValue, (newValue) => { - if (!myOptions.value.some((option) => option[optionValue.value] == newValue)) - fetchFilter(newValue); -}); +function nullishToTrue(value) { + return value ?? true; +} </script> <template> @@ -207,12 +220,12 @@ watch(modelValue, (newValue) => { :option-label="optionLabel" :option-value="optionValue" v-bind="$attrs" - emit-value - map-options - use-input @filter="filterHandler" - hide-selected - fill-input + :emit-value="nullishToTrue($attrs['emit-value'])" + :map-options="nullishToTrue($attrs['map-options'])" + :use-input="nullishToTrue($attrs['use-input'])" + :hide-selected="nullishToTrue($attrs['hide-selected'])" + :fill-input="nullishToTrue($attrs['fill-input'])" ref="vnSelectRef" lazy-rules :rules="mixinRules" @@ -223,7 +236,12 @@ watch(modelValue, (newValue) => { <QIcon v-show="value" name="close" - @click.stop="value = null" + @click.stop=" + () => { + value = null; + emit('remove'); + } + " class="cursor-pointer" size="xs" /> diff --git a/src/components/common/VnSelectCache.vue b/src/components/common/VnSelectCache.vue index 51873ef6e..29cf22dc5 100644 --- a/src/components/common/VnSelectCache.vue +++ b/src/components/common/VnSelectCache.vue @@ -8,18 +8,32 @@ const $props = defineProps({ default: null, }, find: { - type: String, + type: [String, Object], default: null, + description: 'search in row to add default options', }, }); const options = ref([]); + onBeforeMount(async () => { - const { url } = useAttrs(); + const { url, optionValue, optionLabel } = useAttrs(); const findBy = $props.find ?? url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1); - if (findBy) options.value = [$props.row[findBy]]; + if (!findBy || !$props.row) return; + // is object + if (typeof findBy == 'object') { + const { value, label } = findBy; + if (!$props.row[value] || !$props.row[label]) return; + return (options.value = [ + { + [optionValue ?? 'id']: $props.row[value], + [optionLabel ?? 'name']: $props.row[label], + }, + ]); + } + // is string + if ($props.row[findBy]) options.value = [$props.row[findBy]]; }); </script> - <template> <VnSelect v-bind="$attrs" :options="$attrs.options ?? options" /> </template> diff --git a/src/components/common/VnSelectDialog.vue b/src/components/common/VnSelectDialog.vue index 3726691af..7f7c29f5d 100644 --- a/src/components/common/VnSelectDialog.vue +++ b/src/components/common/VnSelectDialog.vue @@ -1,21 +1,12 @@ <script setup> import { ref, computed } from 'vue'; - -import VnSelect from 'src/components/common/VnSelect.vue'; - import { useRole } from 'src/composables/useRole'; +import VnSelect from 'src/components/common/VnSelect.vue'; const emit = defineEmits(['update:modelValue']); +const value = defineModel({ type: [String, Number, Object] }); const $props = defineProps({ - modelValue: { - type: [String, Number, Object], - default: null, - }, - options: { - type: Array, - default: () => [], - }, rolesAllowedToCreate: { type: Array, default: () => ['developer'], @@ -33,15 +24,6 @@ const $props = defineProps({ const role = useRole(); const showForm = ref(false); -const value = computed({ - get() { - return $props.modelValue; - }, - set(value) { - emit('update:modelValue', value); - }, -}); - const isAllowedToCreate = computed(() => { return role.hasAny($props.rolesAllowedToCreate); }); @@ -52,7 +34,11 @@ const toggleForm = () => { </script> <template> - <VnSelect v-model="value" :options="options" v-bind="$attrs"> + <VnSelect + v-model="value" + v-bind="$attrs" + @update:model-value="(...args) => emit('update:modelValue', ...args)" + > <template v-if="isAllowedToCreate" #append> <QIcon @click.stop.prevent="toggleForm()" diff --git a/src/components/common/VnTitle.vue b/src/components/common/VnTitle.vue index 29b4059f8..1fbd43972 100644 --- a/src/components/common/VnTitle.vue +++ b/src/components/common/VnTitle.vue @@ -7,7 +7,7 @@ defineProps({ </script> <template> <div :class="$q.screen.gt.md ? 'q-pb-lg' : 'q-pb-md'"> - <div class="header-link"> + <div class="header-link" :style="{ cursor: url ? 'pointer' : 'default' }"> <a :href="url" :class="url ? 'link' : 'color-vn-text'"> {{ text }} <QIcon v-if="url" :name="icon" /> diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue index 7792ed2cd..90ac856e5 100644 --- a/src/components/ui/CardDescriptor.vue +++ b/src/components/ui/CardDescriptor.vue @@ -120,7 +120,7 @@ const toModule = computed(() => :icon="iconModule" color="white" class="link" - :to="toModule" + :to="$attrs['to-module'] ?? toModule" > <QTooltip> {{ t('globals.goToModuleIndex') }} diff --git a/src/components/ui/CatalogItem.vue b/src/components/ui/CatalogItem.vue index 5c5d71018..ef722483b 100644 --- a/src/components/ui/CatalogItem.vue +++ b/src/components/ui/CatalogItem.vue @@ -31,7 +31,7 @@ const dialog = ref(null); <div class="container order-catalog-item overflow-hidden"> <QCard class="card shadow-6"> <div class="img-wrapper"> - <VnImg :id="item.id" zoom-size="lg" class="image" /> + <VnImg :id="item.id" class="image" /> <div v-if="item.hex && isCatalog" class="item-color-container"> <div class="item-color" diff --git a/src/components/ui/QCalendarMonthWrapper.vue b/src/components/ui/QCalendarMonthWrapper.vue index bced893fe..fc383ed81 100644 --- a/src/components/ui/QCalendarMonthWrapper.vue +++ b/src/components/ui/QCalendarMonthWrapper.vue @@ -52,8 +52,8 @@ const containerClasses = computed(() => { --calendar-border-current: #84d0e2 2px solid; --calendar-current-color-dark: #84d0e2; // Colores de fondo del calendario en dark mode - --calendar-outside-background-dark: #222; - --calendar-background-dark: #222; + --calendar-outside-background-dark: var(--vn-section-color); + --calendar-background-dark: var(--vn-section-color); } // Clases para modificar el color de fecha seleccionada en componente QCalendarMonth @@ -70,8 +70,26 @@ const containerClasses = computed(() => { text-transform: capitalize; } +.q-calendar-month__head--workweek, +.q-calendar-month__head--weekday, +// .q-calendar-month__workweek.q-past-day, +.q-calendar-month__week :nth-child(n+6):nth-child(-n+7) { + color: var(--vn-label-color); +} + +.q-calendar-month__head--weekdays > div[aria-label='miércoles'] > span { + /* color: transparent; */ + visibility: hidden; + // position: absolute; +} +.q-calendar-month__head--weekdays > div[aria-label='miércoles'] > span:after { + content: 'X'; + visibility: visible; + left: 33%; + position: absolute; +} .transparent-background { - --calendar-background-dark: transparent; + // --calendar-background-dark: transparent; --calendar-background: transparent; --calendar-outside-background-dark: transparent; } @@ -110,11 +128,6 @@ const containerClasses = computed(() => { cursor: pointer; } } - .q-calendar-month__week--days > div:nth-child(6), - .q-calendar-month__week--days > div:nth-child(7) { - // Cambia el color de los días sábado y domingo - color: #777777; - } .q-calendar-month__week--wrapper { margin-bottom: 4px; @@ -124,6 +137,7 @@ const containerClasses = computed(() => { height: 32px; display: flex; justify-content: center; + color: var(--vn-label-color); } .q-calendar__button--bordered { @@ -147,7 +161,7 @@ const containerClasses = computed(() => { .q-calendar-month__head--workweek, .q-calendar-month__head--weekday.q-calendar__center.q-calendar__ellipsis { text-transform: capitalize; - color: $color-font-secondary; + color: var(--vn-label-color); font-weight: bold; font-size: 0.8rem; text-align: center; diff --git a/src/components/ui/VnAvatar.vue b/src/components/ui/VnAvatar.vue index 287f741e0..1deb105db 100644 --- a/src/components/ui/VnAvatar.vue +++ b/src/components/ui/VnAvatar.vue @@ -1,45 +1,62 @@ <script setup> -import { computed, ref } from 'vue'; +import { computed, ref, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { useSession } from 'src/composables/useSession'; import { useColor } from 'src/composables/useColor'; +import { getCssVar } from 'quasar'; const $props = defineProps({ workerId: { type: Number, required: true }, description: { type: String, default: null }, - size: { type: String, default: null }, title: { type: String, default: null }, + color: { type: String, default: null }, }); + const { getTokenMultimedia } = useSession(); const token = getTokenMultimedia(); const { t } = useI18n(); -const title = computed(() => $props.title ?? t('globals.system')); +const src = computed( + () => `/api/Images/user/160x160/${$props.workerId}/download?access_token=${token}` +); +const title = computed(() => $props.title?.toUpperCase() || t('globals.system')); const showLetter = ref(false); +const backgroundColor = computed(() => { + const color = $props.color || useColor(title.value); + return getCssVar(color) || color; +}); + +watch(src, () => (showLetter.value = false)); </script> <template> - <div class="avatar-picture column items-center"> + <div class="column items-center"> <QAvatar - :style="{ - backgroundColor: useColor(title), - }" - :size="$props.size" - :title="title" + :style="{ backgroundColor }" + v-bind="$attrs" + :title="title || t('globals.system')" > - <template v-if="showLetter">{{ title.charAt(0) }}</template> - <QImg - v-else - :src="`/api/Images/user/160x160/${$props.workerId}/download?access_token=${token}`" - spinner-color="white" - @error="showLetter = true" - /> + <template v-if="showLetter"> + {{ title.charAt(0) }} + </template> + <QImg v-else :src="src" spinner-color="white" @error="showLetter = true" /> </QAvatar> <div class="description"> - <slot name="description" v-if="$props.description"> - <p> - {{ $props.description }} - </p> + <slot name="description" v-if="description"> + <p v-text="description" /> </slot> </div> </div> </template> +<style lang="scss" scoped> +[size='xxl'] { + .q-avatar, + .q-img { + width: 80px; + height: 80px; + } + + .q-img { + object-fit: cover; + } +} +</style> diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index b93ca7121..9059605ca 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -37,7 +37,7 @@ const $props = defineProps({ }, hiddenTags: { type: Array, - default: () => ['filter'], + default: () => ['filter', 'search', 'or', 'and'], }, customTags: { type: Array, @@ -57,7 +57,7 @@ const $props = defineProps({ }, }); -defineExpose({ search }); +defineExpose({ search, sanitizer }); const emit = defineEmits([ 'update:modelValue', 'refresh', @@ -65,6 +65,7 @@ const emit = defineEmits([ 'search', 'init', 'remove', + 'setUserParams', ]); const arrayData = useArrayData($props.dataKey, { @@ -81,22 +82,26 @@ onMounted(() => { }); function setUserParams(watchedParams) { - if (!watchedParams) return; + if (!watchedParams || Object.keys(watchedParams).length == 0) return; if (typeof watchedParams == 'string') watchedParams = JSON.parse(watchedParams); + if (typeof watchedParams?.filter == 'string') + watchedParams.filter = JSON.parse(watchedParams.filter); + watchedParams = { ...watchedParams, ...watchedParams.filter?.where }; + const order = watchedParams.filter?.order; + delete watchedParams.filter; - userParams.value = { ...userParams.value, ...watchedParams }; + userParams.value = { ...userParams.value, ...sanitizer(watchedParams) }; + emit('setUserParams', userParams.value, order); } watch( - () => route.query[$props.searchUrl], - (val) => setUserParams(val) -); - -watch( - () => arrayData.store.userParams, - (val) => setUserParams(val) + () => [route.query[$props.searchUrl], arrayData.store.userParams], + ([newSearchUrl, newUserParams], [oldSearchUrl, oldUserParams]) => { + if (newSearchUrl || oldSearchUrl) setUserParams(newSearchUrl); + if (newUserParams || oldUserParams) setUserParams(newUserParams); + } ); watch( @@ -106,19 +111,23 @@ watch( const isLoading = ref(false); async function search(evt) { - if (evt && $props.disableSubmitEvent) return; + try { + if (evt && $props.disableSubmitEvent) return; - store.filter.where = {}; - isLoading.value = true; - const filter = { ...userParams.value }; - store.userParamsChanged = true; - const { params: newParams } = await arrayData.addFilter({ params: userParams.value }); - userParams.value = newParams; + store.filter.where = {}; + isLoading.value = true; + const filter = { ...userParams.value, ...$props.modelValue }; + store.userParamsChanged = true; + const { params: newParams } = await arrayData.addFilter({ + params: filter, + }); + userParams.value = newParams; - if (!$props.showAll && !Object.values(filter).length) store.data = []; - - isLoading.value = false; - emit('search'); + if (!$props.showAll && !Object.values(filter).length) store.data = []; + emit('search'); + } finally { + isLoading.value = false; + } } async function reload() { @@ -133,29 +142,31 @@ async function reload() { } async function clearFilters() { - isLoading.value = true; - store.userParamsChanged = true; - arrayData.reset(['skip', 'filter.skip', 'page']); - // Filtrar los params no removibles - const removableFilters = Object.keys(userParams.value).filter((param) => - $props.unRemovableParams.includes(param) - ); - const newParams = {}; - // Conservar solo los params que no son removibles - for (const key of removableFilters) { - newParams[key] = userParams.value[key]; - } - userParams.value = {}; - userParams.value = { ...newParams }; // Actualizar los params con los removibles - await arrayData.applyFilter({ params: userParams.value }); + try { + isLoading.value = true; + store.userParamsChanged = true; + arrayData.reset(['skip', 'filter.skip', 'page']); + // Filtrar los params no removibles + const removableFilters = Object.keys(userParams.value).filter((param) => + $props.unRemovableParams.includes(param) + ); + const newParams = {}; + // Conservar solo los params que no son removibles + for (const key of removableFilters) { + newParams[key] = userParams.value[key]; + } + userParams.value = {}; + userParams.value = { ...newParams }; // Actualizar los params con los removibles + await arrayData.applyFilter({ params: userParams.value }); - if (!$props.showAll) { - store.data = []; + if (!$props.showAll) { + store.data = []; + } + emit('clear'); + emit('update:modelValue', userParams.value); + } finally { + isLoading.value = false; } - - isLoading.value = false; - emit('clear'); - emit('update:modelValue', userParams.value); } const tagsList = computed(() => { @@ -188,6 +199,16 @@ function formatValue(value) { return `"${value}"`; } + +function sanitizer(params) { + for (const [key, value] of Object.entries(params)) { + if (typeof value == 'object') { + const param = Object.values(value)[0]; + if (typeof param == 'string') params[key] = param.replaceAll('%', ''); + } + } + return params; +} </script> <template> @@ -270,7 +291,7 @@ function formatValue(value) { <QSeparator /> </QList> <QList dense class="list q-gutter-y-sm q-mt-sm"> - <slot name="body" :params="userParams" :search-fn="search"></slot> + <slot name="body" :params="sanitizer(userParams)" :search-fn="search"></slot> </QList> </QForm> <QInnerLoading diff --git a/src/components/ui/VnImg.vue b/src/components/ui/VnImg.vue index 985c9cc53..9585b81d8 100644 --- a/src/components/ui/VnImg.vue +++ b/src/components/ui/VnImg.vue @@ -1,6 +1,8 @@ <script setup> -import { ref, computed } from 'vue'; +import { ref } from 'vue'; import { useSession } from 'src/composables/useSession'; +import noImage from '/no-user.png'; +import { useRole } from 'src/composables/useRole'; const $props = defineProps({ storage: { @@ -11,14 +13,17 @@ const $props = defineProps({ type: String, default: 'catalog', }, - size: { + resolution: { type: String, default: '200x200', }, - zoomSize: { + zoomResolution: { type: String, - required: false, - default: 'lg', + default: null, + }, + zoom: { + type: Boolean, + default: true, }, id: { type: Number, @@ -28,14 +33,16 @@ const $props = defineProps({ const show = ref(false); const token = useSession().getTokenMultimedia(); const timeStamp = ref(`timestamp=${Date.now()}`); -import noImage from '/no-user.png'; -import { useRole } from 'src/composables/useRole'; -const url = computed(() => { - const isEmployee = useRole().isEmployee(); +const isEmployee = useRole().isEmployee(); + +const getUrl = (zoom = false) => { + const curResolution = zoom + ? $props.zoomResolution || $props.resolution + : $props.resolution; return isEmployee - ? `/api/${$props.storage}/${$props.collection}/${$props.size}/${$props.id}/download?access_token=${token}&${timeStamp.value}` + ? `/api/${$props.storage}/${$props.collection}/${curResolution}/${$props.id}/download?access_token=${token}&${timeStamp.value}` : noImage; -}); +}; const reload = () => { timeStamp.value = `timestamp=${Date.now()}`; }; @@ -45,23 +52,21 @@ defineExpose({ </script> <template> <QImg - :class="{ zoomIn: $props.zoomSize }" - :src="url" + :class="{ zoomIn: zoom }" + :src="getUrl()" v-bind="$attrs" - @click="show = !show" + @click.stop="show = $props.zoom ? true : false" spinner-color="primary" /> - <QDialog v-model="show" v-if="$props.zoomSize"> + <QDialog v-if="$props.zoom" v-model="show"> <QImg - :src="url" - size="full" - class="img_zoom" + :src="getUrl(true)" v-bind="$attrs" spinner-color="primary" + class="img_zoom" /> </QDialog> </template> - <style lang="scss" scoped> .q-img { &.zoomIn { diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue index f4cdde310..bf5e86a16 100644 --- a/src/components/ui/VnNotes.vue +++ b/src/components/ui/VnNotes.vue @@ -1,13 +1,18 @@ <script setup> -import VnAvatar from 'src/components/ui/VnAvatar.vue'; -import { toDateHourMin } from 'src/filters'; -import { ref } from 'vue'; import axios from 'axios'; +import { ref } from 'vue'; +import { onBeforeRouteLeave } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import VnPaginate from './VnPaginate.vue'; -import VnUserLink from '../ui/VnUserLink.vue'; +import { useQuasar } from 'quasar'; + +import { toDateHourMin } from 'src/filters'; import { useState } from 'src/composables/useState'; +import VnPaginate from 'components/ui/VnPaginate.vue'; +import VnUserLink from 'components/ui/VnUserLink.vue'; +import VnConfirm from 'components/ui/VnConfirm.vue'; +import VnAvatar from 'components/ui/VnAvatar.vue'; + const $props = defineProps({ url: { type: String, default: null }, filter: { type: Object, default: () => {} }, @@ -17,6 +22,7 @@ const $props = defineProps({ const { t } = useI18n(); const state = useState(); +const quasar = useQuasar(); const currentUser = ref(state.getUser()); const newNote = ref(''); const vnPaginateRef = ref(); @@ -28,11 +34,24 @@ function handleKeyUp(event) { } async function insert() { const body = $props.body; - Object.assign(body, { text: newNote.value }); - await axios.post($props.url, body); + const newBody = { ...body, ...{ text: newNote.value } }; + await axios.post($props.url, newBody); await vnPaginateRef.value.fetch(); newNote.value = ''; } + +onBeforeRouteLeave((to, from, next) => { + if (newNote.value) + quasar.dialog({ + component: VnConfirm, + componentProps: { + title: t('globals.unsavedPopup.title'), + message: t('globals.unsavedPopup.subtitle'), + promise: () => next(), + }, + }); + else next(); +}); </script> <template> <QCard class="q-pa-xs q-mb-xl full-width" v-if="$props.addNote"> diff --git a/src/components/ui/VnOutForm.vue b/src/components/ui/VnOutForm.vue new file mode 100644 index 000000000..e7ad441d0 --- /dev/null +++ b/src/components/ui/VnOutForm.vue @@ -0,0 +1,32 @@ +<script setup> +const emit = defineEmits(['submit']); +defineProps({ + icon: { type: String, required: false, default: 'phonelink_lock' }, + title: { type: String, required: true }, +}); +</script> +<template> + <QForm @submit="emit('submit')" class="q-gutter-y-md q-pa-lg formCard"> + <div class="column items-center"> + <QIcon v-if="icon != false" :name="icon" size="xl" color="primary" /> + <h5 class="text-center q-my-md"> + {{ title }} + </h5> + </div> + <slot></slot> + <div class="q-mt-lg"> + <slot name="buttons"></slot> + </div> + </QForm> +</template> +<style lang="scss" scoped> +.formCard { + max-width: 350px; + min-width: 300px; +} +@media (max-width: $breakpoint-xs-max) { + .formCard { + min-width: 100%; + } +} +</style> diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue index fd903e759..0df719c66 100644 --- a/src/components/ui/VnPaginate.vue +++ b/src/components/ui/VnPaginate.vue @@ -115,8 +115,8 @@ watch( ); watch( - () => props.url, - (url) => fetch({ url }) + () => [props.url, props.filter], + ([url, filter]) => mounted.value && fetch({ url, filter }) ); const addFilter = async (filter, params) => { @@ -221,7 +221,7 @@ defineExpose({ fetch, addFilter, paginate }); > <slot name="body" :rows="store.data"></slot> <div v-if="isLoading" class="info-row q-pa-md text-center"> - <QSpinner color="orange" size="md" /> + <QSpinner color="primary" size="md" /> </div> </QInfiniteScroll> </template> diff --git a/src/components/ui/VnRow.vue b/src/components/ui/VnRow.vue index a2f89ff3f..34cdf88b8 100644 --- a/src/components/ui/VnRow.vue +++ b/src/components/ui/VnRow.vue @@ -1,14 +1,17 @@ <template> <div class="vn-row q-gutter-md q-mb-md"> - <slot></slot> + <slot /> </div> </template> -<style lang="scss" scopped> +<style lang="scss" scoped> .vn-row { display: flex; - > * { + > :deep(*) { flex: 1; } + &[wrap] { + flex-wrap: wrap; + } } @media screen and (max-width: 800px) { .vn-row { diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index 0c7a8a3f6..8af3480c9 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -67,6 +67,10 @@ const props = defineProps({ type: Boolean, default: true, }, + searchUrl: { + type: String, + default: 'params', + }, }); const searchText = ref(''); @@ -100,9 +104,7 @@ onMounted(() => { }); async function search() { - const staticParams = Object.entries(store.userParams).filter( - ([key, value]) => value && (props.staticParams || []).includes(key) - ); + const staticParams = Object.entries(store.userParams); arrayData.reset(['skip', 'page']); if (props.makeFetch) diff --git a/src/components/ui/VnSms.vue b/src/components/ui/VnSms.vue index ceb24b2bb..bf6e0695e 100644 --- a/src/components/ui/VnSms.vue +++ b/src/components/ui/VnSms.vue @@ -1,5 +1,5 @@ <script setup> -import { onBeforeMount } from 'vue'; +import { computed } from 'vue'; import { date } from 'quasar'; import VnPaginate from 'src/components/ui/VnPaginate.vue'; import VnAvatar from '../ui/VnAvatar.vue'; @@ -10,31 +10,32 @@ const $props = defineProps({ where: { type: Object, default: () => {} }, }); -const filter = { - fields: ['smsFk'], - include: { - relation: 'sms', - scope: { - fields: [ - 'senderFk', - 'sender', - 'destination', - 'message', - 'statusCode', - 'status', - 'created', - ], - include: { - relation: 'sender', - scope: { - fields: ['name'], +const filter = computed(() => { + return { + fields: ['smsFk'], + include: { + relation: 'sms', + scope: { + fields: [ + 'senderFk', + 'sender', + 'destination', + 'message', + 'statusCode', + 'status', + 'created', + ], + include: { + relation: 'sender', + scope: { + fields: ['name'], + }, }, }, }, - }, -}; - -onBeforeMount(() => (filter.where = $props.where)); + ...{ where: $props.where }, + }; +}); function formatNumber(number) { if (number.length <= 10) return number; diff --git a/src/components/ui/VnSubToolbar.vue b/src/components/ui/VnSubToolbar.vue index 5e2412437..5ded4be00 100644 --- a/src/components/ui/VnSubToolbar.vue +++ b/src/components/ui/VnSubToolbar.vue @@ -43,20 +43,9 @@ onBeforeUnmount(() => stateStore.toggleSubToolbar()); </slot> </QToolbar> </template> -<style lang="scss"> -.q-toolbar { - background: var(--vn-section-color); -} -</style> <style lang="scss" scoped> .sticky { position: sticky; - top: 61px; z-index: 1; } -@media (max-width: $breakpoint-sm) { - .sticky { - top: 90px; - } -} </style> diff --git a/src/components/ui/VnUserLink.vue b/src/components/ui/VnUserLink.vue index 33836550a..b04ea7476 100644 --- a/src/components/ui/VnUserLink.vue +++ b/src/components/ui/VnUserLink.vue @@ -18,4 +18,3 @@ const { t } = useI18n(); </slot> <WorkerDescriptorProxy v-if="$props.workerId" :id="$props.workerId" /> </template> -<style scoped></style> diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index 50d620a34..651bcefb0 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -28,7 +28,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) { delete params.filter; store.userParams = { ...params, ...store.userParams }; store.userFilter = { ...filter, ...store.userFilter }; - if (filter.order) store.order = filter.order; + if (filter?.order) store.order = filter.order; } }); diff --git a/src/composables/useSession.js b/src/composables/useSession.js index 10791c9c8..633a30bb0 100644 --- a/src/composables/useSession.js +++ b/src/composables/useSession.js @@ -3,12 +3,14 @@ import { useRole } from './useRole'; import { useAcl } from './useAcl'; import { useUserConfig } from './useUserConfig'; import axios from 'axios'; +import { useRouter } from 'vue-router'; import useNotify from './useNotify'; import { useTokenConfig } from './useTokenConfig'; const TOKEN_MULTIMEDIA = 'tokenMultimedia'; const TOKEN = 'token'; export function useSession() { + const router = useRouter(); const { notify } = useNotify(); let isCheckingToken = false; let intervalId = null; @@ -102,6 +104,31 @@ export function useSession() { startInterval(); } + async function setLogin(data) { + const { + data: { multimediaToken }, + } = await axios.get('VnUsers/ShareToken', { + headers: { Authorization: data.token }, + }); + + if (!multimediaToken) return; + + await login({ + ...data, + created: Date.now(), + tokenMultimedia: multimediaToken.id, + }); + + notify('login.loginSuccess', 'positive'); + + const currentRoute = router.currentRoute.value; + if (currentRoute.query?.redirect) { + router.push(currentRoute.query.redirect); + } else { + router.push({ name: 'Dashboard' }); + } + } + function isLoggedIn() { const localToken = localStorage.getItem(TOKEN); const sessionToken = sessionStorage.getItem(TOKEN); @@ -163,6 +190,7 @@ export function useSession() { setToken, destroy, login, + setLogin, isLoggedIn, checkValidity, setSession, diff --git a/src/css/app.scss b/src/css/app.scss index 504718ff5..c233b14f0 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -153,6 +153,12 @@ select:-webkit-autofill { background-color: var(--vn-section-color); } +.q-table td[shrink] { + text-overflow: ellipsis; + overflow: hidden; + max-width: 80px; +} + .tr-header { color: var(--vn-label-color); } @@ -184,15 +190,12 @@ select:-webkit-autofill { font-size: medium; } -.q-card__actions { - justify-content: center; +.q-toolbar { + background: var(--vn-section-color); } -.q-card, -.q-table, -.q-table__bottom, -.q-drawer { - background-color: var(--vn-section-color); +.q-card__actions { + justify-content: center; } input[type='number'] { @@ -209,51 +212,59 @@ input::-webkit-inner-spin-button { max-width: 100%; } -/* ===== Scrollbar CSS ===== / -/ Firefox */ +.q-table__container { + /* ===== Scrollbar CSS ===== / + / Firefox */ -* { - scrollbar-width: auto; - scrollbar-color: var(--vn-label-color) transparent; -} + * { + scrollbar-width: auto; + scrollbar-color: var(--vn-label-color) transparent; + } -/* Chrome, Edge, and Safari */ -*::-webkit-scrollbar { - width: 10px; - height: 10px; -} + /* Chrome, Edge, and Safari */ + *::-webkit-scrollbar { + width: 10px; + height: 10px; + } -*::-webkit-scrollbar-thumb { - background-color: var(--vn-label-color); - border-radius: 10px; -} + *::-webkit-scrollbar-thumb { + background-color: var(--vn-label-color); + border-radius: 10px; + } -*::-webkit-scrollbar-track { - background: transparent; + *::-webkit-scrollbar-track { + background: transparent; + } } .q-table { - thead, - tbody { - th { - .q-select { - max-width: 120px; - } - } - td { - padding: 1px 10px 1px 10px; - max-width: 100px; - div span { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } + th, + td { + padding: 1px 10px 1px 10px; + max-width: 100px; + div span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } - .expand { - max-width: 400px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + tr { + th { + font-size: 11pt; + } + td { + font-size: 11pt; + border-top: 1px solid var(--vn-page-color); + border-collapse: collapse; } } + .shrink { + max-width: 75px; + } + .expand { + max-width: 400px; + } } diff --git a/src/filters/getParamWhere.js b/src/filters/getParamWhere.js new file mode 100644 index 000000000..48cd9c479 --- /dev/null +++ b/src/filters/getParamWhere.js @@ -0,0 +1,21 @@ +// parsing JSON safely +function parseJSON(str, fallback) { + try { + return JSON.parse(str ?? '{}'); + } catch (e) { + console.error('Error parsing JSON:', e); + return fallback; + } +} +export default function (route, param) { + // catch route query params + const params = parseJSON(route?.query?.params, {}); + + // extract and parse filter from params + const { filter: filterStr = '{}' } = params; + const where = parseJSON(filterStr, {})?.where; + if (where && where[param] !== undefined) { + return where[param]; + } + return null; +} diff --git a/src/filters/index.js b/src/filters/index.js index 940788ed1..5f08f19c7 100644 --- a/src/filters/index.js +++ b/src/filters/index.js @@ -11,6 +11,7 @@ import dashIfEmpty from './dashIfEmpty'; import dateRange from './dateRange'; import toHour from './toHour'; import dashOrCurrency from './dashOrCurrency'; +import getParamWhere from './getParamWhere'; export { toLowerCase, @@ -26,4 +27,5 @@ export { toPercentage, dashIfEmpty, dateRange, + getParamWhere, }; diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 9bcb3f921..1de826d6f 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -91,6 +91,10 @@ globals: salesPerson: SalesPerson send: Send code: Code + since: Since + from: From + to: To + notes: Notes pageTitles: logIn: Login summary: Summary @@ -247,6 +251,11 @@ globals: mailForwarding: Mail forwarding mailAlias: Mail alias privileges: Privileges + ldap: LDAP + samba: Samba + twoFactor: Two factor + recoverPassword: Recover password + resetPassword: Reset password created: Created worker: Worker now: Now @@ -255,6 +264,11 @@ globals: comment: Comment observations: Observations goToModuleIndex: Go to module index + unsavedPopup: + title: Unsaved changes will be lost + subtitle: Are you sure exit without saving? + createInvoiceIn: Create invoice in + myAccount: My account errors: statusUnauthorized: Access denied statusInternalServerError: An internal server error has ocurred @@ -280,14 +294,17 @@ twoFactor: explanation: >- Please, enter the verification code that we have sent to your email in the next 5 minutes - pageTitles: - twoFactor: Two-Factor verifyEmail: pageTitles: verifyEmail: Email verification -dashboard: - pageTitles: - +recoverPassword: + userOrEmail: User or recovery email + explanation: >- + We will sent you an email to recover your password +resetPassword: + repeatPassword: Repeat password + passwordNotMatch: Passwords don't match + passwordChanged: Password changed customer: list: phone: Phone @@ -387,8 +404,8 @@ customer: extendedList: tableVisibleColumns: id: Identifier - name: Comercial name - socialName: Business name + name: Name + socialName: Social name fi: Tax number salesPersonFk: Salesperson credit: Credit @@ -998,18 +1015,6 @@ route: shipped: Preparation date viewCmr: View CMR downloadCmrs: Download CMRs - columnLabels: - Id: Id - vehicle: Vehicle - description: Description - isServed: Served - worker: Worker - date: Date - started: Started - actions: Actions - agency: Agency - volume: Volume - finished: Finished supplier: list: payMethod: Pay method diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 229cb1e27..a5676ad7e 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -93,6 +93,10 @@ globals: salesPerson: Comercial send: Enviar code: Código + since: Desde + from: Desde + to: Hasta + notes: Notas pageTitles: logIn: Inicio de sesión summary: Resumen @@ -251,6 +255,11 @@ globals: components: Componentes pictures: Fotos packages: Bultos + ldap: LDAP + samba: Samba + twoFactor: Doble factor + recoverPassword: Recuperar contraseña + resetPassword: Restablecer contraseña created: Fecha creación worker: Trabajador now: Ahora @@ -259,6 +268,11 @@ globals: comment: Comentario observations: Observaciones goToModuleIndex: Ir al índice del módulo + unsavedPopup: + title: Los cambios que no haya guardado se perderán + subtitle: ¿Seguro que quiere salir sin guardar? + createInvoiceIn: Crear factura recibida + myAccount: Mi cuenta errors: statusUnauthorized: Acceso denegado statusInternalServerError: Ha ocurrido un error interno del servidor @@ -282,14 +296,17 @@ twoFactor: validate: Validar insert: Introduce el código de verificación explanation: Por favor introduce el código de verificación que te hemos enviado a tu email en los próximos 5 minutos - pageTitles: - twoFactor: Doble factor verifyEmail: pageTitles: verifyEmail: Verificación de correo -dashboard: - pageTitles: - +recoverPassword: + userOrEmail: Usuario o correo de recuperación + explanation: >- + Te enviaremos un correo para restablecer tu contraseña +resetPassword: + repeatPassword: Repetir contraseña + passwordNotMatch: Las contraseñas no coinciden + passwordChanged: Contraseña cambiada customer: list: phone: Teléfono @@ -388,7 +405,7 @@ customer: extendedList: tableVisibleColumns: id: Identificador - name: Nombre Comercial + name: Nombre socialName: Razón social fi: NIF / CIF salesPersonFk: Comercial @@ -695,8 +712,6 @@ invoiceOut: percentageText: '{getPercentage}% {getAddressNumber} de {getNAddresses}' pdfsNumberText: '{nPdfs} de {totalPdfs} PDFs' negativeBases: - from: Desde - to: Hasta company: Empresa country: País clientId: Id cliente @@ -871,7 +886,7 @@ worker: card: workerId: ID Trabajador name: Nombre - email: Email + email: Correo personal phone: Teléfono mobile: Móvil active: Activo @@ -981,18 +996,6 @@ route: shipped: Fecha preparación viewCmr: Ver CMR downloadCmrs: Descargar CMRs - columnLabels: - Id: Id - vehicle: Vehículo - description: Descripción - isServed: Servida - worker: Trabajador - date: Fecha - started: Iniciada - actions: Acciones - agency: Agencia - volume: Volumen - finished: Finalizada supplier: list: payMethod: Método de pago @@ -1250,8 +1253,6 @@ components: # LatestBuysFilter salesPersonFk: Comprador supplierFk: Proveedor - from: Desde - to: Hasta active: Activo visible: Visible floramondo: Floramondo diff --git a/src/pages/Account/AccountAccounts.vue b/src/pages/Account/AccountAccounts.vue index 3d7dda899..9cc282551 100644 --- a/src/pages/Account/AccountAccounts.vue +++ b/src/pages/Account/AccountAccounts.vue @@ -1,11 +1,9 @@ <script setup> import { useI18n } from 'vue-i18n'; - import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnInput from 'src/components/common/VnInput.vue'; - import axios from 'axios'; import useNotify from 'src/composables/useNotify.js'; diff --git a/src/pages/Account/AccountAcls.vue b/src/pages/Account/AccountAcls.vue index bd7f0f9ae..110358e7f 100644 --- a/src/pages/Account/AccountAcls.vue +++ b/src/pages/Account/AccountAcls.vue @@ -1,19 +1,14 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { ref } from 'vue'; -import FetchData from 'components/FetchData.vue'; - -import VnPaginate from 'components/ui/VnPaginate.vue'; -import VnSearchbar from 'components/ui/VnSearchbar.vue'; -import CardList from 'src/components/ui/CardList.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import AclFilter from './Acls/AclFilter.vue'; -import AclFormView from './Acls/AclFormView.vue'; - -import { useVnConfirm } from 'composables/useVnConfirm'; +import { ref, computed } from 'vue'; import { useStateStore } from 'stores/useStateStore'; import axios from 'axios'; import useNotify from 'src/composables/useNotify.js'; +import { useQuasar } from 'quasar'; + +import VnTable from 'components/VnTable/VnTable.vue'; +import VnSearchbar from 'components/ui/VnSearchbar.vue'; +import VnConfirm from 'components/ui/VnConfirm.vue'; defineProps({ id: { @@ -25,11 +20,9 @@ defineProps({ const { notify } = useNotify(); const { t } = useI18n(); const stateStore = useStateStore(); -const { openConfirmationModal } = useVnConfirm(); +const quasar = useQuasar(); -const paginateRef = ref(); -const formDialog = ref(false); -const rolesOptions = ref([]); +const tableRef = ref(); const exprBuilder = (param, value) => { switch (param) { @@ -40,106 +33,120 @@ const exprBuilder = (param, value) => { } }; -const deleteAcl = async (id) => { +const columns = computed(() => [ + { + align: 'left', + name: 'id', + label: t('id'), + isId: true, + cardVisible: true, + }, + { + align: 'left', + name: 'model', + label: t('model'), + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'principalId', + label: t('principalId'), + cardVisible: true, + component: 'select', + attrs: { + url: 'VnRoles', + optionLabel: 'name', + optionValue: 'name', + }, + create: true, + }, + { + align: 'left', + name: 'property', + label: t('property'), + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'accessType', + label: t('accessType'), + component: 'select', + attrs: { + options: ['READ', 'WRITE', '*'], + }, + cardVisible: true, + create: true, + }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('Delete'), + icon: 'delete', + action: deleteAcl, + isPrimary: true, + }, + ], + }, +]); +const deleteAcl = async ({ id }) => { try { + await new Promise((resolve) => { + quasar + .dialog({ + component: VnConfirm, + componentProps: { + title: t('Remove ACL'), + message: t('Do you want to remove this ACL?'), + }, + }) + .onOk(() => { + resolve(true); + }) + .onCancel(() => { + resolve(false); + }); + }); await axios.delete(`ACLs/${id}`); - paginateRef.value.fetch(); + tableRef.value.reload(); notify('ACL removed', 'positive'); } catch (error) { console.error('Error deleting Acl: ', error); } }; -function showFormDialog(data) { - formDialog.value = { - show: true, - formInitialData: { ...data }, - }; -} </script> <template> - <FetchData - url="VnRoles" - :filter="{ fields: ['name'], order: 'name ASC' }" - @on-fetch="(data) => (rolesOptions = data)" - auto-load + <VnSearchbar + data-key="AccountAcls" + url="ACLs" + :expr-builder="exprBuilder" + :label="t('acls.search')" + :info="t('acls.searchInfo')" /> - <template v-if="stateStore.isHeaderMounted()"> - <Teleport to="#searchbar"> - <VnSearchbar - data-key="AccountAcls" - url="ACLs" - :expr-builder="exprBuilder" - :label="t('acls.search')" - :info="t('acls.searchInfo')" - /> - </Teleport> - </template> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> - <QScrollArea class="fit text-grey-8"> - <AclFilter data-key="AccountAcls" /> - </QScrollArea> </QDrawer> - - <QPage class="flex justify-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - ref="paginateRef" - data-key="AccountAcls" - url="ACLs" - :expr-builder="exprBuilder" - > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :id="row.id" - :key="row.id" - :title="`${row.model}.${row.property}`" - @click="showFormDialog(row)" - > - <template #list-items> - <VnLv :label="t('acls.role')" :value="row.principalId" /> - <VnLv :label="t('acls.accessType')" :value="row.accessType" /> - <VnLv - :label="t('acls.permissions')" - :value="row.permission" - /> - </template> - <template #actions> - <QBtn - :label="t('globals.delete')" - @click.stop=" - openConfirmationModal( - t('ACL will be removed'), - t('Are you sure you want to continue?'), - () => deleteAcl(row.id) - ) - " - color="primary" - style="margin-top: 15px" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - <QDialog - v-model="formDialog.show" - transition-show="scale" - transition-hide="scale" - > - <AclFormView - :form-initial-data="formDialog.formInitialData" - @on-data-change="paginateRef.fetch()" - :roles-options="rolesOptions" - /> - </QDialog> - <QPageSticky position="bottom-right" :offset="[18, 18]"> - <QBtn fab icon="add" color="primary" @click="showFormDialog()"> - <QTooltip class="text-no-wrap">{{ t('New ACL') }}</QTooltip> - </QBtn> - </QPageSticky> - </QPage> + <VnTable + ref="tableRef" + data-key="AccountAcls" + :url="`ACLs`" + :create="{ + urlCreate: 'ACLs', + title: 'Create ACL', + onDataSaved: () => tableRef.reload(), + formInitialData: {}, + }" + order="id DESC" + :columns="columns" + default-mode="table" + :right-search="true" + :is-editable="true" + :use-model="true" + /> </template> <i18n> @@ -148,4 +155,17 @@ es: ACL removed: ACL eliminado ACL will be removed: El ACL será eliminado Are you sure you want to continue?: ¿Seguro que quieres continuar? + Remove ACL: Eliminar Acl + Do you want to remove this ACL?: ¿Quieres eliminar este ACL? + principalId: Rol + model: Modelo +en: + New ACL: New ACL + ACL removed: ACL removed + ACL will be removed: ACL will be removed + Are you sure you want to continue?: Are you sure you want to continue? + Remove ACL: Remove ACL + Do you want to remove this ACL?: Do you want to remove this ACL? + principalId: Rol + model: Models </i18n> diff --git a/src/pages/Account/AccountAliasList.vue b/src/pages/Account/AccountAliasList.vue index 29e8d4d78..b6f7b219c 100644 --- a/src/pages/Account/AccountAliasList.vue +++ b/src/pages/Account/AccountAliasList.vue @@ -1,30 +1,13 @@ <script setup> -import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import { ref } from 'vue'; - -import VnPaginate from 'components/ui/VnPaginate.vue'; +import { ref, computed } from 'vue'; +import VnTable from 'components/VnTable/VnTable.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue'; -import CardList from 'src/components/ui/CardList.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import AliasSummary from './Alias/Card/AliasSummary.vue'; -import AliasCreateForm from './Alias/AliasCreateForm.vue'; - -import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { useStateStore } from 'stores/useStateStore'; -defineProps({ - id: { - type: Number, - default: 0, - }, -}); - +const tableRef = ref(); const { t } = useI18n(); -const { viewSummary } = useSummaryDialog(); -const router = useRouter(); const stateStore = useStateStore(); -const aliasCreateDialogRef = ref(null); const exprBuilder = (param, value) => { switch (param) { @@ -34,10 +17,32 @@ const exprBuilder = (param, value) => { : { alias: { like: `%${value}%` } }; } }; - -const navigate = (id) => router.push({ name: 'AliasSummary', params: { id } }); - -const openCreateModal = () => aliasCreateDialogRef.value.show(); +const columns = computed(() => [ + { + align: 'left', + name: 'id', + label: t('id'), + isId: true, + field: 'id', + cardVisible: true, + }, + { + align: 'left', + name: 'alias', + label: t('alias'), + field: 'alias', + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'description', + label: t('description'), + field: 'description', + cardVisible: true, + create: true, + }, +]); </script> <template> @@ -52,54 +57,21 @@ const openCreateModal = () => aliasCreateDialogRef.value.show(); /> </Teleport> </template> - <QPage class="flex justify-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - ref="paginateRef" - data-key="AccountAliasList" - url="MailAliases" - :expr-builder="exprBuilder" - > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :id="row.id" - :key="row.id" - :title="row.alias" - @click="navigate(row.id)" - > - <template #list-items> - <VnLv :label="t('mailAlias.alias')" :value="row.alias"> - </VnLv> - <VnLv - :label="t('mailAlias.description')" - :value="row.description" - > - </VnLv> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, AliasSummary)" - color="primary" - style="margin-top: 15px" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - <QDialog - ref="aliasCreateDialogRef" - transition-show="scale" - transition-hide="scale" - > - <AliasCreateForm /> - </QDialog> - <QPageSticky position="bottom-right" :offset="[18, 18]"> - <QBtn fab icon="add" color="primary" @click="openCreateModal()"> - <QTooltip class="text-no-wrap">{{ t('mailAlias.newAlias') }}</QTooltip> - </QBtn> - </QPageSticky> - </QPage> + <VnTable + ref="tableRef" + data-key="AccountAliasList" + url="MailAliases" + :create="{ + urlCreate: 'MailAliases', + title: 'Create MailAlias', + onDataSaved: ({ id }) => tableRef.redirect(id), + formInitialData: {}, + }" + order="id DESC" + :columns="columns" + default-mode="table" + redirect="account/alias" + :is-editable="true" + :use-model="true" + /> </template> diff --git a/src/pages/Account/AccountConnections.vue b/src/pages/Account/AccountConnections.vue index 98208e5f2..4d3450665 100644 --- a/src/pages/Account/AccountConnections.vue +++ b/src/pages/Account/AccountConnections.vue @@ -2,11 +2,9 @@ import { ref } from 'vue'; import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; - import VnPaginate from 'components/ui/VnPaginate.vue'; import CardList from 'src/components/ui/CardList.vue'; import VnLv from 'src/components/ui/VnLv.vue'; - import { toDateTimeFormat } from 'src/filters/date.js'; import axios from 'axios'; import useNotify from 'src/composables/useNotify.js'; diff --git a/src/pages/Account/AccountCreate.vue b/src/pages/Account/AccountCreate.vue index 1c0f9fee6..e584a1acd 100644 --- a/src/pages/Account/AccountCreate.vue +++ b/src/pages/Account/AccountCreate.vue @@ -2,7 +2,6 @@ import { reactive, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; - import FormModelPopup from 'components/FormModelPopup.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import FetchData from 'components/FetchData.vue'; @@ -15,7 +14,6 @@ const newAccountForm = reactive({ active: true, }); const rolesOptions = ref([]); - const redirectToAccountBasicData = (_, { id }) => { router.push({ name: 'AccountBasicData', params: { id } }); }; diff --git a/src/pages/Account/AccountFilter.vue b/src/pages/Account/AccountFilter.vue index 784c925bc..1775aa06b 100644 --- a/src/pages/Account/AccountFilter.vue +++ b/src/pages/Account/AccountFilter.vue @@ -1,7 +1,6 @@ <script setup> import { ref } from 'vue'; import { useI18n } from 'vue-i18n'; - import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; diff --git a/src/pages/Account/AccountLdap.vue b/src/pages/Account/AccountLdap.vue index 77c4d89f8..7b8433e73 100644 --- a/src/pages/Account/AccountLdap.vue +++ b/src/pages/Account/AccountLdap.vue @@ -1,12 +1,10 @@ <script setup> import { ref, onMounted, computed } from 'vue'; import { useI18n } from 'vue-i18n'; - import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; - import { useArrayData } from 'src/composables/useArrayData'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; @@ -15,7 +13,6 @@ const { t } = useI18n(); const { notify } = useNotify(); const arrayData = useArrayData('AccountLdap'); - const URL_UPDATE = `LdapConfigs/${1}`; const URL_CREATE = `LdapConfigs`; const DEFAULT_DATA = { @@ -27,11 +24,9 @@ const DEFAULT_DATA = { server: null, userDn: null, }; - const initialData = ref({ ...DEFAULT_DATA, }); - const hasData = computed({ get: () => initialData.value.hasData, set: (val) => { @@ -40,12 +35,10 @@ const hasData = computed({ else formCustomFn.value = null; }, }); - const initialDataLoaded = ref(false); const formUrlCreate = ref(null); const formUrlUpdate = ref(null); const formCustomFn = ref(null); - const onTestConection = async () => { try { await axios.get(`LdapConfigs/test`); @@ -54,7 +47,6 @@ const onTestConection = async () => { console.error('Error testing connection', error); } }; - const getInitialLdapConfig = async () => { try { initialDataLoaded.value = false; @@ -79,7 +71,6 @@ const getInitialLdapConfig = async () => { initialDataLoaded.value = true; } }; - const deleteMailForward = async () => { try { await axios.delete(URL_UPDATE); diff --git a/src/pages/Account/AccountList.vue b/src/pages/Account/AccountList.vue index dee019fed..cdd88551b 100644 --- a/src/pages/Account/AccountList.vue +++ b/src/pages/Account/AccountList.vue @@ -1,33 +1,74 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; -import { computed, ref } from 'vue'; - -import VnPaginate from 'src/components/ui/VnPaginate.vue'; +import { ref, computed } from 'vue'; +import VnTable from 'components/VnTable/VnTable.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import CardList from 'src/components/ui/CardList.vue'; import AccountSummary from './Card/AccountSummary.vue'; -import AccountFilter from './AccountFilter.vue'; -import AccountCreate from './AccountCreate.vue'; - import { useSummaryDialog } from 'src/composables/useSummaryDialog'; -import { useStateStore } from 'stores/useStateStore'; -import { useRole } from 'src/composables/useRole'; -import { QDialog } from 'quasar'; -const stateStore = useStateStore(); -const router = useRouter(); const { t } = useI18n(); const { viewSummary } = useSummaryDialog(); -const accountCreateDialogRef = ref(null); -const showNewUserBtn = computed(() => useRole().hasAny(['itManagement'])); - -const filter = { - fields: ['id', 'nickname', 'name', 'role'], - include: { relation: 'role', scope: { fields: ['id', 'name'] } }, -}; +const tableRef = ref(); +const columns = computed(() => [ + { + align: 'left', + name: 'id', + label: t('id'), + isId: true, + field: 'id', + cardVisible: true, + }, + { + align: 'left', + name: 'username', + label: t('nickname'), + isTitle: true, + component: 'input', + columnField: { + component: null, + }, + columnFilter: { + inWhere: true, + }, + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'name', + label: t('name'), + component: 'input', + columnField: { + component: null, + }, + columnFilter: { + inWhere: true, + }, + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'email', + label: t('email'), + component: 'input', + create: true, + visible: false, + }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('View Summary'), + icon: 'preview', + action: (row) => viewSummary(row.id, AccountSummary), + }, + ], + }, +]); const exprBuilder = (param, value) => { switch (param) { case 'search': @@ -46,99 +87,24 @@ const exprBuilder = (param, value) => { return { [param]: value }; } }; - -const getApiUrl = () => new URL(window.location).origin; - -const navigate = (event, id) => { - if (event.ctrlKey || event.metaKey) - return window.open(`${getApiUrl()}/#/account/${id}/summary`); - router.push({ path: `/account/${id}` }); -}; - -const openCreateModal = () => accountCreateDialogRef.value.show(); </script> <template> - <template v-if="stateStore.isHeaderMounted()"> - <Teleport to="#searchbar"> - <VnSearchbar - data-key="AccountList" - url="VnUsers/preview" - :expr-builder="exprBuilder" - :label="t('account.search')" - :info="t('account.searchInfo')" - /> - </Teleport> - <Teleport to="#actions-append"> - <div class="row q-gutter-x-sm"> - <QBtn - flat - @click="stateStore.toggleRightDrawer()" - round - dense - icon="menu" - > - <QTooltip bottom anchor="bottom right"> - {{ t('globals.collapseMenu') }} - </QTooltip> - </QBtn> - </div> - </Teleport> - </template> - <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> - <QScrollArea class="fit text-grey-8"> - <AccountFilter data-key="AccountList" :expr-builder="exprBuilder" /> - </QScrollArea> - </QDrawer> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - :filter="filter" - data-key="AccountList" - url="VnUsers/preview" - auto-load - > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :id="row.id" - :key="row.id" - :title="row.nickname" - @click="navigate($event, row.id)" - > - <template #list-items> - <VnLv :label="t('account.card.name')" :value="row.nickname"> - </VnLv> - <VnLv - :label="t('account.card.nickname')" - :value="row.username" - > - </VnLv> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, AccountSummary)" - color="primary" - style="margin-top: 15px" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - <QDialog - ref="accountCreateDialogRef" - transition-hide="scale" - transition-show="scale" - > - <AccountCreate /> - </QDialog> - <QPageSticky :offset="[20, 20]" v-if="showNewUserBtn"> - <QBtn @click="openCreateModal" color="primary" fab icon="add" /> - <QTooltip class="text-no-wrap"> - {{ t('account.card.newUser') }} - </QTooltip> - </QPageSticky> - </QPage> + <VnSearchbar + data-key="AccountUsers" + :expr-builder="exprBuilder" + :label="t('account.search')" + :info="t('account.searchInfo')" + /> + + <VnTable + ref="tableRef" + data-key="AccountUsers" + url="VnUsers/preview" + order="id DESC" + :columns="columns" + default-mode="table" + redirect="account" + :use-model="true" + /> </template> diff --git a/src/pages/Account/AccountMain.vue b/src/pages/Account/AccountMain.vue deleted file mode 100644 index f0dc2e500..000000000 --- a/src/pages/Account/AccountMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Account/AccountSamba.vue b/src/pages/Account/AccountSamba.vue index 25428a674..7af9f4364 100644 --- a/src/pages/Account/AccountSamba.vue +++ b/src/pages/Account/AccountSamba.vue @@ -1,23 +1,18 @@ <script setup> import { ref, onMounted, computed } from 'vue'; import { useI18n } from 'vue-i18n'; - import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; - import { useArrayData } from 'src/composables/useArrayData'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; const { t } = useI18n(); const { notify } = useNotify(); - const arrayData = useArrayData('AccountSamba'); - const formModel = ref(null); - const URL_UPDATE = `SambaConfigs/${1}`; const URL_CREATE = `SambaConfigs`; diff --git a/src/pages/Account/Alias/AliasCreateForm.vue b/src/pages/Account/Alias/AliasCreateForm.vue index d4d61a804..b21099555 100644 --- a/src/pages/Account/Alias/AliasCreateForm.vue +++ b/src/pages/Account/Alias/AliasCreateForm.vue @@ -34,12 +34,12 @@ const onDataSaved = ({ id }) => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput v-model="data.alias" :label="t('mailAlias.name')" /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput v-model="data.description" diff --git a/src/pages/Account/Alias/Card/AliasCard.vue b/src/pages/Account/Alias/Card/AliasCard.vue index f5103cf03..65951b3bf 100644 --- a/src/pages/Account/Alias/Card/AliasCard.vue +++ b/src/pages/Account/Alias/Card/AliasCard.vue @@ -1,22 +1,8 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; -import { computed } from 'vue'; - import VnCard from 'components/common/VnCard.vue'; import AliasDescriptor from './AliasDescriptor.vue'; - const { t } = useI18n(); -const route = useRoute(); - -const routeName = computed(() => route.name); -const customRouteRedirectName = computed(() => { - return routeName.value; -}); -const searchBarDataKeys = { - AliasBasicData: 'AliasBasicData', - AliasUsers: 'AliasUsers', -}; </script> <template> @@ -24,10 +10,12 @@ const searchBarDataKeys = { data-key="Alias" base-url="MailAliases" :descriptor="AliasDescriptor" - :search-data-key="searchBarDataKeys[routeName]" - :search-custom-route-redirect="customRouteRedirectName" - :search-redirect="!!customRouteRedirectName" - :searchbar-label="t('mailAlias.search')" - :searchbar-info="t('mailAlias.searchInfo')" + search-data-key="AccountAliasList" + :searchbar-props="{ + url: 'MailAliases', + info: t('mailAlias.searchInfo'), + label: t('mailAlias.search'), + searchUrl: 'table', + }" /> </template> diff --git a/src/pages/Account/Alias/Card/AliasSummary.vue b/src/pages/Account/Alias/Card/AliasSummary.vue index cedae28b7..b2dc1f0fc 100644 --- a/src/pages/Account/Alias/Card/AliasSummary.vue +++ b/src/pages/Account/Alias/Card/AliasSummary.vue @@ -28,6 +28,7 @@ const entityId = computed(() => $props.id || route.params.id); ref="summary" :url="`MailAliases/${entityId}`" @on-fetch="(data) => (alias = data)" + data-key="MailAliasesSummary" > <template #header> {{ alias.id }} - {{ alias.alias }} </template> <template #body> diff --git a/src/pages/Account/Card/AccountBasicData.vue b/src/pages/Account/Card/AccountBasicData.vue index 42b77419f..f38299f9e 100644 --- a/src/pages/Account/Card/AccountBasicData.vue +++ b/src/pages/Account/Card/AccountBasicData.vue @@ -37,9 +37,11 @@ watch( <VnInput v-model="data.nickname" :label="t('account.card.alias')" /> <VnInput v-model="data.email" :label="t('account.card.email')" /> <VnSelect + url="Languages" v-model="data.lang" - :options="['es', 'en']" :label="t('account.card.lang')" + option-value="code" + option-label="code" /> </div> </template> diff --git a/src/pages/Account/Card/AccountCard.vue b/src/pages/Account/Card/AccountCard.vue index e4db3ee2b..a9857b283 100644 --- a/src/pages/Account/Card/AccountCard.vue +++ b/src/pages/Account/Card/AccountCard.vue @@ -1,34 +1,21 @@ <script setup> -import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; - import VnCard from 'components/common/VnCard.vue'; import AccountDescriptor from './AccountDescriptor.vue'; const { t } = useI18n(); -const route = useRoute(); - -const routeName = computed(() => route.name); -const customRouteRedirectName = computed(() => routeName.value); -const searchBarDataKeys = { - AccountSummary: 'AccountSummary', - AccountInheritedRoles: 'AccountInheritedRoles', - AccountMailForwarding: 'AccountMailForwarding', - AccountMailAlias: 'AccountMailAlias', - AccountPrivileges: 'AccountPrivileges', - AccountLog: 'AccountLog', -}; </script> <template> <VnCard data-key="Account" :descriptor="AccountDescriptor" - :search-data-key="searchBarDataKeys[routeName]" - :search-custom-route-redirect="customRouteRedirectName" - :search-redirect="!!customRouteRedirectName" - :searchbar-label="t('account.search')" - :searchbar-info="t('account.searchInfo')" + search-data-key="AccountUsers" + :searchbar-props="{ + url: 'VnUsers/preview', + label: t('account.search'), + info: t('account.searchInfo'), + searchUrl: 'table', + }" /> </template> diff --git a/src/pages/Account/Card/AccountDescriptor.vue b/src/pages/Account/Card/AccountDescriptor.vue index d43266172..bc0c8c713 100644 --- a/src/pages/Account/Card/AccountDescriptor.vue +++ b/src/pages/Account/Card/AccountDescriptor.vue @@ -54,7 +54,7 @@ const hasAccount = ref(false); </template> <template #before> <!-- falla id :id="entityId.value" collection="user" size="160x160" --> - <VnImg :id="entityId" collection="user" size="160x160" class="photo"> + <VnImg :id="entityId" collection="user" resolution="160x160" class="photo"> <template #error> <div class="absolute-full picture text-center q-pa-md flex flex-center" diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue index 60510394d..0e35d25f3 100644 --- a/src/pages/Account/Card/AccountDescriptorMenu.vue +++ b/src/pages/Account/Card/AccountDescriptorMenu.vue @@ -1,15 +1,12 @@ <script setup> import axios from 'axios'; import { computed, ref, toRefs } from 'vue'; -import { useQuasar } from 'quasar'; import { useI18n } from 'vue-i18n'; import { useVnConfirm } from 'composables/useVnConfirm'; import { useRoute } from 'vue-router'; import { useArrayData } from 'src/composables/useArrayData'; -import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue'; import VnConfirm from 'src/components/ui/VnConfirm.vue'; - -const quasar = useQuasar(); +import useNotify from 'src/composables/useNotify.js'; const $props = defineProps({ hasAccount: { type: Boolean, @@ -21,7 +18,7 @@ const { t } = useI18n(); const { hasAccount } = toRefs($props); const { openConfirmationModal } = useVnConfirm(); const route = useRoute(); - +const { notify } = useNotify(); const account = computed(() => useArrayData('AccountId').store.data[0]); account.value.hasAccount = hasAccount.value; const entityId = computed(() => +route.params.id); @@ -35,7 +32,7 @@ async function updateStatusAccount(active) { account.value.hasAccount = active; const status = active ? 'enable' : 'disable'; - quasar.notify({ + notify({ message: t(`account.card.${status}Account.success`), type: 'positive', }); @@ -44,19 +41,11 @@ async function updateStatusUser(active) { await axios.patch(`VnUsers/${entityId.value}`, { active }); account.value.active = active; const status = active ? 'activate' : 'deactivate'; - quasar.notify({ + notify({ message: t(`account.card.actions.${status}User.success`), type: 'positive', }); } -function setPassword() { - quasar.dialog({ - component: CustomerChangePassword, - componentProps: { - id: entityId.value, - }, - }); -} const showSyncDialog = ref(false); const syncPassword = ref(null); const shouldSyncPassword = ref(false); @@ -66,7 +55,7 @@ async function sync() { await axios.patch(`Accounts/${account.value.name}/sync`, { params, }); - quasar.notify({ + notify({ message: t('account.card.actions.sync.success'), type: 'positive', }); @@ -103,23 +92,6 @@ async function sync() { /> </template> </VnConfirm> - <QItem v-ripple clickable @click="setPassword"> - <QItemSection>{{ t('account.card.actions.setPassword') }}</QItemSection> - </QItem> - <QItem - v-if="!account.hasAccount" - v-ripple - clickable - @click=" - openConfirmationModal( - t('account.card.actions.enableAccount.title'), - t('account.card.actions.enableAccount.subtitle'), - () => updateStatusAccount(true) - ) - " - > - <QItemSection>{{ t('account.card.actions.enableAccount.name') }}</QItemSection> - </QItem> <QItem v-if="account.hasAccount" v-ripple @@ -168,20 +140,4 @@ async function sync() { </QItem> <QSeparator /> - <QItem - @click=" - openConfirmationModal( - t('account.card.actions.delete.title'), - t('account.card.actions.delete.subTitle'), - removeAccount - ) - " - v-ripple - clickable - > - <QItemSection avatar> - <QIcon name="delete" /> - </QItemSection> - <QItemSection>{{ t('account.card.actions.delete.name') }}</QItemSection> - </QItem> </template> diff --git a/src/pages/Account/Card/AccountMailAlias.vue b/src/pages/Account/Card/AccountMailAlias.vue index 99ce3ab22..594353219 100644 --- a/src/pages/Account/Card/AccountMailAlias.vue +++ b/src/pages/Account/Card/AccountMailAlias.vue @@ -85,7 +85,7 @@ const fetchMailAliases = async () => { paginateRef.value.fetch(); }; -const getAccountData = async () => { +const getAccountData = async (reload = true) => { loading.value = true; hasAccount.value = await fetchAccountExistence(); if (!hasAccount.value) { @@ -93,7 +93,7 @@ const getAccountData = async () => { store.data = []; return; } - await fetchMailAliases(); + reload && (await fetchMailAliases()); loading.value = false; }; @@ -102,13 +102,11 @@ const openCreateMailAliasForm = () => createMailAliasDialogRef.value.show(); watch( () => route.params.id, () => { - store.url = urlPath; - store.filter = filter.value; getAccountData(); } ); -onMounted(async () => await getAccountData()); +onMounted(async () => await getAccountData(false)); </script> <template> diff --git a/src/pages/Account/Card/AccountMailAliasCreateForm.vue b/src/pages/Account/Card/AccountMailAliasCreateForm.vue index 8f6d57091..f0f69dcba 100644 --- a/src/pages/Account/Card/AccountMailAliasCreateForm.vue +++ b/src/pages/Account/Card/AccountMailAliasCreateForm.vue @@ -33,7 +33,7 @@ const aliasOptions = ref([]); @on-submit="emit('onSubmitCreateAlias', aliasFormData)" > <template #form-inputs> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('account.card.alias')" diff --git a/src/pages/Account/Card/AccountPrivileges.vue b/src/pages/Account/Card/AccountPrivileges.vue index f1f24f19b..1300f5018 100644 --- a/src/pages/Account/Card/AccountPrivileges.vue +++ b/src/pages/Account/Card/AccountPrivileges.vue @@ -14,16 +14,11 @@ const rolesOptions = ref([]); const formModelRef = ref(); </script> <template> - <FetchData - url="VnRoles" - :filter="{ fields: ['id', 'name'], order: 'name ASC' }" - auto-load - @on-fetch="(data) => (rolesOptions = data)" - /> + <FetchData url="VnRoles" auto-load @on-fetch="(data) => (rolesOptions = data)" /> <FormModel ref="formModelRef" model="AccountPrivileges" - :url="`VnUsers/${route.params.id}`" + :url="`VnUsers/${route.params.id}/privileges`" :url-create="`VnUsers/${route.params.id}/privileges`" auto-load @on-data-saved="formModelRef.fetch()" diff --git a/src/pages/Account/InheritedRoles.vue b/src/pages/Account/InheritedRoles.vue index 41e718bb5..13294cfdf 100644 --- a/src/pages/Account/InheritedRoles.vue +++ b/src/pages/Account/InheritedRoles.vue @@ -1,23 +1,17 @@ <script setup> import { useRoute, useRouter } from 'vue-router'; import { computed, ref, watch } from 'vue'; - import VnPaginate from 'components/ui/VnPaginate.vue'; - import { useArrayData } from 'composables/useArrayData'; const props = defineProps({ dataKey: { type: String, required: true }, }); - const route = useRoute(); const router = useRouter(); - const paginateRef = ref(null); - const arrayData = useArrayData(props.dataKey); const store = arrayData.store; - const data = computed(() => { const dataCopy = store.data; return dataCopy.sort((a, b) => a.role?.name.localeCompare(b.role?.name)); @@ -37,7 +31,6 @@ const filter = computed(() => ({ })); const urlPath = 'RoleMappings'; - const columns = computed(() => [ { name: 'name', diff --git a/src/pages/Account/Role/AccountRoles.vue b/src/pages/Account/Role/AccountRoles.vue index f4197e433..8f3372a6d 100644 --- a/src/pages/Account/Role/AccountRoles.vue +++ b/src/pages/Account/Role/AccountRoles.vue @@ -1,26 +1,60 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; -import { ref } from 'vue'; - -import VnPaginate from 'src/components/ui/VnPaginate.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import CardList from 'src/components/ui/CardList.vue'; -import RoleSummary from './Card/RoleSummary.vue'; -import RoleForm from './Card/RoleForm.vue'; +import { computed, ref } from 'vue'; +import VnTable from 'components/VnTable/VnTable.vue'; +import { useRoute } from 'vue-router'; import VnSearchbar from 'components/ui/VnSearchbar.vue'; -import AccountRolesFilter from './AccountRolesFilter.vue'; - -import { useStateStore } from 'stores/useStateStore'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; - -const stateStore = useStateStore(); -const router = useRouter(); +import RoleSummary from './Card/RoleSummary.vue'; +const route = useRoute(); const { t } = useI18n(); +const $props = defineProps({ + id: { + type: Number, + default: 0, + }, +}); +const tableRef = ref(); +const entityId = computed(() => $props.id || route.params.id); const { viewSummary } = useSummaryDialog(); - -const roleCreateDialogRef = ref(null); - +const columns = computed(() => [ + { + align: 'left', + name: 'id', + label: t('id'), + isId: true, + columnFilter: { + inWhere: true, + }, + cardVisible: true, + }, + { + align: 'left', + name: 'name', + label: t('name'), + cardVisible: true, + create: true, + }, + { + align: 'left', + name: 'description', + label: t('description'), + cardVisible: true, + create: true, + }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('View Summary'), + icon: 'preview', + action: (row) => viewSummary(row.id, RoleSummary), + }, + ], + }, +]); const exprBuilder = (param, value) => { switch (param) { case 'search': @@ -37,95 +71,30 @@ const exprBuilder = (param, value) => { return { [param]: { like: `%${value}%` } }; } }; - -const openCreateModal = () => roleCreateDialogRef.value.show(); - -const getApiUrl = () => new URL(window.location).origin; - -const navigate = (event, id) => { - if (event.ctrlKey || event.metaKey) - return window.open(`${getApiUrl()}/#/account/role/${id}/summary`); - router.push({ name: 'RoleSummary', params: { id } }); -}; </script> <template> - <template v-if="stateStore.isHeaderMounted()"> - <Teleport to="#searchbar"> - <VnSearchbar - data-key="RolesList" - url="VnRoles" - :label="t('role.searchRoles')" - :info="t('role.searchInfo')" - /> - </Teleport> - <Teleport to="#actions-append"> - <div class="row q-gutter-x-sm"> - <QBtn - flat - @click="stateStore.toggleRightDrawer()" - round - dense - icon="menu" - > - <QTooltip bottom anchor="bottom right"> - {{ t('globals.collapseMenu') }} - </QTooltip> - </QBtn> - </div> - </Teleport> - </template> - <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> - <QScrollArea class="fit text-grey-8"> - <AccountRolesFilter data-key="RolesList" :expr-builder="exprBuilder" /> - </QScrollArea> - </QDrawer> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate data-key="RolesList" url="VnRoles"> - <template #body="{ rows }"> - <CardList - :id="row.id" - :key="row.id" - :title="row.name" - @click="navigate($event, row.id)" - v-for="row of rows" - > - <template #list-items> - <div style="flex-direction: column; width: 100%"> - <VnLv :label="t('role.card.name')" :value="row.name"> - </VnLv> - <VnLv - :label="t('role.card.description')" - :value="row.description" - > - </VnLv> - </div> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, RoleSummary)" - color="primary" - style="margin-top: 15px" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - <QDialog - ref="roleCreateDialogRef" - transition-show="scale" - transition-hide="scale" - > - <RoleForm /> - </QDialog> - <QPageSticky :offset="[20, 20]"> - <QBtn fab icon="add" color="primary" @click="openCreateModal()" /> - <QTooltip> - {{ t('role.newRole') }} - </QTooltip> - </QPageSticky> - </QPage> + <VnSearchbar + data-key="Roles" + :expr-builder="exprBuilder" + :label="t('role.searchRoles')" + :info="t('role.searchInfo')" + /> + <VnTable + ref="tableRef" + data-key="Roles" + :url="`VnRoles`" + :create="{ + urlCreate: 'VnRoles', + title: t('Create rol'), + onDataSaved: ({ id }) => tableRef.redirect(id), + formInitialData: { + editorFk: entityId, + }, + }" + order="id ASC" + :columns="columns" + default-mode="table" + redirect="account/role" + /> </template> diff --git a/src/pages/Account/Role/AccountRolesFilter.vue b/src/pages/Account/Role/AccountRolesFilter.vue index b1929b1de..8340b965d 100644 --- a/src/pages/Account/Role/AccountRolesFilter.vue +++ b/src/pages/Account/Role/AccountRolesFilter.vue @@ -1,6 +1,5 @@ <script setup> import { useI18n } from 'vue-i18n'; - import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; diff --git a/src/pages/Account/Role/Card/RoleBasicData.vue b/src/pages/Account/Role/Card/RoleBasicData.vue index 1f3b3b6da..56f4f0c27 100644 --- a/src/pages/Account/Role/Card/RoleBasicData.vue +++ b/src/pages/Account/Role/Card/RoleBasicData.vue @@ -10,12 +10,12 @@ const { t } = useI18n(); <template> <FormModel :url="`VnRoles/${route.params.id}`" model="VnRole" auto-load> <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput v-model="data.name" :label="t('role.card.name')" /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput v-model="data.description" @@ -23,11 +23,6 @@ const { t } = useI18n(); /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> - <div class="col"> - <QCheckbox :label="t('mailAlias.isPublic')" v-model="data.isPublic" /> - </div> - </VnRow> </template> </FormModel> </template> diff --git a/src/pages/Account/Role/Card/RoleCard.vue b/src/pages/Account/Role/Card/RoleCard.vue index c7b5c695d..35f9a1f27 100644 --- a/src/pages/Account/Role/Card/RoleCard.vue +++ b/src/pages/Account/Role/Card/RoleCard.vue @@ -1,32 +1,20 @@ <script setup> -import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; - import VnCard from 'components/common/VnCard.vue'; import RoleDescriptor from './RoleDescriptor.vue'; const { t } = useI18n(); -const route = useRoute(); - -const routeName = computed(() => route.name); -const customRouteRedirectName = computed(() => routeName.value); -const searchBarDataKeys = { - RoleSummary: 'RoleSummary', - RoleBasicData: 'RoleBasicData', - SubRoles: 'SubRoles', - InheritedRoles: 'InheritedRoles', - RoleLog: 'RoleLog', -}; </script> <template> <VnCard data-key="Role" :descriptor="RoleDescriptor" - :search-data-key="searchBarDataKeys[routeName]" - :search-custom-route-redirect="customRouteRedirectName" - :search-redirect="!!customRouteRedirectName" - :searchbar-label="t('role.searchRoles')" - :searchbar-info="t('role.searchInfo')" + search-data-key="AccountRoles" + :searchbar-props="{ + url: 'VnRoles', + label: t('role.searchRoles'), + info: t('role.searchInfo'), + searchUrl: 'table', + }" /> </template> diff --git a/src/pages/Account/Role/Card/RoleDescriptor.vue b/src/pages/Account/Role/Card/RoleDescriptor.vue index 91d733714..e4af3ed13 100644 --- a/src/pages/Account/Role/Card/RoleDescriptor.vue +++ b/src/pages/Account/Role/Card/RoleDescriptor.vue @@ -1,12 +1,10 @@ <script setup> import { ref, computed } from 'vue'; -import { useRoute, useRouter } from 'vue-router'; +import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import CardDescriptor from 'components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import useCardDescription from 'src/composables/useCardDescription'; -import { useQuasar } from 'quasar'; - import axios from 'axios'; import useNotify from 'src/composables/useNotify.js'; const $props = defineProps({ @@ -23,9 +21,6 @@ const $props = defineProps({ const route = useRoute(); -const quasar = useQuasar(); -const router = useRouter(); - const { notify } = useNotify(); const { t } = useI18n(); const entityId = computed(() => { @@ -36,29 +31,13 @@ const setData = (entity) => (data.value = useCardDescription(entity.name, entity const filter = { where: { id: entityId }, }; -const removeRole = () => { - quasar - .dialog({ - title: 'Are you sure you want to delete it?', - message: 'Delete department', - ok: { - push: true, - color: 'primary', - }, - cancel: true, - }) - .onOk(async () => { - try { - await axios.post( - `/Departments/${entityId.value}/removeChild`, - entityId.value - ); - router.push({ name: 'WorkerDepartment' }); - notify('department.departmentRemoved', 'positive'); - } catch (err) { - console.error('Error removing department'); - } - }); +const removeRole = async () => { + try { + await axios.delete(`VnRoles/${entityId.value}`); + notify(t('Role removed'), 'positive'); + } catch (error) { + console.error('Error deleting role', error); + } }; </script> diff --git a/src/pages/Account/Role/Card/RoleForm.vue b/src/pages/Account/Role/Card/RoleForm.vue index d6fc16598..382639beb 100644 --- a/src/pages/Account/Role/Card/RoleForm.vue +++ b/src/pages/Account/Role/Card/RoleForm.vue @@ -1,7 +1,6 @@ <script setup> import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; - import FormModelPopup from 'components/FormModelPopup.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; @@ -21,12 +20,12 @@ const { t } = useI18n(); " > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput v-model="data.name" :label="t('role.card.name')" /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput v-model="data.description" diff --git a/src/pages/Account/Role/Card/SubRoleCreateForm.vue b/src/pages/Account/Role/Card/SubRoleCreateForm.vue index 89eceed62..8f8214a63 100644 --- a/src/pages/Account/Role/Card/SubRoleCreateForm.vue +++ b/src/pages/Account/Role/Card/SubRoleCreateForm.vue @@ -2,17 +2,14 @@ import { reactive, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; - import VnSelect from 'src/components/common/VnSelect.vue'; import FetchData from 'components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; import FormPopup from 'components/FormPopup.vue'; const emit = defineEmits(['onSubmitCreateSubrole']); - const { t } = useI18n(); const route = useRoute(); - const subRoleFormData = reactive({ inheritsFrom: null, role: route.params.id, @@ -33,7 +30,7 @@ const rolesOptions = ref([]); @on-submit="emit('onSubmitCreateSubrole', subRoleFormData)" > <template #form-inputs> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('account.card.role')" diff --git a/src/pages/Account/Role/Card/SubRoles.vue b/src/pages/Account/Role/Card/SubRoles.vue index 1fb84fe4f..7a0088bac 100644 --- a/src/pages/Account/Role/Card/SubRoles.vue +++ b/src/pages/Account/Role/Card/SubRoles.vue @@ -2,10 +2,8 @@ import { useRoute, useRouter } from 'vue-router'; import { computed, ref, watch } from 'vue'; import { useI18n } from 'vue-i18n'; - import VnPaginate from 'components/ui/VnPaginate.vue'; import SubRoleCreateForm from './SubRoleCreateForm.vue'; - import { useVnConfirm } from 'composables/useVnConfirm'; import { useArrayData } from 'composables/useArrayData'; import useNotify from 'src/composables/useNotify.js'; @@ -16,10 +14,8 @@ const route = useRoute(); const router = useRouter(); const { openConfirmationModal } = useVnConfirm(); const { notify } = useNotify(); - const paginateRef = ref(null); const createSubRoleDialogRef = ref(null); - const arrayData = useArrayData('SubRoles'); const store = arrayData.store; diff --git a/src/pages/Account/locale/en.yml b/src/pages/Account/locale/en.yml index c7220d7c9..3cf861fb2 100644 --- a/src/pages/Account/locale/en.yml +++ b/src/pages/Account/locale/en.yml @@ -68,7 +68,7 @@ account: delete: name: Delete title: The account will be deleted - subtitle: Are you sure you want to continue? + subTitle: Are you sure you want to continue? success: '' search: Search user searchInfo: You can search by id, name or nickname diff --git a/src/pages/Account/locale/es.yml b/src/pages/Account/locale/es.yml index fcc4ce1c8..b53a0153c 100644 --- a/src/pages/Account/locale/es.yml +++ b/src/pages/Account/locale/es.yml @@ -67,7 +67,7 @@ account: delete: name: Eliminar title: El usuario será eliminado - subtitle: ¿Seguro que quieres continuar? + subTitle: ¿Seguro que quieres continuar? success: '' search: Buscar usuario searchInfo: Puedes buscar por id, nombre o usuario diff --git a/src/pages/Claim/Card/ClaimAction.vue b/src/pages/Claim/Card/ClaimAction.vue index e64eab81d..2e890dba8 100644 --- a/src/pages/Claim/Card/ClaimAction.vue +++ b/src/pages/Claim/Card/ClaimAction.vue @@ -31,7 +31,7 @@ const destinationTypes = ref([]); const totalClaimed = ref(null); const DEFAULT_MAX_RESPONSABILITY = 5; const DEFAULT_MIN_RESPONSABILITY = 1; -const arrayData = useArrayData('claimData'); +const arrayData = useArrayData('Claim'); const marker_labels = [ { value: DEFAULT_MIN_RESPONSABILITY, label: t('claim.company') }, { value: DEFAULT_MAX_RESPONSABILITY, label: t('claim.person') }, diff --git a/src/pages/Claim/Card/ClaimBasicData.vue b/src/pages/Claim/Card/ClaimBasicData.vue index de0dc50c3..b1d3e24cd 100644 --- a/src/pages/Claim/Card/ClaimBasicData.vue +++ b/src/pages/Claim/Card/ClaimBasicData.vue @@ -10,13 +10,10 @@ import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import axios from 'axios'; -// import { useSession } from 'src/composables/useSession'; -import VnImg from 'src/components/ui/VnImg.vue'; +import VnAvatar from 'src/components/ui/VnAvatar.vue'; const route = useRoute(); const { t } = useI18n(); -// const { getTokenMultimedia } = useSession(); -// const token = getTokenMultimedia(); const claimStates = ref([]); const claimStatesCopy = ref([]); @@ -74,7 +71,7 @@ const statesFilter = { :reload="true" > <template #form="{ data, validate, filter }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.client.name" :label="t('claim.customer')" @@ -82,7 +79,7 @@ const statesFilter = { /> <VnInputDate v-model="data.created" :label="t('claim.created')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('claim.assignedTo')" v-model="data.workerFk" @@ -94,15 +91,14 @@ const statesFilter = { :rules="validate('claim.claimStateFk')" > <template #before> - <QAvatar color="orange"> - <VnImg - v-if="data.workerFk" - :size="'160x160'" - :id="data.workerFk" - collection="user" - spinner-color="white" - /> - </QAvatar> + <VnAvatar + :worker-id="data.workerFk" + size="md" + :title=" + workersOptions.find(({ id }) => id == data.workerFk)?.name + " + color="primary" + /> </template> </VnSelect> <QSelect @@ -120,7 +116,7 @@ const statesFilter = { > </QSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput v-model.number="data.packages" :label="t('globals.packages')" diff --git a/src/pages/Claim/Card/ClaimCard.vue b/src/pages/Claim/Card/ClaimCard.vue index 19d63e3b2..3642dc0d0 100644 --- a/src/pages/Claim/Card/ClaimCard.vue +++ b/src/pages/Claim/Card/ClaimCard.vue @@ -11,9 +11,11 @@ import filter from './ClaimFilter.js'; :descriptor="ClaimDescriptor" :filter-panel="ClaimFilter" search-data-key="ClaimList" - search-url="Claims/filter" - searchbar-label="Search claim" - searchbar-info="You can search by claim id or customer name" :filter="filter" + :searchbar-props="{ + url: 'Claims/filter', + label: 'Search claim', + info: 'You can search by claim id or customer name', + }" /> </template> diff --git a/src/pages/Claim/Card/ClaimDevelopment.vue b/src/pages/Claim/Card/ClaimDevelopment.vue index 842d45050..f7e8131c6 100644 --- a/src/pages/Claim/Card/ClaimDevelopment.vue +++ b/src/pages/Claim/Card/ClaimDevelopment.vue @@ -20,20 +20,22 @@ const workers = ref([]); const selected = ref([]); const saveButtonRef = ref(); -const developmentsFilter = { - fields: [ - 'id', - 'claimFk', - 'claimReasonFk', - 'claimResultFk', - 'claimResponsibleFk', - 'workerFk', - 'claimRedeliveryFk', - ], - where: { - claimFk: route.params.id, - }, -}; +const developmentsFilter = computed(() => { + return { + fields: [ + 'id', + 'claimFk', + 'claimReasonFk', + 'claimResultFk', + 'claimResponsibleFk', + 'workerFk', + 'claimRedeliveryFk', + ], + where: { + claimFk: route.params.id, + }, + }; +}); const columns = computed(() => [ { @@ -142,9 +144,9 @@ const columns = computed(() => [ ref="claimDevelopmentForm" :data-required="{ claimFk: route.params.id }" v-model:selected="selected" - auto-load @save-changes="$router.push(`/claim/${route.params.id}/action`)" :default-save="false" + auto-load > <template #body="{ rows }"> <QTable diff --git a/src/pages/Claim/Card/ClaimNotes.vue b/src/pages/Claim/Card/ClaimNotes.vue index 83e144e97..a4d11e9f6 100644 --- a/src/pages/Claim/Card/ClaimNotes.vue +++ b/src/pages/Claim/Card/ClaimNotes.vue @@ -14,22 +14,24 @@ const $props = defineProps({ }); const claimId = computed(() => $props.id || route.params.id); -const claimFilter = { - where: { claimFk: claimId.value }, - fields: ['id', 'created', 'workerFk', 'text'], - include: { - relation: 'worker', - scope: { - fields: ['id', 'firstName', 'lastName'], - include: { - relation: 'user', - scope: { - fields: ['id', 'nickname'], +const claimFilter = computed(() => { + return { + where: { claimFk: claimId.value }, + fields: ['id', 'created', 'workerFk', 'text'], + include: { + relation: 'worker', + scope: { + fields: ['id', 'firstName', 'lastName'], + include: { + relation: 'user', + scope: { + fields: ['id', 'nickname'], + }, }, }, }, - }, -}; + }; +}); const body = { claimFk: claimId.value, diff --git a/src/pages/Claim/Card/ClaimPhoto.vue b/src/pages/Claim/Card/ClaimPhoto.vue index 076f8d092..21f1be6ed 100644 --- a/src/pages/Claim/Card/ClaimPhoto.vue +++ b/src/pages/Claim/Card/ClaimPhoto.vue @@ -1,6 +1,6 @@ <script setup> import axios from 'axios'; -import { ref, computed } from 'vue'; +import { ref, computed, watch } from 'vue'; import { useQuasar } from 'quasar'; import { useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; @@ -22,10 +22,8 @@ const claimDms = ref([ }, ]); const client = ref({}); - const inputFile = ref(); const files = ref({}); - const spinnerRef = ref(); const claimDmsRef = ref(); const dmsType = ref({}); @@ -58,6 +56,14 @@ const claimDmsFilter = ref({ const multimediaDialog = ref(); const multimediaSlide = ref(); +watch( + () => router.currentRoute.value.params.id, + () => { + claimDmsFilter.value.where.id = router.currentRoute.value.params.id; + claimDmsRef.value.fetch(); + } +); + function openDialog(dmsId) { multimediaSlide.value = dmsId; multimediaDialog.value = true; diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue index a34830631..4d817c3c2 100644 --- a/src/pages/Claim/Card/ClaimSummary.vue +++ b/src/pages/Claim/Card/ClaimSummary.vue @@ -279,7 +279,7 @@ async function changeState(value) { <ClaimNotes :id="entityId" :add-note="false" - class="max-container-height" + style="max-height: 300px" order="created ASC" /> </QCard> @@ -330,7 +330,7 @@ async function changeState(value) { <QTable :columns="detailsColumns" :rows="salesClaimed" - flat + separator="horizontal" dense :rows-per-page-options="[0]" hide-bottom @@ -344,7 +344,7 @@ async function changeState(value) { </template> <template #body="props"> <QTr :props="props"> - <QTh v-for="col in props.cols" :key="col.name" :props="props"> + <QTd v-for="col in props.cols" :key="col.name" :props="props"> <span v-if="col.name != 'description'">{{ t(col.value) }}</span> @@ -359,7 +359,7 @@ async function changeState(value) { :id="props.row.sale.itemFk" :sale-fk="props.row.saleFk" ></ItemDescriptorProxy> - </QTh> + </QTd> </QTr> </template> </QTable> @@ -384,7 +384,7 @@ async function changeState(value) { <template #body-cell-worker="props"> <QTd :props="props" class="link"> {{ props.value }} - <WorkerDescriptorProxy :id="props.row.worker.id" /> + <WorkerDescriptorProxy :id="props.row.worker?.id" /> </QTd> </template> </QTable> diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue index 8878040f6..dc25fe4a0 100644 --- a/src/pages/Claim/ClaimFilter.vue +++ b/src/pages/Claim/ClaimFilter.vue @@ -100,6 +100,7 @@ defineExpose({ states }); url="Items/withName" option-value="id" option-label="name" + :use-like="false" sort-by="id DESC" outlined rounded diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue index 05698debe..b03dfb226 100644 --- a/src/pages/Claim/ClaimList.vue +++ b/src/pages/Claim/ClaimList.vue @@ -44,13 +44,13 @@ const columns = computed(() => [ fields: ['id', 'name'], }, }, - class: 'expand', + columnClass: 'expand', }, { align: 'left', label: t('claim.attendedBy'), name: 'attendedBy', - cardVisible: true, + orderBy: 'workerFk', columnFilter: { component: 'select', attrs: { @@ -63,6 +63,7 @@ const columns = computed(() => [ optionFilter: 'firstName', }, }, + cardVisible: true, }, { align: 'left', @@ -77,6 +78,9 @@ const columns = computed(() => [ { align: 'left', label: t('claim.state'), + format: ({ stateCode }) => + claimFilterRef.value?.states.find(({code}) => code === stateCode) + ?.description, name: 'stateCode', chip: { condition: () => true, @@ -125,7 +129,7 @@ const STATE_COLOR = { <VnTable data-key="ClaimList" url="Claims/filter" - :order="['priority ASC', 'created DESC']" + :order="['priority ASC', 'created ASC']" :columns="columns" redirect="claim" :right-search="false" diff --git a/src/pages/Claim/ClaimMain.vue b/src/pages/Claim/ClaimMain.vue deleted file mode 100644 index f0dc2e500..000000000 --- a/src/pages/Claim/ClaimMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue index 02f230c03..346e76681 100644 --- a/src/pages/Customer/Card/CustomerBalance.vue +++ b/src/pages/Customer/Card/CustomerBalance.vue @@ -1,120 +1,171 @@ <script setup> -import { computed, onBeforeMount, ref, watch } from 'vue'; +import { computed, onBeforeMount, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; - +import { useRole } from 'src/composables/useRole'; import axios from 'axios'; -import { QCheckbox, QBtn, useQuasar } from 'quasar'; +import { useQuasar } from 'quasar'; import { toCurrency, toDate, toDateHourMin } from 'src/filters'; -import { useState } from 'src/composables/useState'; +import { useState } from 'composables/useState'; import { useStateStore } from 'stores/useStateStore'; -import { useValidator } from 'src/composables/useValidator'; -import { usePrintService } from 'src/composables/usePrintService'; -import { useSession } from 'src/composables/useSession'; +import { usePrintService } from 'composables/usePrintService'; +import { useSession } from 'composables/useSession'; +import { useVnConfirm } from 'composables/useVnConfirm'; + +import VnTable from 'components/VnTable/VnTable.vue'; +import VnInput from 'components/common/VnInput.vue'; +import VnSubToolbar from 'components/ui/VnSubToolbar.vue'; +import VnFilter from 'components/VnTable/VnFilter.vue'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; -import FetchData from 'components/FetchData.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; -const session = useSession(); - -const tokenMultimedia = session.getTokenMultimedia(); +const { openConfirmationModal } = useVnConfirm(); const { sendEmail } = usePrintService(); const { t } = useI18n(); -const { validate } = useValidator(); +const { hasAny } = useRole(); + +const session = useSession(); +const tokenMultimedia = session.getTokenMultimedia(); const quasar = useQuasar(); const route = useRoute(); const state = useState(); const stateStore = useStateStore(); const user = state.getUser(); -const clientRisks = ref(null); -const clientRisksRef = ref(null); -const companiesOptions = ref([]); -const companyId = ref(null); -const receiptsRef = ref(null); -const receiptsData = ref([]); +const clientRisk = ref([]); +const tableRef = ref(); +const companyId = ref(); +const companyLastId = ref(user.value.companyFk); +const balances = ref([]); +const vnFilterRef = ref({}); +const filter = computed(() => { + return { + clientId: route.params.id, + companyId: companyId.value ?? user.value.companyFk, + }; +}); -const filterCompanies = { order: ['code'] }; -const userParams = { - clientId: route.params.id, - companyId: user.value.companyFk, -}; -const filter = { - include: { relation: 'company', scope: { fields: ['code'] } }, - where: { clientFk: route.params.id, companyFk: user.value.companyFk }, +const companyFilterColumn = { + align: 'left', + name: 'companyId', + label: t('Company'), + component: 'select', + attrs: { + url: 'Companies', + optionLabel: 'code', + sortBy: 'code', + limit: 0, + }, + columnFilter: { + event: { + remove: () => (companyId.value = null), + 'update:modelValue': (newCompanyFk) => { + if (!newCompanyFk) return; + vnFilterRef.value.addFilter(newCompanyFk); + companyLastId.value = newCompanyFk; + }, + blur: () => + !companyId.value && + (companyId.value = companyLastId.value ?? user.value.companyFk), + }, + }, + visible: false, }; const columns = computed(() => [ { align: 'left', - field: 'payed', - format: (value) => toDate(value), + name: 'payed', label: t('Date'), - name: 'date', + format: ({ payed }) => toDate(payed), + cardVisible: true, }, { align: 'left', - field: 'created', - format: (value) => toDateHourMin(value), + name: 'created', label: t('Creation date'), - name: 'creationDate', + format: ({ created }) => toDateHourMin(created), + cardVisible: true, }, { align: 'left', - field: 'userName', + name: 'workerFk', label: t('Employee'), - name: 'employee', + columnField: { + component: 'userLink', + attrs: ({ row }) => { + return { + workerId: row.workerFk, + name: row.userName, + }; + }, + }, + cardVisible: true, }, { align: 'left', - field: 'description', + name: 'description', label: t('Reference'), - name: 'reference', + isTitle: true, + class: 'extend', }, { - align: 'left', - field: 'bankFk', + align: 'right', + name: 'bankFk', label: t('Bank'), - name: 'bank', + cardVisible: true, }, { align: 'right', - field: 'debit', - format: (value) => value && toCurrency(value), - label: t('Debit'), name: 'debit', + label: t('Debit'), + format: ({ debit }) => debit && toCurrency(debit), + isId: true, }, { align: 'right', - field: 'credit', - format: (value) => value && toCurrency(value), + name: 'credit', label: t('Havings'), - name: 'havings', + format: ({ credit }) => credit && toCurrency(credit), + cardVisible: true, }, { align: 'right', - field: 'balance', - format: (value) => value && toCurrency(value), - label: t('Balance'), name: 'balance', + label: t('Balance'), + format: ({ balance }) => toCurrency(balance), + cardVisible: true, }, { align: 'left', - field: 'isConciliate', + name: 'isConciliate', label: t('Conciliated'), - name: 'conciliated', + cardVisible: true, }, { align: 'left', - field: 'totalWithVat', - label: '', - name: 'actions', + name: 'tableActions', + actions: [ + { + title: t('globals.downloadPdf'), + icon: 'cloud_download', + show: (row) => row.isInvoice, + action: (row) => showBalancePdf(row), + }, + { + title: t('Send compensation'), + icon: 'outgoing_mail', + show: (row) => !!row.isCompensation, + action: ({ id }) => + openConfirmationModal( + t('Send compensation'), + t('Do you want to report compensation to the client by mail?'), + () => sendEmail(`Receipts/${id}/balance-compensation-email`) + ), + }, + ], }, ]); @@ -123,249 +174,124 @@ onBeforeMount(() => { companyId.value = user.value.companyFk; }); -watch( - () => route.params.id, - (newValue) => { - if (!newValue) return; - userParams.clientId = newValue; - filter.where.clientFk = newValue; - getData(); - } -); +async function getClientRisk() { + const { data } = await axios.get(`clientRisks`, { + params: { + filter: JSON.stringify({ + include: { relation: 'company', scope: { fields: ['code'] } }, + where: { clientFk: route.params.id, companyFk: user.value.companyFk }, + }), + }, + }); + clientRisk.value = data; + return clientRisk.value; +} -const getData = () => { - receiptsRef.value?.fetch(); - clientRisksRef.value?.fetch(); -}; - -const getCurrentBalance = () => { - const currentBalance = clientRisks.value.find((balance) => { +async function getCurrentBalance() { + const currentBalance = (await getClientRisk()).find((balance) => { return balance.companyFk === companyId.value; }); return currentBalance && currentBalance.amount; -}; +} -const onFetch = (balances) => { - balances.forEach((balance, index) => { +async function onFetch(data) { + balances.value = []; + for (const [index, balance] of data.entries()) { if (index === 0) { - balance.balance = getCurrentBalance(); - } else { - let previousBalance = balances[index - 1]; - balance.balance = - previousBalance.balance - - (previousBalance.debit - previousBalance.credit); + balance.balance = await getCurrentBalance(); + continue; } - }); - - receiptsData.value = balances; -}; + const previousBalance = data[index - 1]; + balance.balance = + previousBalance?.balance - (previousBalance?.debit - previousBalance?.credit); + } + balances.value = data; +} const showNewPaymentDialog = () => { quasar.dialog({ component: CustomerNewPayment, componentProps: { companyId: companyId.value, - totalCredit: clientRisks.value[0]?.amount, - promise: getData, + totalCredit: clientRisk.value[0]?.amount, + promise: () => tableRef.value.reload(), }, }); }; -const updateCompanyId = (id) => { - if (id) { - companyId.value = id; - userParams.companyId = id; - filter.where.companyFk = id; - } - getData(); -}; - -const saveFieldValue = async (row) => { - try { - const payload = { description: row.description }; - await axios.patch(`Receipts/${row.id}`, payload); - } catch (err) { - return err; - } -}; - -const sendEmailAction = () => { - sendEmail(`Suppliers/${route.params.id}/campaign-metrics-email`); -}; - -const showBalancePdf = (balance) => { - const url = `api/InvoiceOuts/${balance.id}/download?access_token=${tokenMultimedia}`; +const showBalancePdf = ({ id }) => { + const url = `api/InvoiceOuts/${id}/download?access_token=${tokenMultimedia}`; window.open(url, '_blank'); }; </script> <template> - <FetchData - :filter="filter" - @on-fetch="(data) => (clientRisks = data)" - auto-load - ref="clientRisksRef" - url="ClientRisks" - /> - <FetchData - :filter="filterCompanies" - @on-fetch="(data) => (companiesOptions = data)" - auto-load - url="Companies" - /> - - <VnPaginate - auto-load + <VnSubToolbar class="q-mb-md"> + <template #st-data> + <div class="column justify-center q-px-md q-py-sm"> + <span class="text-bold">{{ t('Total by company') }}</span> + <div class="row justify-center" v-if="clientRisk?.length"> + {{ clientRisk[0].company.code }}: + {{ toCurrency(clientRisk[0].amount) }} + </div> + </div> + </template> + <template #st-actions> + <div> + <VnFilter + ref="vnFilterRef" + v-model="companyId" + data-key="CustomerBalance" + :column="companyFilterColumn" + search-url="balance" + /> + </div> + </template> + </VnSubToolbar> + <VnTable + ref="tableRef" data-key="CustomerBalance" url="Receipts/filter" - :user-params="userParams" - ref="receiptsRef" + search-url="balance" + :user-params="filter" + :columns="columns" + :right-search="false" + :is-editable="false" + :column-search="false" @on-fetch="onFetch" + auto-load > - <template #body="{ rows }"> - <QTable - :columns="columns" - :no-data-label="t('globals.noResults')" - :rows-per-page-options="[0]" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - > - <template #body-cell-employee="{ row }"> - <QTd auto-width @click.stop> - <QBtn color="blue" flat no-caps>{{ row.userName }}</QBtn> - <WorkerDescriptorProxy :id="row.workerFk" /> - </QTd> - </template> - - <template #body-cell-reference="{ row }"> - <QTd auto-width @click.stop v-if="row.isInvoice"> - <QBtn color="blue" dense flat> - {{ t('bill', { ref: row.description }) }} - </QBtn> - <InvoiceOutDescriptorProxy :id="row.id" /> - </QTd> - <QTd v-else> - <VnInput - @keyup.enter="saveFieldValue(row)" - autofocus - clearable - dense - v-model="row.description" - /> - </QTd> - </template> - - <template #body-cell-conciliated="{ row }"> - <QTd align="center"> - <QCheckbox :model-value="row.isConciliate === 1" disable /> - </QTd> - </template> - - <template #body-cell-actions="{ row }"> - <QTd align="center"> - <QIcon - @click.stop="showDialog = true" - class="q-ml-md fill-icon" - color="primary" - name="outgoing_mail" - size="sm" - v-if="row.isCompensation" - > - <QTooltip> - {{ t('Send compensation') }} - </QTooltip> - </QIcon> - <QIcon - @click="showBalancePdf(row)" - class="q-ml-md fill-icon" - color="primary" - name="cloud_download" - size="sm" - v-if="row.hasPdf" - > - <QTooltip> - {{ t('globals.downloadPdf') }} - </QTooltip> - </QIcon> - - <QDialog v-model="showDialog"> - <QCard class="q-pa-sm"> - <QCardSection> - <span - ref="closeButton" - class="flex justify-end color-vn-label" - v-close-popup - > - <QIcon name="close" size="sm" /> - </span> - <div class="text-h6"> - {{ t('Send compensation') }} - </div> - </QCardSection> - <QCardSection> - <div> - {{ - t( - 'Do you want to report compensation to the client by mail?' - ) - }} - </div> - </QCardSection> - <QCardActions class="flex justify-end q-mb-sm"> - <QBtn - :label="t('globals.cancel')" - color="primary" - flat - v-close-popup - /> - <QBtn - :label="t('globals.save')" - @click="sendEmailAction" - class="q-ml-sm" - color="primary" - /> - </QCardActions> - </QCard> - </QDialog> - </QTd> - </template> - </QTable> + <template #column-balance="{ rowIndex }"> + {{ toCurrency(balances[rowIndex]?.balance) }} </template> - </VnPaginate> - - <QDrawer :width="256" show-if-above side="right" v-model="stateStore.rightDrawer"> - <div class="q-mt-xl q-px-md"> - <VnSelect - :label="t('Company')" - :options="companiesOptions" - @update:model-value="updateCompanyId($event)" - hide-selected - option-label="code" - option-value="id" - v-model="companyId" - :rules="validate('entry.companyFk')" - /> - </div> - - <QCard class="q-ma-md q-pa-md q-mt-lg" v-if="receiptsData?.length"> - <QCardSection> - <div class="flex justify-center text-subtitle1 text-bold"> - {{ t('Total by company') }} - </div> - <div class="flex justify-center"> - <div class="q-mr-sm" v-if="clientRisks?.length"> - {{ clientRisks[0].company.code }}: - </div> - <div v-if="clientRisks?.length"> - {{ toCurrency(clientRisks[0].amount) }} - </div> - </div> - </QCardSection> - </QCard> - </QDrawer> - - <QPageSticky :offset="[18, 18]"> + <template #column-description="{ row }"> + <div class="link" v-if="row.isInvoice"> + {{ row.description }} + <InvoiceOutDescriptorProxy :id="row.description" /> + </div> + <span v-else class="q-pa-xs dotted rounded-borders" :title="row.description"> + {{ row.description }} + </span> + <QPopupEdit + v-model="row.description" + v-slot="scope" + @save=" + (value) => + value != row.description && + axios.patch(`Receipts/${row.id}`, { description: value }) + " + auto-save + > + <VnInput + v-model="scope.value" + :disable="!hasAny(['administrative'])" + @keypress.enter="scope.set" + autofocus + /> + </QPopupEdit> + </template> + </VnTable> + <QPageSticky :offset="[18, 18]" style="z-index: 2"> <QBtn @click.stop="showNewPaymentDialog()" color="primary" fab icon="add" /> <QTooltip> {{ t('New payment') }} @@ -393,3 +319,12 @@ es: Send compensation: Enviar compensación Do you want to report compensation to the client by mail?: ¿Desea informar de la compensación al cliente por correo? </i18n> + +<style lang="scss" scoped> +.dotted { + border: 1px dotted var(--vn-header-color); +} +.dotted:hover { + border: 1px dotted $primary; +} +</style> diff --git a/src/pages/Customer/Card/CustomerBasicData.vue b/src/pages/Customer/Card/CustomerBasicData.vue index 6f37544e8..87a3b08f7 100644 --- a/src/pages/Customer/Card/CustomerBasicData.vue +++ b/src/pages/Customer/Card/CustomerBasicData.vue @@ -7,67 +7,30 @@ import FetchData from 'components/FetchData.vue'; import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; -import VnImg from 'src/components/ui/VnImg.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnAvatar from 'src/components/ui/VnAvatar.vue'; const route = useRoute(); const { t } = useI18n(); -const workers = ref([]); -const workersCopy = ref([]); const businessTypes = ref([]); const contactChannels = ref([]); - -function setWorkers(data) { - workers.value = data; - workersCopy.value = data; -} - -const filterOptions = { - options: workers, - filterFn: (options, value) => { - const search = value.toLowerCase(); - - if (value === '') return workersCopy.value; - - return options.value.filter((row) => { - const id = row.id; - const name = row.name.toLowerCase(); - - const idMatches = id === search; - const nameMatches = name.indexOf(search) > -1; - - return idMatches || nameMatches; - }); - }, -}; +const title = ref(); </script> <template> - <fetch-data - url="Workers/activeWithInheritedRole" - :filter="{ where: { role: 'salesPerson' } }" - @on-fetch="setWorkers" - auto-load - /> - <fetch-data + <FetchData url="ContactChannels" @on-fetch="(data) => (contactChannels = data)" auto-load /> - <fetch-data + <FetchData url="BusinessTypes" @on-fetch="(data) => (businessTypes = data)" auto-load /> - <fetch-data - :filter="filter" - @on-fetch="(data) => (clients = data)" - auto-load - url="Clients" - /> - <FormModel :url="`Clients/${route.params.id}`" auto-load model="customer"> - <template #form="{ data, validate, filter }"> - <VnRow class="row q-gutter-md q-mb-md"> + <template #form="{ data, validate }"> + <VnRow> <VnInput :label="t('globals.name')" :rules="validate('client.socialName')" @@ -75,7 +38,6 @@ const filterOptions = { clearable v-model="data.name" /> - <QSelect :input-debounce="0" :label="t('customer.basicData.businessType')" @@ -88,7 +50,7 @@ const filterOptions = { v-model="data.businessTypeFk" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('customer.basicData.contact')" :rules="validate('client.contact')" @@ -111,7 +73,7 @@ const filterOptions = { </template> </VnInput> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('customer.basicData.phone')" :rules="validate('client.phone')" @@ -125,31 +87,26 @@ const filterOptions = { v-model="data.mobile" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> - <QSelect - :input-debounce="0" - :label="t('customer.basicData.salesPerson')" - :options="workers" - :rules="validate('client.salesPersonFk')" - @filter="(value, update) => filter(value, update, filterOptions)" - emit-value - map-options - option-label="name" - option-value="id" - use-input + <VnRow> + <VnSelect + url="Workers/activeWithInheritedRole" + :filter="{ where: { role: 'salesPerson' } }" + option-filter="firstName" v-model="data.salesPersonFk" + :label="t('customer.basicData.salesPerson')" + :rules="validate('client.salesPersonFk')" + :use-like="false" + :emit-value="false" + @update:model-value="(val) => (title = val?.nickname)" > <template #prepend> - <QAvatar color="orange"> - <VnImg - v-if="data.salesPersonFk" - :id="user.id" - collection="user" - spinner-color="white" - /> - </QAvatar> + <VnAvatar + :worker-id="data.salesPersonFk" + color="primary" + :title="title" + /> </template> - </QSelect> + </VnSelect> <QSelect v-model="data.contactChannelFk" :options="contactChannels" @@ -162,7 +119,7 @@ const filterOptions = { :input-debounce="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QSelect :input-debounce="0" :label="t('customer.basicData.previousClient')" diff --git a/src/pages/Customer/Card/CustomerBillingData.vue b/src/pages/Customer/Card/CustomerBillingData.vue index 63bbd872c..b01dc4523 100644 --- a/src/pages/Customer/Card/CustomerBillingData.vue +++ b/src/pages/Customer/Card/CustomerBillingData.vue @@ -47,7 +47,7 @@ const getBankEntities = (data, formData) => { model="customer" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Billing data')" :options="payMethods" @@ -59,7 +59,7 @@ const getBankEntities = (data, formData) => { <VnInput :label="t('Due day')" clearable v-model="data.dueDay" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('IBAN')" clearable v-model="data.iban"> <template #append> <QIcon name="info" class="cursor-info"> @@ -94,7 +94,7 @@ const getBankEntities = (data, formData) => { </VnSelectDialog> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox :label="t('Received LCR')" v-model="data.hasLcr" /> <QCheckbox :label="t('VNL core received')" v-model="data.hasCoreVnl" /> <QCheckbox :label="t('VNL B2B received')" v-model="data.hasSepaVnl" /> diff --git a/src/pages/Customer/Card/CustomerCard.vue b/src/pages/Customer/Card/CustomerCard.vue index 17f123e7b..229946ea2 100644 --- a/src/pages/Customer/Card/CustomerCard.vue +++ b/src/pages/Customer/Card/CustomerCard.vue @@ -10,8 +10,10 @@ import CustomerFilter from '../CustomerFilter.vue'; :descriptor="CustomerDescriptor" :filter-panel="CustomerFilter" search-data-key="CustomerList" - search-url="Clients/extendedListFilter" - searchbar-label="Search customer" - searchbar-info="You can search by customer id or name" + :searchbar-props="{ + url: 'Clients/extendedListFilter', + label: 'Search customer', + info: 'You can search by customer id or name', + }" /> </template> diff --git a/src/pages/Customer/Card/CustomerConsumption.vue b/src/pages/Customer/Card/CustomerConsumption.vue index 1ee771bf8..4d3da1116 100644 --- a/src/pages/Customer/Card/CustomerConsumption.vue +++ b/src/pages/Customer/Card/CustomerConsumption.vue @@ -1,13 +1,12 @@ <script setup> -import { useI18n } from 'vue-i18n'; - -const { t } = useI18n(); +import CustomerConsumptionFilter from './CustomerConsumptionFilter.vue'; +import { useStateStore } from 'src/stores/useStateStore'; </script> <template> - <h5 class="flex justify-center color-vn-label"> - {{ t('Enter a new search') }} - </h5> + <Teleport to="#right-panel" v-if="useStateStore().isHeaderMounted()"> + <CustomerConsumptionFilter data-key="CustomerConsumption" /> + </Teleport> </template> <i18n> diff --git a/src/pages/Customer/Card/CustomerConsumptionFilter.vue b/src/pages/Customer/Card/CustomerConsumptionFilter.vue new file mode 100644 index 000000000..4d2c5ff3c --- /dev/null +++ b/src/pages/Customer/Card/CustomerConsumptionFilter.vue @@ -0,0 +1,91 @@ +<script setup> +import { useI18n } from 'vue-i18n'; +import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import { QItem } from 'quasar'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import { QItemSection } from 'quasar'; + +const { t } = useI18n(); +defineProps({ dataKey: { type: String, required: true } }); +</script> +<template> + <VnFilterPanel :data-key="dataKey" :search-button="true"> + <template #tags="{ tag, formatFn }"> + <div class="q-gutter-x-xs"> + <strong>{{ t(`params.${tag.label}`) }}: </strong> + <span>{{ formatFn(tag.value) }}</span> + </div> + </template> + <template #body="{ params }"> + <QItem> + <QItemSection> + <VnInput + :label="t('params.item')" + v-model="params.itemId" + is-outlined + lazy-rules + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + v-model="params.buyerId" + url="TicketRequests/getItemTypeWorker" + :label="t('params.buyer')" + option-value="id" + option-label="nickname" + dense + outlined + rounded + /> + </QItemSection> + </QItem> + <QItem> + <!--It's required to include the relation category !! There's 413 records in production--> + <QItemSection> + <VnSelect + v-model="params.typeId" + url="ItemTypes" + :label="t('params.type')" + option-label="name" + option-value="id" + dense + outlined + rounded + > + </VnSelect> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnSelect + url="ItemCategories" + :label="t('params.category')" + option-label="name" + option-value="id" + v-model="params.categoryId" + dense + outlined + rounded + /> + </QItemSection> + </QItem> + </template> + </VnFilterPanel> +</template> +<i18n> +en: + params: + item: Item id + buyer: Buyer + type: Type + category: Category +es: + params: + item: Id artículo + buyer: Comprador + type: Tipo + category: Categoría +</i18n> diff --git a/src/pages/Customer/Card/CustomerCreditOpinion.vue b/src/pages/Customer/Card/CustomerCreditOpinion.vue index 5d8e5727b..9c060b1a5 100644 --- a/src/pages/Customer/Card/CustomerCreditOpinion.vue +++ b/src/pages/Customer/Card/CustomerCreditOpinion.vue @@ -88,7 +88,7 @@ watch( :url-create="`Clients/${route.params.id}/setRating`" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Rating')" diff --git a/src/pages/Customer/Card/CustomerCredits.vue b/src/pages/Customer/Card/CustomerCredits.vue index 755ba3b9a..377d95412 100644 --- a/src/pages/Customer/Card/CustomerCredits.vue +++ b/src/pages/Customer/Card/CustomerCredits.vue @@ -1,138 +1,88 @@ <script setup> import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - -import { QBtn } from 'quasar'; - +import { useRoute } from 'vue-router'; import { toCurrency, toDateHourMin } from 'src/filters'; - -import FetchData from 'components/FetchData.vue'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; +import VnTable from 'components/VnTable/VnTable.vue'; +import VnUserLink from 'src/components/ui/VnUserLink.vue'; const { t } = useI18n(); const route = useRoute(); -const router = useRouter(); -const rows = ref([]); - -const filter = { - include: [ - { - relation: 'worker', - scope: { - fields: ['id'], - include: { relation: 'user', scope: { fields: ['name'] } }, +const filter = computed(() => { + return { + include: [ + { + relation: 'worker', + scope: { + fields: ['id'], + include: { relation: 'user', scope: { fields: ['name'] } }, + }, }, - }, - ], - where: { clientFk: route.params.id }, - order: ['created DESC'], - limit: 20, -}; - -const tableColumnComponents = { - created: { - component: 'span', - props: () => {}, - event: () => {}, - }, - employee: { - component: QBtn, - props: () => ({ flat: true, color: 'blue', noCaps: true }), - event: () => {}, - }, - amount: { - component: 'span', - props: () => {}, - event: () => {}, - }, -}; + ], + where: { clientFk: +route.params.id }, + }; +}); +const tableRef = ref(); +const tableData = ref([]); const columns = computed(() => [ { align: 'left', - field: 'created', - label: t('Since'), name: 'created', - format: (value) => toDateHourMin(value), + label: t('Since'), + format: ({ created }) => toDateHourMin(created), }, { align: 'left', - field: (value) => value.worker.user.name, label: t('Employee'), name: 'employee', }, { align: 'left', - field: 'amount', label: t('Credit'), name: 'amount', - format: (value) => toCurrency(value), + format: ({ amount }) => toCurrency(amount), + }, + { + label: t('Credit'), + name: 'credit', + create: true, + visible: false, + attrs: { + autofocus: true, + }, }, ]); - -const toCustomerCreditCreate = () => { - router.push({ name: 'CustomerCreditCreate' }); -}; </script> - <template> - <FetchData - :filter="filter" - @on-fetch="(data) => (rows = data)" - auto-load + <VnTable + ref="tableRef" + data-key="ClientCredit" url="ClientCredits" - /> - - <div class="full-width flex justify-center"> - <QCard class="card-width q-pa-lg"> - <QTable - :columns="columns" - :pagination="{ rowsPerPage: 12 }" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - v-if="rows?.length" - > - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is="tableColumnComponents[props.col.name].component" - @click=" - tableColumnComponents[props.col.name].event(props) - " - class="rounded-borders q-pa-sm" - v-bind=" - tableColumnComponents[props.col.name].props(props) - " - > - {{ props.value }} - <WorkerDescriptorProxy - :id="props.row.workerFk" - v-if="props.col.name === 'employee'" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> - - <h5 class="flex justify-center color-vn-label" v-else> - {{ t('globals.noResults') }} - </h5> - </QCard> - </div> - - <QPageSticky :offset="[18, 18]"> - <QBtn @click.stop="toCustomerCreditCreate()" color="primary" fab icon="add" /> - <QTooltip> - {{ t('New credit') }} - </QTooltip> - </QPageSticky> + search-url="credits" + :filter="filter" + :order="['created DESC']" + :columns="columns" + auto-load + :right-search="false" + :is-editable="false" + :use-model="true" + :column-search="false" + :disable-option="{ card: true }" + @on-fetch="(data) => (tableData = data)" + :create="{ + urlUpdate: `Clients/${route.params.id}`, + title: t('New credit'), + onDataSaved: () => tableRef.reload(), + formInitialData: { credit: tableData.at(0)?.amount }, + }" + > + <template #column-employee="{ row }"> + <VnUserLink :name="row?.worker?.user?.name" :worker-id="row.worker?.id" /> + </template> + </VnTable> </template> - <i18n> es: Since: Desde diff --git a/src/pages/Customer/Card/CustomerDescriptor.vue b/src/pages/Customer/Card/CustomerDescriptor.vue index 938d90ab1..0e76bcfed 100644 --- a/src/pages/Customer/Card/CustomerDescriptor.vue +++ b/src/pages/Customer/Card/CustomerDescriptor.vue @@ -139,7 +139,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit <QBtn :to="{ name: 'TicketList', - query: { params: JSON.stringify({ clientFk: entity.id }) }, + query: { table: JSON.stringify({ clientFk: entity.id }) }, }" size="md" icon="vn:ticket" @@ -150,7 +150,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit <QBtn :to="{ name: 'InvoiceOutList', - query: { params: JSON.stringify({ clientFk: entity.id }) }, + query: { table: JSON.stringify({ clientFk: entity.id }) }, }" size="md" icon="vn:invoice-out" @@ -161,7 +161,7 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit <QBtn :to="{ name: 'OrderCreate', - query: { clientFk: entity.id }, + query: { clientId: entity.id }, }" size="md" icon="vn:basketadd" @@ -169,8 +169,19 @@ const setData = (entity) => (data.value = useCardDescription(entity?.name, entit > <QTooltip>{{ t('New order') }}</QTooltip> </QBtn> - <QBtn size="md" icon="face" color="primary"> - <!-- TODO:: Redirigir a la vista de usuario cuando exista --> + <QBtn + :to="{ + name: 'AccountList', + query: { + table: JSON.stringify({ + filter: { where: { id: entity.id } }, + }), + }, + }" + size="md" + icon="face" + color="primary" + > <QTooltip>{{ t('Go to user') }}</QTooltip> </QBtn> </QCardActions> diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue index a7cdfafc5..5cc656bb3 100644 --- a/src/pages/Customer/Card/CustomerFiscalData.vue +++ b/src/pages/Customer/Card/CustomerFiscalData.vue @@ -15,7 +15,6 @@ const route = useRoute(); const typesTaxes = ref([]); const typesTransactions = ref([]); -const postcodesOptions = ref([]); function handleLocation(data, location) { const { town, code, provinceFk, countryFk } = location ?? {}; @@ -40,7 +39,7 @@ function handleLocation(data, location) { model="customer" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Social name')" :required="true" @@ -57,11 +56,11 @@ function handleLocation(data, location) { <VnInput :label="t('Tax number')" clearable v-model="data.fi" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Street')" clearable v-model="data.street" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Sage tax type')" :options="typesTaxes" @@ -91,22 +90,18 @@ function handleLocation(data, location) { </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.postcode" @update:model-value="(location) => handleLocation(data, location)" - > - </VnLocation> + /> </VnRow> - <VnRow> <QCheckbox :label="t('Active')" v-model="data.isActive" /> <QCheckbox :label="t('Frozen')" v-model="data.isFreezed" /> </VnRow> - <VnRow> <QCheckbox :label="t('Has to invoice')" v-model="data.hasToInvoice" /> <div> diff --git a/src/pages/Customer/Card/CustomerGreuges.vue b/src/pages/Customer/Card/CustomerGreuges.vue index 8cca2ef23..12173727f 100644 --- a/src/pages/Customer/Card/CustomerGreuges.vue +++ b/src/pages/Customer/Card/CustomerGreuges.vue @@ -2,101 +2,86 @@ import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; -import { QBtn } from 'quasar'; -import { useStateStore } from 'src/stores/useStateStore'; import { toCurrency } from 'src/filters'; import { toDateTimeFormat } from 'src/filters/date'; -import FetchData from 'components/FetchData.vue'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; +import VnTable from 'components/VnTable/VnTable.vue'; const { t } = useI18n(); const route = useRoute(); -const stateStore = computed(() => useStateStore()); const rows = ref([]); const totalAmount = ref(); - -const filter = { - include: [ - { - relation: 'greugeType', - scope: { - fields: ['id', 'name'], +const tableRef = ref(); +const filter = computed(() => { + return { + include: [ + { + relation: 'greugeType', + scope: { + fields: ['id', 'name'], + }, }, - }, - { - relation: 'user', - scope: { - fields: ['id', 'name'], + { + relation: 'user', + scope: { + fields: ['id', 'name'], + }, }, + ], + where: { + clientFk: route.params.id, }, - ], - order: 'shipped DESC, amount', - where: { - clientFk: `${route.params.id}`, - }, - limit: 20, -}; - -const tableColumnComponents = { - date: { - component: 'span', - props: () => {}, - event: () => {}, - }, - createdBy: { - component: QBtn, - props: () => ({ flat: true, color: 'blue', noCaps: true }), - event: () => {}, - }, - comment: { - component: 'span', - props: () => {}, - event: () => {}, - }, - type: { - component: 'span', - props: () => {}, - event: () => {}, - }, - amount: { - component: 'span', - props: () => {}, - event: () => {}, - }, -}; + }; +}); const columns = computed(() => [ { align: 'left', - field: 'shipped', label: t('Date'), - name: 'date', - format: (value) => toDateTimeFormat(value), + name: 'shipped', + format: ({ shipped }) => toDateTimeFormat(shipped), + create: true, + columnCreate: { + component: 'date', + autofocus: true, + }, }, { align: 'left', - field: (value) => value?.user?.name, + name: 'userFk', label: t('Created by'), - name: 'createdBy', + component: 'userLink', + attrs: ({ row }) => { + return { + defaultName: true, + workerId: row.user?.id, + name: row.user?.name, + }; + }, }, { align: 'left', - field: 'description', + name: 'description', label: t('Comment'), - name: 'comment', + create: true, }, { align: 'left', - field: (value) => value?.greugeType?.name, + name: 'greugeTypeFk', + format: ({ greugeType }) => greugeType?.name, label: t('Type'), - name: 'type', + create: true, + columnCreate: { + component: 'select', + url: 'greugeTypes', + limit: 0, + }, }, { align: 'left', - field: 'amount', - label: t('Amount'), name: 'amount', - format: (value) => toCurrency(value), + label: t('Amount'), + format: ({ amount }) => toCurrency(amount), + create: true, }, ]); @@ -107,60 +92,33 @@ const setRows = (data) => { </script> <template> - <FetchData :filter="filter" @on-fetch="setRows" auto-load url="greuges" /> - <QDrawer v-model="stateStore.rightDrawer" side="right" :width="300" show-if-above> - <QCard class="full-width q-pa-sm"> - <h6 class="flex justify-end q-my-lg q-pr-lg" v-if="totalAmount !== undefined"> - <span class="color-vn-label q-mr-md">{{ t('Total') }}:</span> - {{ toCurrency(totalAmount) }} - </h6> - <QSkeleton v-else type="QInput" square /> - </QCard> - </QDrawer> - <div class="full-width flex justify-center"> - <QPage class="card-width q-pa-lg"> - <QCard class="q-pa-sm q-mt-md"> - <QTable - :columns="columns" - :no-data-label="t('globals.noResults')" - :pagination="{ rowsPerPage: 12 }" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - > - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is="tableColumnComponents[props.col.name].component" - class="col-content" - v-bind=" - tableColumnComponents[props.col.name].props(props) - " - @click=" - tableColumnComponents[props.col.name].event(props) - " - > - {{ props.value }} - <WorkerDescriptorProxy - :id="props.row.userFk" - v-if="props.col.name === 'createdBy'" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> + <VnTable + ref="tableRef" + data-key="Greuges" + url="Greuges" + search-url="greuges" + :filter="filter" + :order="['shipped DESC', 'amount']" + :columns="columns" + :right-search="false" + :is-editable="false" + :use-model="true" + :column-search="false" + @on-fetch="(data) => setRows(data)" + :create="{ + urlCreate: `Greuges`, + title: t('New credit'), + onDataSaved: () => tableRef.reload(), + formInitialData: { shipped: new Date(), clientFk: route.params.id }, + }" + auto-load + > + <template #top-left> + <QCard class="q-px-md q-py-sm"> + {{ t('Total') }}: {{ toCurrency(totalAmount) }} </QCard> - </QPage> - </div> - - <QPageSticky :offset="[18, 18]"> - <QBtn color="primary" fab icon="add" :to="{ name: 'CustomerGreugeCreate' }" /> - <QTooltip> - {{ t('New greuge') }} - </QTooltip> - </QPageSticky> + </template> + </VnTable> </template> <style lang="scss"> diff --git a/src/pages/Customer/Card/CustomerLog.vue b/src/pages/Customer/Card/CustomerLog.vue index 4f0ee2de7..cdf1394b1 100644 --- a/src/pages/Customer/Card/CustomerLog.vue +++ b/src/pages/Customer/Card/CustomerLog.vue @@ -1,262 +1,6 @@ <script setup> -import { onBeforeMount, ref } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; - -import { useStateStore } from 'stores/useStateStore'; - -import FetchData from 'components/FetchData.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnInputDate from 'src/components/common/VnInputDate.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; - -const { t } = useI18n(); -const route = useRoute(); -const stateStore = useStateStore(); - -const clientLogs = ref(null); -const urlClientLogsEditors = ref(null); -const urlClientLogsModels = ref(null); -const clientLogsModelsOptions = ref([]); -const clientLogsOptions = ref([]); -const clientLogsEditorsOptions = ref([]); -const radioButtonValue = ref('all'); -const insert = ref(false); -const update = ref(false); -const deletes = ref(false); -const select = ref(false); -const neq = ref(null); -const inq = ref([]); - -const filterClientLogs = { - fields: [ - 'id', - 'originFk', - 'userFk', - 'action', - 'changedModel', - 'oldInstance', - 'newInstance', - 'creationDate', - 'changedModel', - 'changedModelId', - 'changedModelValue', - 'description', - ], - include: [ - { - relation: 'user', - scope: { - fields: ['nickname', 'name', 'image'], - include: { relation: 'worker', scope: { fields: ['id'] } }, - }, - }, - ], - order: ['creationDate DESC', 'id DESC'], - limit: 20, -}; -const filterClientLogsEditors = { - fields: ['id', 'nickname', 'name', 'image'], - order: 'nickname', - limit: 30, -}; -const filterClientLogsModels = { order: ['changedModel'] }; -const urlBase = `ClientLogs/${route.params.id}`; - -onBeforeMount(() => { - stateStore.rightDrawer = true; - filterClientLogs.where = { - and: [ - { originFk: `${route.params.id}` }, - { userFk: { neq: radioButtonValue.value } }, - { action: { inq: inq.value } }, - ], - }; - urlClientLogsEditors.value = `${urlBase}/editors`; - urlClientLogsModels.value = `${urlBase}/models`; -}); - -const getClientLogs = async (value, status) => { - if (status === 'neq') { - neq.value = value; - } else { - setInq(value, status); - } - filterClientLogs.where = { - and: [ - { originFk: `${route.params.id}` }, - { userFk: { neq: neq.value } }, - { action: { inq: inq.value } }, - ], - }; - clientLogs.value?.fetch(); -}; - -const setInq = (value, status) => { - if (status) { - if (!inq.value.includes(value)) { - inq.value.push(value); - } - } else { - inq.value = inq.value.filter((item) => item !== value); - } -}; +import VnLog from 'src/components/common/VnLog.vue'; </script> - <template> - <FetchData - :filter="filterClientLogs" - @on-fetch="(data) => (clientLogsOptions = data)" - auto-load - url="ClientLogs" - ref="clientLogs" - /> - <FetchData - :filter="filterClientLogsEditors" - @on-fetch="(data) => (clientLogsEditorsOptions = data)" - auto-load - :url="urlClientLogsEditors" - /> - <FetchData - :filter="filterClientLogsModels" - @on-fetch="(data) => (clientLogsModelsOptions = data)" - auto-load - :url="urlClientLogsModels" - /> - - <h5 class="flex justify-center color-vn-label"> - {{ t('globals.noResults') }} - </h5> - - <QDrawer :width="256" show-if-above side="right" v-model="stateStore.rightDrawer"> - <div class="q-mt-sm q-px-md"> - <VnInput :label="t('Search')" clearable> - <template #append> - <QIcon name="info" class="cursor-pointer"> - <QTooltip> - {{ t('Search by id or concept') }} - </QTooltip> - </QIcon> - </template> - </VnInput> - <VnSelect - :label="t('Entity')" - :options="[]" - class="q-mt-md" - hide-selected - option-label="name" - option-value="id" - /> - - <div class="q-mt-lg"> - <QRadio - :dark="true" - :label="t('All')" - @update:model-value="getClientLogs($event, 'neq')" - dense - v-model="radioButtonValue" - val="all" - /> - </div> - <div class="q-mt-md"> - <QRadio - :dark="true" - :label="t('User')" - @update:model-value="getClientLogs($event, 'neq')" - dense - v-model="radioButtonValue" - val="user" - /> - </div> - <div class="q-mt-md"> - <QRadio - :dark="true" - :label="t('System')" - @update:model-value="getClientLogs($event, 'neq')" - dense - v-model="radioButtonValue" - val="system" - /> - </div> - - <VnSelect - :label="t('User')" - :options="[]" - class="q-mt-sm" - hide-selected - option-label="name" - option-value="id" - /> - <VnInput :label="t('Changes')" clearable class="q-mt-sm"> - <template #append> - <QIcon name="info" class="cursor-pointer"> - <QTooltip> - {{ t('Search by changes') }} - </QTooltip> - </QIcon> - </template> - </VnInput> - - <div class="q-mt-md"> - <QCheckbox - :label="t('Creates')" - @update:model-value="getClientLogs('insert', $event)" - v-model="insert" - /> - </div> - <div> - <QCheckbox - :label="t('Edits')" - @update:model-value="getClientLogs('update', $event)" - v-model="update" - /> - </div> - <div> - <QCheckbox - :label="t('Deletes')" - @update:model-value="getClientLogs('delete', $event)" - v-model="deletes" - /> - </div> - <div> - <QCheckbox - :label="t('Accesses')" - @update:model-value="getClientLogs('select', $event)" - v-model="select" - /> - </div> - - <VnInputDate :label="t('Date')" class="q-mt-sm" /> - <VnInput :label="t('To')" clearable class="q-mt-md" /> - </div> - </QDrawer> - - <QPageSticky - :offset="[18, 18]" - v-if="radioButtonValue !== 'all' || insert || update || deletes || select" - > - <QBtn color="primary" fab icon="filter_alt_off" /> - <QTooltip> - {{ t('Quit filter') }} - </QTooltip> - </QPageSticky> + <VnLog model="Client" /> </template> - -<i18n> -es: - Search: Buscar - Search by id or concept: xxx - Entity: Entidad - All: Todo - User: Usuario - System: Sistema - Changes: Cambios - Search by changes: xxx - Creates: Crea - Edits: Modifica - Deletes: Elimina - Accesses: Accede - Date: Fecha - To: Hasta - Quit filter: Quitar filtro -</i18n> diff --git a/src/pages/Customer/Card/CustomerNotes.vue b/src/pages/Customer/Card/CustomerNotes.vue index 419da4b42..a9121f7f5 100644 --- a/src/pages/Customer/Card/CustomerNotes.vue +++ b/src/pages/Customer/Card/CustomerNotes.vue @@ -1,83 +1,26 @@ <script setup> -import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; +import { computed } from 'vue'; +import { useRoute } from 'vue-router'; +import VnNotes from 'src/components/ui/VnNotes.vue'; -import { toDateTimeFormat } from 'src/filters/date'; - -import VnPaginate from 'src/components/ui/VnPaginate.vue'; - -const { t } = useI18n(); const route = useRoute(); -const router = useRouter(); -const noteFilter = { - order: 'created DESC', - where: { - clientFk: `${route.params.id}`, - }, -}; - -const toCustomerNoteCreate = () => { - router.push({ name: 'CustomerNoteCreate' }); -}; +const noteFilter = computed(() => { + return { + order: 'created DESC', + where: { + clientFk: `${route.params.id}`, + }, + }; +}); </script> <template> - <div class="full-width flex justify-center"> - <QCard class="card-width q-pa-lg"> - <VnPaginate - data-key="CustomerNotes" - url="clientObservations" - auto-load - :filter="noteFilter" - > - <template #body="{ rows }"> - <div v-if="rows.length"> - <QCard - v-for="(item, index) in rows" - :key="index" - class="q-pa-md q-rounded custom-border" - :class="{ 'q-mb-md': index < rows.length - 1 }" - > - <div class="flex justify-between"> - <p class="color-vn-label"> - {{ item.worker.user.nickname }} - </p> - <p class="color-vn-label"> - {{ toDateTimeFormat(item?.created) }} - </p> - </div> - <h6 class="q-mt-xs q-mb-none">{{ item.text }}</h6> - </QCard> - </div> - - <div v-else> - <h5 class="flex justify-center color-vn-label"> - {{ t('globals.noResults') }} - </h5> - </div> - </template> - </VnPaginate> - </QCard> - </div> - - <QPageSticky :offset="[18, 18]"> - <QBtn @click.stop="toCustomerNoteCreate()" color="primary" fab icon="add" /> - <QTooltip> - {{ t('New note') }} - </QTooltip> - </QPageSticky> + <VnNotes + url="clientObservations" + :add-note="true" + :filter="noteFilter" + :body="{ clientFk: route.params.id }" + style="overflow-y: auto" + /> </template> - -<style lang="scss"> -.custom-border { - border: 2px solid var(--vn-accent-color); - border-radius: 10px; - padding: 10px; -} -</style> - -<i18n> -es: - New note: Nueva nota -</i18n> diff --git a/src/pages/Customer/Card/CustomerRecoveries.vue b/src/pages/Customer/Card/CustomerRecoveries.vue index 289b4bc0e..8d3d05702 100644 --- a/src/pages/Customer/Card/CustomerRecoveries.vue +++ b/src/pages/Customer/Card/CustomerRecoveries.vue @@ -1,146 +1,107 @@ <script setup> +import axios from 'axios'; import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - +import { useRoute } from 'vue-router'; import { toCurrency, toDate } from 'src/filters'; -import FetchData from 'components/FetchData.vue'; +import VnTable from 'components/VnTable/VnTable.vue'; const { t } = useI18n(); const route = useRoute(); -const router = useRouter(); -const rows = ref([]); - -const filter = { - where: { clientFk: route.params.id }, - order: ['started DESC'], - limit: 20, +const tableRef = ref(); +const filter = computed(() => { + return { + where: { clientFk: route.params.id }, + }; +}); +const componentColumn = (type) => { + return { + columnFilter: { + component: type, + }, + columnCreate: { + component: type, + }, + }; }; - -const tableColumnComponents = { - since: { - component: 'span', - props: () => {}, - event: () => {}, - }, - to: { - component: 'span', - props: () => {}, - event: () => {}, - }, - amount: { - component: 'span', - props: () => {}, - event: () => {}, - }, - period: { - component: 'span', - props: () => {}, - event: () => {}, - }, -}; - const columns = computed(() => [ { align: 'left', - field: 'started', - label: t('Since'), - name: 'since', - format: (value) => toDate(value), + label: t('globals.since'), + name: 'started', + format: ({ started }) => toDate(started), + create: true, + ...componentColumn('date'), }, { align: 'left', - field: 'finished', - label: t('To'), - name: 'to', - format: (value) => toDate(value), + name: 'finished', + label: t('globals.to'), + format: ({ finished }) => toDate(finished), + create: true, + ...componentColumn('date'), }, { align: 'left', - field: 'amount', - label: t('Amount'), name: 'amount', - format: (value) => toCurrency(value), + label: t('globals.amount'), + format: ({ amount }) => toCurrency(amount), + create: true, + ...componentColumn('number'), }, { align: 'left', - field: 'period', - label: t('Period'), name: 'period', + label: t('Period'), + create: true, + ...componentColumn('number'), + }, + { + align: 'left', + name: 'tableActions', + actions: [ + { + title: t('Finish that recovery period'), + icon: 'lock', + show: (row) => !row.finished, + action: ({ id }) => setFinished(id), + isPrimary: true, + }, + ], }, ]); -const toCustomerRecoverieCreate = () => { - router.push({ name: 'CustomerRecoverieCreate' }); -}; +function setFinished(id) { + axios.patch(`Recoveries/${id}`, { finished: Date.vnNow() }); + tableRef.value.reload(); +} </script> <template> - <FetchData - :filter="filter" - @on-fetch="(data) => (rows = data)" - auto-load + <VnTable + ref="tableRef" + data-key="Recoveries" url="Recoveries" + search-url="recoveries" + :filter="filter" + order="started DESC" + :columns="columns" + :use-model="true" + :right-search="false" + :create="{ + urlCreate: 'Recoveries', + title: 'New recovery', + onDataSaved: () => tableRef.reload(), + formInitialData: { clientFk: route.params.id, started: Date.vnNew() }, + }" + auto-load /> - - <div class="full-width flex justify-center"> - <QPage class="card-width q-pa-lg"> - <QTable - :columns="columns" - :no-data-label="t('globals.noResults')" - :pagination="{ rowsPerPage: 12 }" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - > - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is="tableColumnComponents[props.col.name].component" - class="col-content" - v-bind=" - tableColumnComponents[props.col.name].props(props) - " - @click=" - tableColumnComponents[props.col.name].event(props) - " - > - {{ props.value }} - </component> - </QTr> - </QTd> - </template> - </QTable> - </QPage> - </div> - - <QPageSticky :offset="[18, 18]"> - <QBtn @click.stop="toCustomerRecoverieCreate()" color="primary" fab icon="add" /> - <QTooltip> - {{ t('New recoverie') }} - </QTooltip> - </QPageSticky> </template> -<style lang="scss"> -.consignees-card { - border: 2px solid var(--vn-accent-color); - border-radius: 10px; - padding: 10px; -} - -.label-color { - color: var(--vn-label-color); -} -</style> - <i18n> es: - Since: Desde - To: Hasta - Amount: Importe Period: Periodo - New recoverie: Nuevo recobro + New recovery: Nuevo recobro + Finish that recovery period: Terminar recobro </i18n> diff --git a/src/pages/Customer/Card/CustomerSms.vue b/src/pages/Customer/Card/CustomerSms.vue index a567f6b47..0ad1f8168 100644 --- a/src/pages/Customer/Card/CustomerSms.vue +++ b/src/pages/Customer/Card/CustomerSms.vue @@ -1,17 +1,16 @@ <script setup> +import { computed } from 'vue'; import { useRoute } from 'vue-router'; import VnSms from 'src/components/ui/VnSms.vue'; const route = useRoute(); -const id = route.params.id; - -const where = { - clientFk: id, - ticketFk: null, -}; +const where = computed(() => { + return { + clientFk: route.params.id, + ticketFk: null, + }; +}); </script> <template> - <div class="column items-center"> - <VnSms url="clientSms" :where="where" /> - </div> + <VnSms url="clientSms" :where="where" /> </template> diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue index 86de5217e..15bf19b48 100644 --- a/src/pages/Customer/Card/CustomerSummary.vue +++ b/src/pages/Customer/Card/CustomerSummary.vue @@ -9,7 +9,7 @@ import VnLv from 'src/components/ui/VnLv.vue'; import VnLinkPhone from 'src/components/ui/VnLinkPhone.vue'; import CustomerSummaryTable from 'src/pages/Customer/components/CustomerSummaryTable.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; - +import VnRow from 'src/components/ui/VnRow.vue'; const route = useRoute(); const { t } = useI18n(); @@ -131,41 +131,33 @@ const creditWarning = computed(() => { :url="`#/customer/${entityId}/fiscal-data`" :text="t('customer.summary.fiscalData')" /> - <QCheckbox - :label="t('customer.summary.isEqualizated')" - v-model="entity.isEqualizated" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.isActive')" - v-model="entity.isActive" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.invoiceByAddress')" - v-model="entity.hasToInvoiceByAddress" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.verifiedData')" - v-model="entity.isTaxDataChecked" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.hasToInvoice')" - v-model="entity.hasToInvoice" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.notifyByEmail')" - v-model="entity.isToBeMailed" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.vies')" - v-model="entity.isVies" - :disable="true" - /> + <VnRow> + <VnLv + :label="t('customer.summary.isEqualizated')" + :value="entity.isEqualizated" + /> + <VnLv + :label="t('customer.summary.isActive')" + :value="entity.isActive" + /> + </VnRow> + <VnRow> + <VnLv + :label="t('customer.summary.verifiedData')" + :value="entity.isTaxDataChecked" + /> + <VnLv + :label="t('customer.summary.hasToInvoice')" + :value="entity.hasToInvoice" + /> + </VnRow> + <VnRow> + <VnLv + :label="t('customer.summary.notifyByEmail')" + :value="entity.isToBeMailed" + /> + <VnLv :label="t('customer.summary.vies')" :value="entity.isVies" /> + </VnRow> </QCard> <QCard class="vn-one"> <VnTitle @@ -178,23 +170,18 @@ const creditWarning = computed(() => { /> <VnLv :label="t('customer.summary.bankAccount')" :value="entity.iban" /> <VnLv :label="t('customer.summary.dueDay')" :value="entity.dueDay" /> - <QCheckbox - style="padding: 0" - :label="t('customer.summary.hasLcr')" - v-model="entity.hasLcr" - :disable="true" - /> - <QCheckbox - :label="t('customer.summary.hasCoreVnl')" - v-model="entity.hasCoreVnl" - :disable="true" - /> + <VnRow class="q-mt-sm" wrap> + <VnLv :label="t('customer.summary.hasLcr')" :value="entity.hasLcr" /> + <VnLv + :label="t('customer.summary.hasCoreVnl')" + :value="entity.hasCoreVnl" + /> - <QCheckbox - :label="t('customer.summary.hasB2BVnl')" - v-model="entity.hasSepaVnl" - :disable="true" - /> + <VnLv + :label="t('customer.summary.hasB2BVnl')" + :value="entity.hasSepaVnl" + /> + </VnRow> </QCard> <QCard class="vn-one" v-if="entity.defaultAddress"> <VnTitle diff --git a/src/pages/Customer/Card/CustomerUnpaid.vue b/src/pages/Customer/Card/CustomerUnpaid.vue index a9d4a3d66..5b9a6cde2 100644 --- a/src/pages/Customer/Card/CustomerUnpaid.vue +++ b/src/pages/Customer/Card/CustomerUnpaid.vue @@ -134,7 +134,7 @@ watch( <div class="full-width flex justify-center"> <QCard class="card-width q-pa-lg"> <QForm> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <QCheckbox :label="t('Unpaid client')" v-model="unpaidClient" /> </div> diff --git a/src/pages/Customer/Card/CustomerWebAccess.vue b/src/pages/Customer/Card/CustomerWebAccess.vue index 33659dd77..8d025a365 100644 --- a/src/pages/Customer/Card/CustomerWebAccess.vue +++ b/src/pages/Customer/Card/CustomerWebAccess.vue @@ -2,164 +2,81 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; - import axios from 'axios'; import { useQuasar } from 'quasar'; -import { useValidator } from 'src/composables/useValidator'; -import useNotify from 'src/composables/useNotify'; -import { useStateStore } from 'stores/useStateStore'; - -import FetchData from 'components/FetchData.vue'; import VnInput from 'src/components/common/VnInput.vue'; import CustomerChangePassword from 'src/pages/Customer/components/CustomerChangePassword.vue'; +import FormModel from 'components/FormModel.vue'; -const { notify } = useNotify(); const { t } = useI18n(); -const { validate } = useValidator(); const quasar = useQuasar(); const route = useRoute(); -const stateStore = useStateStore(); - -const active = ref(false); const canChangePassword = ref(0); -const email = ref(null); -const isLoading = ref(false); -const name = ref(null); -const usersPreviewRef = ref(null); -const user = ref([]); -const dataChanges = computed(() => { - return ( - user.value.active !== active.value || - user.value.email !== email.value || - user.value.name !== name.value - ); +const filter = computed(() => { + return { + fields: ['active', 'email', 'name'], + where: { id: route.params.id }, + }; }); -const filter = { where: { id: `${route.params.id}` } }; - const showChangePasswordDialog = () => { quasar.dialog({ component: CustomerChangePassword, componentProps: { id: route.params.id, - promise: usersPreviewRef.value.fetch(), }, }); }; -const setInitialData = () => { - if (user.value.length) { - active.value = user.value[0].active; - email.value = user.value[0].email; - name.value = user.value[0].name; - } -}; - -const onSubmit = async () => { - isLoading.value = true; - - const payload = { - active: active.value, - email: email.value, - name: name.value, - }; - try { - await axios.patch(`Clients/${route.params.id}/updateUser`, payload); - notify('globals.dataSaved', 'positive'); - if (usersPreviewRef.value) usersPreviewRef.value.fetch(); - } catch (error) { - notify('errors.create', 'negative'); - } finally { - isLoading.value = false; - } -}; +async function hasCustomerRole() { + const { data } = await axios(`Clients/${route.params.id}/hasCustomerRole`); + canChangePassword.value = data; +} </script> <template> - <FetchData + <FormModel + url="VnUsers/preview" + :url-update="`Clients/${route.params.id}/updateUser`" :filter="filter" - @on-fetch=" - (data) => { - user = data; - setInitialData(); + model="webAccess" + :mapper=" + ({ active, name, email }) => { + return { + active, + name, + email, + }; } " + @on-fetch="hasCustomerRole()" auto-load - ref="usersPreviewRef" - url="VnUsers/preview" - /> - <FetchData - :url="`Clients/${route.params.id}/hasCustomerRole`" - @on-fetch="(data) => (canChangePassword = data)" - auto-load - /> - - <Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()"> - <QBtnGroup push class="q-gutter-x-sm"> - <QBtn - :disabled="isLoading" - :label="t('globals.reset')" - :loading="isLoading" - @click="setInitialData" - color="primary" - flat - icon="restart_alt" - type="reset" + > + <template #form="{ data, validate }"> + <QCheckbox :label="t('Enable web access')" v-model="data.active" /> + <VnInput :label="t('User')" clearable v-model="data.name" /> + <VnInput + :label="t('Recovery email')" + :rules="validate('client.email')" + clearable + type="email" + v-model="data.email" + class="q-mt-sm" + :info="t('This email is used for user to regain access their account')" /> + </template> + <template #moreActions> <QBtn - :disabled="isLoading" :label="t('Change password')" - :loading="isLoading" - @click.stop="showChangePasswordDialog()" color="primary" - flat icon="edit" - v-if="canChangePassword" + :disable="!canChangePassword" + @click="showChangePasswordDialog()" /> - <QBtn - :disabled="isLoading || !dataChanges" - :label="t('globals.save')" - :loading="isLoading" - @click="onSubmit" - color="primary" - icon="save" - /> - </QBtnGroup> - </Teleport> - - <div class="full-width flex justify-center"> - <QCard class="card-width q-pa-lg"> - <QCardSection> - <QForm> - <QCheckbox :label="t('Enable web access')" v-model="active" /> - - <div class="q-px-sm"> - <VnInput :label="t('User')" clearable v-model="name" /> - <VnInput - :label="t('Recovery email')" - :rules="validate('client.email')" - clearable - type="email" - v-model="email" - class="q-mt-sm" - > - <template #append> - <QIcon name="info" class="cursor-pointer"> - <QTooltip>{{ - t( - 'This email is used for user to regain access their account' - ) - }}</QTooltip> - </QIcon> - </template> - </VnInput> - </div> - </QForm> - </QCardSection> - </QCard> - </div> + </template> + </FormModel> </template> <i18n> diff --git a/src/pages/Customer/CustomerCreate.vue b/src/pages/Customer/CustomerCreate.vue index 80bfd1efe..041c92d17 100644 --- a/src/pages/Customer/CustomerCreate.vue +++ b/src/pages/Customer/CustomerCreate.vue @@ -18,7 +18,6 @@ const initialData = reactive({ const workersOptions = ref([]); const businessTypesOptions = ref([]); -const postcodesOptions = ref([]); function handleLocation(data, location) { const { town, code, provinceFk, countryFk } = location ?? {}; @@ -48,7 +47,7 @@ function handleLocation(data, location) { url-create="Clients/createWithUser" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('Comercial name')" v-model="data.name" /> <VnSelect :label="t('Salesperson')" @@ -59,7 +58,7 @@ function handleLocation(data, location) { v-model="data.salesPersonFk" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Business type')" :options="businessTypesOptions" @@ -70,32 +69,31 @@ function handleLocation(data, location) { /> <QInput v-model="data.fi" :label="t('Tax number')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('Business name')" :rules="validate('client.socialName')" v-model="data.socialName" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('Street')" :rules="validate('client.street')" v-model="data.street" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.location" @update:model-value="(location) => handleLocation(data, location)" > </VnLocation> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput v-model="data.userName" :label="t('Web user')" /> <QInput :label="t('Email')" diff --git a/src/pages/Customer/CustomerList.vue b/src/pages/Customer/CustomerList.vue index a9e4d978e..82ad559ad 100644 --- a/src/pages/Customer/CustomerList.vue +++ b/src/pages/Customer/CustomerList.vue @@ -15,7 +15,6 @@ import { toDate } from 'src/filters'; const { t } = useI18n(); const router = useRouter(); -const postcodesOptions = ref([]); const tableRef = ref(); const columns = computed(() => [ @@ -42,9 +41,7 @@ const columns = computed(() => [ name: 'name', isTitle: true, create: true, - columnField: { - class: 'expand', - }, + columnClass: 'expand', }, { align: 'left', @@ -52,9 +49,7 @@ const columns = computed(() => [ label: t('customer.extendedList.tableVisibleColumns.socialName'), isTitle: true, create: true, - columnField: { - class: 'expand', - }, + columnClass: 'expand', }, { align: 'left', @@ -110,9 +105,9 @@ const columns = computed(() => [ component: null, after: { component: markRaw(VnLinkPhone), - attrs: (prop) => { + attrs: ({ model }) => { return { - 'phone-number': prop, + 'phone-number': model, }; }, }, @@ -136,9 +131,7 @@ const columns = computed(() => [ columnFilter: { inWhere: true, }, - columnField: { - class: 'expand', - }, + columnClass: 'expand', }, { align: 'left', @@ -420,7 +413,6 @@ function handleLocation(data, location) { <template #more-create-dialog="{ data }"> <VnLocation :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.location" @update:model-value="(location) => handleLocation(data, location)" /> diff --git a/src/pages/Customer/CustomerMain.vue b/src/pages/Customer/CustomerMain.vue deleted file mode 100644 index f0dc2e500..000000000 --- a/src/pages/Customer/CustomerMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Customer/Defaulter/CustomerDefaulter.vue b/src/pages/Customer/Defaulter/CustomerDefaulter.vue index 693b016fb..11f6362f8 100644 --- a/src/pages/Customer/Defaulter/CustomerDefaulter.vue +++ b/src/pages/Customer/Defaulter/CustomerDefaulter.vue @@ -1,9 +1,8 @@ <script setup> import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { QBtn, QCheckbox, useQuasar } from 'quasar'; +import { useQuasar } from 'quasar'; import { toCurrency, toDate, dateRange } from 'filters/index'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; import CustomerNotificationsFilter from './CustomerDefaulterFilter.vue'; import CustomerBalanceDueTotal from './CustomerBalanceDueTotal.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -11,8 +10,9 @@ import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.v import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnInput from 'src/components/common/VnInput.vue'; import CustomerDefaulterAddObservation from './CustomerDefaulterAddObservation.vue'; -import axios from 'axios'; +import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; +import VnTable from 'src/components/VnTable/VnTable.vue'; const { t } = useI18n(); const quasar = useQuasar(); @@ -21,175 +21,139 @@ const dataRef = ref(null); const balanceDueTotal = ref(0); const selected = ref([]); -const tableColumnComponents = { - clientFk: { - component: QBtn, - props: () => ({ flat: true, class: 'link', noCaps: true }), - event: () => {}, - }, - isWorker: { - component: QCheckbox, - props: (prop) => ({ - disable: true, - 'model-value': Boolean(prop.value), - }), - event: () => {}, - }, - salesPerson: { - component: QBtn, - props: () => ({ flat: true, class: 'link', noCaps: true }), - event: () => {}, - }, - departmentName: { - component: 'span', - props: () => {}, - event: () => {}, - }, - country: { - component: 'span', - props: () => {}, - event: () => {}, - }, - payMethod: { - component: 'span', - props: () => {}, - event: () => {}, - }, - balance: { - component: 'span', - props: () => {}, - event: () => {}, - }, - author: { - component: QBtn, - props: () => ({ flat: true, class: 'link', noCaps: true }), - event: () => {}, - }, - lastObservation: { - component: 'span', - props: () => {}, - event: () => {}, - }, - date: { - component: 'span', - props: () => {}, - event: () => {}, - }, - credit: { - component: 'span', - props: () => {}, - event: () => {}, - }, - from: { - component: 'span', - props: () => {}, - event: () => {}, - }, - finished: { - component: QCheckbox, - - props: (prop) => ({ - disable: true, - 'model-value': prop.value, - }), - event: () => {}, - }, -}; - const columns = computed(() => [ { align: 'left', - field: 'clientName', - label: t('Client'), name: 'clientFk', - sortable: true, + label: t('Client'), + columnFilter: { + component: 'select', + attrs: { + url: 'Clients', + fields: ['id', 'name'], + }, + }, }, { align: 'left', - field: ({ isWorker }) => Boolean(isWorker), - label: t('Is worker'), name: 'isWorker', + label: t('Is worker'), }, { align: 'left', - field: 'salesPersonName', + name: 'salesPersonFk', label: t('Salesperson'), - name: 'salesPerson', - sortable: true, + columnFilter: { + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesPerson' }, + useLike: false, + optionValue: 'id', + optionLabel: 'name', + optionFilter: 'firstName', + }, + }, }, { align: 'left', - field: 'departmentName', + name: 'departmentFk', label: t('Department'), - name: 'departmentName', - sortable: true, + columnFilter: { + component: 'select', + attrs: { + url: 'Departments', + fields: ['id', 'name'], + }, + }, }, { align: 'left', - field: 'country', + name: 'countryFk', label: t('Country'), - name: 'country', - sortable: true, + format: ({ country }) => country, + columnFilter: { + component: 'select', + attrs: { + url: 'Countries', + fields: ['id', 'name'], + }, + }, }, { align: 'left', - field: 'payMethod', - label: t('P. Method'), name: 'payMethod', - sortable: true, - tooltip: t('Pay method'), + label: t('P. Method'), + columnFilter: { + component: 'select', + attrs: { + url: 'Paymethods', + }, + }, }, { align: 'left', - field: ({ amount }) => toCurrency(amount), + name: 'amount', label: t('Balance D.'), - name: 'balance', - sortable: true, - tooltip: t('Balance due'), + format: ({ amount }) => toCurrency(amount), }, { align: 'left', - field: 'workerName', + name: 'workerFk', label: t('Author'), - name: 'author', - sortable: true, tooltip: t('Worker who made the last observation'), + columnFilter: { + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + useLike: false, + optionValue: 'id', + optionLabel: 'name', + optionFilter: 'firstName', + }, + }, }, { align: 'left', - field: 'observation', + name: 'observation', label: t('Last observation'), - name: 'lastObservation', - sortable: true, + columnClass: 'expand', }, { align: 'left', - field: ({ created }) => toDate(created), + name: 'created', label: t('L. O. Date'), - name: 'date', - sortable: true, + format: ({ created }) => toDate(created), tooltip: t('Last observation date'), + columnFilter: { + component: 'date', + }, }, { align: 'left', - field: ({ creditInsurance }) => toCurrency(creditInsurance), + name: 'creditInsurance', + format: ({ creditInsurance }) => toCurrency(creditInsurance), label: t('Credit I.'), - name: 'credit', - sortable: true, tooltip: t('Credit insurance'), + columnFilter: { + component: 'number', + }, }, { align: 'left', - field: ({ defaulterSinced }) => toDate(defaulterSinced), + name: 'defaulterSinced', + format: ({ defaulterSinced }) => toDate(defaulterSinced), label: t('From'), - name: 'from', - sortable: true, + columnFilter: { + component: 'date', + }, }, { align: 'left', - field: 'finished', - label: t('Has recover'), - name: 'finished', + label: t('Has recovery'), + name: 'hasRecovery', }, ]); @@ -198,22 +162,12 @@ const viewAddObservation = (rowsSelected) => { component: CustomerDefaulterAddObservation, componentProps: { clients: rowsSelected, - promise: async () => await dataRef.value.fetch(), + promise: async () => await dataRef.value.reload(), }, }); }; const onFetch = async (data) => { - const recoveryData = await axios.get('Recoveries'); - const recoveries = recoveryData.data.map(({ clientFk, finished }) => ({ - clientFk, - finished, - })); - - data.forEach((item) => { - const recovery = recoveries.find(({ clientFk }) => clientFk === item.clientFk); - item.finished = recovery?.finished === null; - }); balanceDueTotal.value = data.reduce((acc, { amount = 0 }) => acc + amount, 0); }; @@ -229,7 +183,7 @@ function exprBuilder(param, value) { case 'payMethod': case 'salesPersonFk': return { [`d.${param}`]: value }; - case 'date': + case 'created': return { 'd.created': { between: dateRange(value) } }; case 'defaulterSinced': return { 'd.defaulterSinced': { between: dateRange(value) } }; @@ -246,123 +200,64 @@ function exprBuilder(param, value) { <VnSubToolbar> <template #st-data> <CustomerBalanceDueTotal :amount="balanceDueTotal" /> - <div class="flex items-center q-ml-lg"> - <QBtn - color="primary" - icon="vn:notes" - :disabled="!selected.length" - @click.stop="viewAddObservation(selected)" - > - <QTooltip>{{ t('Add observation') }}</QTooltip> - </QBtn> - </div> + </template> + <template #st-actions> + <QBtn + color="primary" + icon="vn:notes" + :disabled="!selected.length" + @click.stop="viewAddObservation(selected)" + > + <QTooltip>{{ t('Add observation') }}</QTooltip> + </QBtn> </template> </VnSubToolbar> - <QPage class="column items-center q-pa-md"> - <VnPaginate - ref="dataRef" - @on-fetch="onFetch" - data-key="CustomerDefaulter" - :filter="filter" - :expr-builder="exprBuilder" - auto-load - url="Defaulters/filter" - > - <template #body="{ rows }"> - <div class="q-pa-md"> - <QTable - :columns="columns" - :rows="rows" - class="full-width" - row-key="clientFk" - selection="multiple" - v-model:selected="selected" - > - <template #header="props"> - <QTr :props="props" class="bg" style="min-height: 200px"> - <QTh> - <QCheckbox v-model="props.selected" /> - </QTh> - <QTh - v-for="col in props.cols" - :key="col.name" - :props="props" - > - {{ t(col.label) }} - <QTooltip v-if="col.tooltip">{{ - col.tooltip - }}</QTooltip> - </QTh> - </QTr> - </template> - - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is=" - tableColumnComponents[props.col.name] - .component - " - class="col-content" - v-bind=" - tableColumnComponents[props.col.name].props( - props - ) - " - @click=" - tableColumnComponents[props.col.name].event( - props - ) - " - > - <template v-if="typeof props.value !== 'boolean'"> - <div - v-if=" - props.col.name === 'lastObservation' - " - > - <VnInput - type="textarea" - v-model="props.value" - readonly - dense - rows="2" - /> - </div> - <div v-else>{{ props.value }}</div> - </template> - - <WorkerDescriptorProxy - :id="props.row.salesPersonFk" - v-if="props.col.name === 'salesPerson'" - /> - <WorkerDescriptorProxy - :id="props.row.workerFk" - v-if="props.col.name === 'author'" - /> - <CustomerDescriptorProxy - :id="props.row.clientFk" - v-if="props.col.name === 'client'" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> - </div> - </template> - </VnPaginate> - </QPage> + <VnTable + ref="dataRef" + data-key="CustomerDefaulter" + url="Defaulters/filter" + :expr-builder="exprBuilder" + :columns="columns" + @on-fetch="onFetch" + :use-model="true" + :table="{ + 'row-key': 'clientFk', + selection: 'multiple', + }" + v-model:selected="selected" + :disable-option="{ card: true }" + auto-load + :order="['amount DESC']" + > + <template #column-clientFk="{ row }"> + <span class="link" @click.stop> + {{ row.clientName }} + <CustomerDescriptorProxy :id="row.clientFk" /> + </span> + </template> + <template #column-observation="{ row }"> + <VnInput type="textarea" v-model="row.observation" readonly dense rows="2" /> + </template> + <template #column-salesPersonFk="{ row }"> + <span class="link" @click.stop> + {{ row.salesPersonName }} + <WorkerDescriptorProxy :id="row.salesPersonFk" /> + </span> + </template> + <template #column-departmentFk="{ row }"> + <span class="link" @click.stop> + {{ row.departmentName }} + <DepartmentDescriptorProxy :id="row.departmentFk" /> + </span> + </template> + <template #column-workerFk="{ row }"> + <span class="link" @click.stop> + {{ row.workerName }} + <WorkerDescriptorProxy :id="row.workerFk" /> + </span> + </template> + </VnTable> </template> - -<style lang="scss" scoped> -.col-content { - border-radius: 4px; - padding: 6px; -} -</style> - <i18n> es: Add observation: Añadir observación @@ -383,4 +278,5 @@ es: Credit I.: Crédito A. Credit insurance: Crédito asegurado From: Desde + Has recovery: Tiene recobro </i18n> diff --git a/src/pages/Customer/Defaulter/CustomerDefaulterAddObservation.vue b/src/pages/Customer/Defaulter/CustomerDefaulterAddObservation.vue index ef1e17e83..5798e7512 100644 --- a/src/pages/Customer/Defaulter/CustomerDefaulterAddObservation.vue +++ b/src/pages/Customer/Defaulter/CustomerDefaulterAddObservation.vue @@ -60,7 +60,7 @@ const onSubmit = async () => { }) }} </div> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('Message')" type="textarea" diff --git a/src/pages/Customer/Notifications/CustomerNotifications.vue b/src/pages/Customer/Notifications/CustomerNotifications.vue index 2b816b5d0..ce18739b4 100644 --- a/src/pages/Customer/Notifications/CustomerNotifications.vue +++ b/src/pages/Customer/Notifications/CustomerNotifications.vue @@ -1,92 +1,92 @@ <script setup> import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; -import { QBtn } from 'quasar'; -import CustomerNotificationsFilter from './CustomerNotificationsFilter.vue'; import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; import CustomerNotificationsCampaignConsumption from './CustomerNotificationsCampaignConsumption.vue'; -import RightMenu from 'src/components/common/RightMenu.vue'; +import VnTable from 'src/components/VnTable/VnTable.vue'; const { t } = useI18n(); +const dataKey = 'CustomerNotifications'; const selected = ref([]); -const selectedCustomerId = ref(0); - -const tableColumnComponents = { - id: { - component: QBtn, - props: () => ({ flat: true, color: 'blue' }), - event: (prop) => selectCustomerId(prop.row.id), - }, - socialName: { - component: 'span', - props: () => {}, - event: () => {}, - }, - city: { - component: 'span', - props: () => {}, - event: () => {}, - }, - phone: { - component: 'span', - props: () => {}, - event: () => {}, - }, - email: { - component: 'span', - props: () => {}, - event: () => {}, - }, -}; - const columns = computed(() => [ { align: 'left', - field: 'id', label: t('Identifier'), name: 'id', + columnClass: 'shrink', }, { align: 'left', - field: 'socialName', label: t('Social name'), name: 'socialName', + columnFilter: { + component: 'select', + attrs: { + url: 'Clients', + fields: ['id', 'socialName'], + optionLabel: 'socialName', + }, + }, + columnClass: 'expand', + isTitle: true, }, { align: 'left', - field: 'city', label: t('City'), name: 'city', + columnFilter: { + component: 'select', + attrs: { + url: 'Towns', + }, + }, + cardVisible: true, }, { align: 'left', - field: 'phone', label: t('Phone'), name: 'phone', + cardVisible: true, }, { align: 'left', - field: 'email', label: t('Email'), name: 'email', + cardVisible: true, + }, + { + align: 'left', + name: 'fi', + label: t('Fi'), + visible: false, + }, + { + align: 'left', + name: 'postcode', + label: t('Postcode'), + visible: false, + }, + { + align: 'left', + label: t('customer.extendedList.tableVisibleColumns.salesPersonFk'), + name: 'salesPersonFk', + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesPerson' }, + optionFilter: 'firstName', + useLike: false, + }, + visible: false, }, ]); - -const selectCustomerId = (id) => { - selectedCustomerId.value = id; -}; </script> <template> - <RightMenu> - <template #right-panel> - <CustomerNotificationsFilter data-key="CustomerNotifications" /> - </template> - </RightMenu> <VnSubToolbar class="justify-end"> - <template #st-data> + <template #st-actions> <CustomerNotificationsCampaignConsumption :selected-rows="selected.length > 0" :clients="selected" @@ -94,51 +94,26 @@ const selectCustomerId = (id) => { /> </template> </VnSubToolbar> - <QPage class="column items-center q-pa-md"> - <VnPaginate data-key="CustomerNotifications" url="Clients" auto-load> - <template #body="{ rows }"> - <div class="q-pa-md"> - <QTable - :columns="columns" - :rows="rows" - class="full-width q-mt-md" - row-key="id" - selection="multiple" - v-model:selected="selected" - > - <template #body-cell="props"> - <QTd :props="props"> - <QTr :props="props" class="cursor-pointer"> - <component - :is=" - tableColumnComponents[props.col.name] - .component - " - class="col-content" - v-bind=" - tableColumnComponents[props.col.name].props( - props - ) - " - @click=" - tableColumnComponents[props.col.name].event( - props - ) - " - > - {{ props.value }} - <CustomerDescriptorProxy - :id="selectedCustomerId" - /> - </component> - </QTr> - </QTd> - </template> - </QTable> - </div> - </template> - </VnPaginate> - </QPage> + <VnTable + :data-key="dataKey" + url="Clients" + :table="{ + 'row-key': 'id', + selection: 'multiple', + }" + v-model:selected="selected" + :right-search="true" + :columns="columns" + :use-model="true" + auto-load + > + <template #column-id="{ row }"> + <span class="link"> + {{ row.id }} + <CustomerDescriptorProxy :id="row.id" /> + </span> + </template> + </VnTable> </template> <style lang="scss" scoped> diff --git a/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue b/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue index 6d8e00966..6952379ca 100644 --- a/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue +++ b/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue @@ -99,7 +99,7 @@ onMounted(async () => { <QPopupProxy ref="popupProxyRef"> <QCard class="column q-pa-md"> <span class="text-body1 q-mb-sm">{{ t('Campaign consumption') }}</span> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :options="moreFields" option-value="code" @@ -109,7 +109,7 @@ onMounted(async () => { @update:model-value="campaignChange" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate v-model="campaignParams.from" :label="t('From')" /> <VnInputDate v-model="campaignParams.to" :label="t('To')" /> </VnRow> diff --git a/src/pages/Customer/Notifications/CustomerNotificationsFilter.vue b/src/pages/Customer/Notifications/CustomerNotificationsFilter.vue deleted file mode 100644 index a7c8635e7..000000000 --- a/src/pages/Customer/Notifications/CustomerNotificationsFilter.vue +++ /dev/null @@ -1,145 +0,0 @@ -<script setup> -import { ref } from 'vue'; -import { useI18n } from 'vue-i18n'; - -import FetchData from 'components/FetchData.vue'; -import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'components/common/VnSelect.vue'; - -const { t } = useI18n(); -const props = defineProps({ - dataKey: { - type: String, - required: true, - }, -}); - -const cities = ref(); -const clients = ref(); -</script> - -<template> - <FetchData - :filter="{ where: { role: 'socialName' } }" - @on-fetch="(data) => (clients = data)" - auto-load - url="Clients" - /> - <FetchData @on-fetch="(data) => (cities = data)" auto-load url="Towns" /> - <VnFilterPanel :data-key="props.dataKey" :search-button="true"> - <template #tags="{ tag, formatFn }"> - <div class="q-gutter-x-xs"> - <strong>{{ t(`params.${tag.label}`) }}: </strong> - <span>{{ formatFn(tag.value) }}</span> - </div> - </template> - - <template #body="{ params, searchFn }"> - <QItem class="q-mb-sm q-mt-sm"> - <QItemSection> - <VnInput - :label="t('Identifier')" - clearable - is-outlined - v-model="params.identifier" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection v-if="!clients"> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - <QItemSection v-if="clients"> - <VnSelect - :input-debounce="0" - :label="t('Social name')" - :options="clients" - @update:model-value="searchFn()" - dense - emit-value - hide-selected - map-options - option-label="socialName" - option-value="socialName" - outlined - rounded - use-input - v-model="params.socialName" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection v-if="!cities"> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - <QItemSection v-if="cities"> - <VnSelect - :input-debounce="0" - :label="t('City')" - :options="cities" - @update:model-value="searchFn()" - dense - emit-value - hide-selected - map-options - option-label="name" - option-value="name" - outlined - rounded - use-input - v-model="params.city" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection> - <VnInput - :label="t('Phone')" - clearable - is-outlined - v-model="params.phone" - /> - </QItemSection> - </QItem> - - <QItem class="q-mb-sm"> - <QItemSection> - <VnInput - :label="t('Email')" - clearable - is-outlined - type="email" - v-model="params.email" - /> - </QItemSection> - </QItem> - <QSeparator /> - </template> - </VnFilterPanel> -</template> - -<i18n> -en: - params: - identifier: Identifier - socialName: Social name - city: City - phone: Phone - email: Email -es: - params: - identifier: Identificador - socialName: Razón social - city: Población - phone: Teléfono - email: Email - Identifier: Identificador - Social name: Razón social - City: Población - Phone: Teléfono - Email: Email -</i18n> diff --git a/src/pages/Customer/Payments/CustomerPayments.vue b/src/pages/Customer/Payments/CustomerPayments.vue index cd2642c57..25dfcc58a 100644 --- a/src/pages/Customer/Payments/CustomerPayments.vue +++ b/src/pages/Customer/Payments/CustomerPayments.vue @@ -1,19 +1,18 @@ <script setup> import axios from 'axios'; -import { ref, computed } from 'vue'; +import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; -import { useArrayData } from 'composables/useArrayData'; -import VnPaginate from 'components/ui/VnPaginate.vue'; +import { toDate, toCurrency } from 'filters/index'; + +import VnTable from 'src/components/VnTable/VnTable.vue'; import VnConfirm from 'components/ui/VnConfirm.vue'; import CustomerDescriptorProxy from '../Card/CustomerDescriptorProxy.vue'; -import { toDate, toCurrency } from 'filters/index'; import CustomerPaymentsFilter from './CustomerPaymentsFilter.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; const quasar = useQuasar(); const { t } = useI18n(); -const arrayData = useArrayData('CustomerTransactions'); async function confirm(transaction) { quasar @@ -36,59 +35,73 @@ async function confirmTransaction({ id }) { }); } -const grid = ref(false); const columns = computed(() => [ { name: 'id', label: t('Transaction ID'), - field: (row) => row.id, - sortable: true, - }, - { - name: 'customerId', - label: t('Customer ID'), - field: (row) => row.clientFk, - align: 'right', - sortable: true, - }, - { - name: 'customer', - label: t('Customer Name'), - field: (row) => row.customerName, - }, - { - name: 'state', - label: t('State'), - field: (row) => row.isConfirmed, - format: (value) => (value ? t('Confirmed') : t('Unconfirmed')), + isTitle: true, align: 'left', - sortable: true, + columnFilter: { + inWhere: true, + alias: 't', + }, + columnClass: 'shrink', }, { - name: 'dated', + align: 'left', + name: 'clientFk', + label: t('Customer'), + columnFilter: { + component: 'select', + attrs: { + url: 'Clients', + fields: ['id', 'name'], + }, + }, + columnClass: 'expand', + cardVisible: true, + }, + { + name: 'isConfirmed', + label: t('State'), + align: 'left', + format: ({ isConfirmed }) => (isConfirmed ? t('Confirmed') : t('Unconfirmed')), + chip: { + condition: () => true, + color: ({ isConfirmed }) => (isConfirmed ? 'bg-positive' : 'bg-primary'), + }, + visible: false, + }, + { + name: 'created', label: t('Dated'), - field: (row) => toDate(row.created), - sortable: true, + format: ({ created }) => toDate(created), + columnFilter: false, + cardVisible: true, }, { name: 'amount', label: t('Amount'), - field: (row) => row.amount, - format: (value) => toCurrency(value), - sortable: true, + format: ({ amount }) => toCurrency(amount), + columnFilter: { + component: 'number', + }, + cardVisible: true, }, { - name: 'actions', - label: t('Actions'), - grid: false, + align: 'right', + name: 'tableActions', + actions: [ + { + title: t('Confirm transaction'), + icon: 'check', + action: (row) => confirm(row), + show: ({ isConfirmed }) => !isConfirmed, + isPrimary: true, + }, + ], }, ]); -const isLoading = computed(() => arrayData.isLoading.value); - -function stateColor(row) { - if (row.isConfirmed) return 'positive'; - return 'primary'; -} </script> <template> @@ -97,158 +110,22 @@ function stateColor(row) { <CustomerPaymentsFilter data-key="CustomerTransactions" /> </template> </RightMenu> - <QPage class="column items-center q-pa-md customer-payments"> - <div class="vn-card-list"> - <QToolbar class="q-pa-none justify-end"> - <QBtn - @click="arrayData.refresh()" - :loading="isLoading" - icon="refresh" - color="primary" - class="q-mr-sm" - round - dense - /> - <QBtn @click="grid = !grid" icon="list" color="primary" round dense> - <QTooltip>{{ t('Change view') }}</QTooltip> - </QBtn> - </QToolbar> - <VnPaginate - data-key="CustomerTransactions" - url="Clients/transactions" - order="created DESC" - :limit="20" - :offset="50" - :auto-load="!!$route?.query.params" - > - <template #body="{ rows }"> - <QTable - :dense="$q.screen.lt.md" - :columns="columns" - :rows="rows" - row-key="id" - :grid="grid || $q.screen.lt.sm" - class="q-mt-xs custom-table" - > - <template #body-cell-actions="{ row }"> - <QTd auto-width class="text-center"> - <QBtn - v-if="!row.isConfirmed" - icon="check" - @click="confirm(row)" - color="primary" - size="md" - round - flat - dense - > - <QTooltip>{{ t('Confirm transaction') }}</QTooltip> - </QBtn> - </QTd> - </template> - <template #body-cell-id="{ row }"> - <QTd auto-width align="right"> - <span> - {{ row.id }} - </span> - </QTd> - </template> - <template #body-cell-customerId="{ row }"> - <QTd align="right"> - <span class="link"> - {{ row.clientFk }} - <CustomerDescriptorProxy :id="row.clientFk" /> - </span> - </QTd> - </template> - <template #body-cell-customer="{ row }"> - <QTd auto-width align="left" :title="row.customerName"> - <span> - {{ row.customerName }} - </span> - </QTd> - </template> - <template #body-cell-state="{ row }"> - <QTd auto-width class="text-center"> - <QBadge text-color="black" :color="stateColor(row)"> - {{ - row.isConfirmed - ? t('Confirmed') - : t('Unconfirmed') - }} - </QBadge> - </QTd> - </template> - <template #item="{ cols, row }"> - <div class="q-mb-md col-12"> - <QCard class="q-pa-none"> - <QItem class="q-pa-none items-start"> - <QItemSection class="q-pa-none"> - <QList> - <template - v-for="col of cols" - :key="col.name" - > - <QItem - v-if="col.grid !== false" - class="q-pa-none" - > - <QItemSection> - <QItemLabel caption> - {{ col.label }} - </QItemLabel> - <QItemLabel - v-if="col.name == 'state'" - > - <QBadge - text-color="black" - :color=" - stateColor(row) - " - > - {{ col.value }} - </QBadge> - </QItemLabel> - <QItemLabel - v-if="col.name != 'state'" - > - {{ col.value }} - </QItemLabel> - </QItemSection> - </QItem> - </template> - </QList> - </QItemSection> - <template v-if="!row.isConfirmed"> - <QSeparator vertical /> - <QCardActions - vertical - class="justify-between" - > - <QBtn - icon="check" - @click="confirm(row)" - color="primary" - size="md" - round - flat - dense - > - <QTooltip> - {{ t('Confirm transaction') }} - </QTooltip> - </QBtn> - </QCardActions> - </template> - </QItem> - </QCard> - </div> - </template> - </QTable> - </template> - </VnPaginate> - </div> - </QPage> + <VnTable + data-key="CustomerTransactions" + url="Clients/transactions" + order="created DESC" + :columns="columns" + :right-search="false" + auto-load + > + <template #column-clientFk="{ row }"> + <span class="link"> + {{ row.clientFk }} - + {{ row.customerName }} + <CustomerDescriptorProxy :id="row.clientFk" /> + </span> + </template> + </VnTable> </template> <style lang="scss"> @@ -269,14 +146,11 @@ es: Web Payments: Pagos Web Confirm transaction: Confirmar transacción Transaction ID: ID transacción - Customer ID: ID cliente - Customer Name: Nombre cliente + Customer: cliente State: Estado Dated: Fecha Amount: Importe - Actions: Acciones Confirmed: Confirmada Unconfirmed: Sin confirmar - Change view: Cambiar vista Payment confirmed: Pago confirmado </i18n> diff --git a/src/pages/Customer/Payments/CustomerPaymentsFilter.vue b/src/pages/Customer/Payments/CustomerPaymentsFilter.vue index 1b79868c0..8982cba5a 100644 --- a/src/pages/Customer/Payments/CustomerPaymentsFilter.vue +++ b/src/pages/Customer/Payments/CustomerPaymentsFilter.vue @@ -3,7 +3,7 @@ import { useI18n } from 'vue-i18n'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const props = defineProps({ @@ -47,7 +47,11 @@ const props = defineProps({ </QItem> <QItem> <QItemSection> - <VnCurrency v-model="params.amount" is-outlined /> + <VnInputNumber + :label="t('Amount')" + v-model="params.amount" + is-outlined + /> </QItemSection> </QItem> <QItem> diff --git a/src/pages/Customer/components/CustomerAddressCreate.vue b/src/pages/Customer/components/CustomerAddressCreate.vue index 57997fb01..30e4b21d0 100644 --- a/src/pages/Customer/components/CustomerAddressCreate.vue +++ b/src/pages/Customer/components/CustomerAddressCreate.vue @@ -21,7 +21,6 @@ const formInitialData = reactive({ isDefaultAddress: false }); const urlCreate = ref(''); -const postcodesOptions = ref([]); const agencyModes = ref([]); const incoterms = ref([]); const customsAgents = ref([]); @@ -85,7 +84,7 @@ function handleLocation(data, location) { <template #form="{ data, validate }"> <QCheckbox :label="t('Default')" v-model="data.isDefaultAddress" /> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Consignee')" clearable v-model="data.nickname" /> <VnInput :label="t('Street address')" clearable v-model="data.street" /> @@ -94,7 +93,6 @@ function handleLocation(data, location) { <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.location" @update:model-value="(location) => handleLocation(data, location)" /> @@ -119,7 +117,7 @@ function handleLocation(data, location) { /> </div> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Incoterms')" :options="incoterms" diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue index 2d14b571e..7a4c44014 100644 --- a/src/pages/Customer/components/CustomerAddressEdit.vue +++ b/src/pages/Customer/components/CustomerAddressEdit.vue @@ -18,7 +18,6 @@ const route = useRoute(); const router = useRouter(); const urlUpdate = ref(''); -const postcodesOptions = ref([]); const agencyModes = ref([]); const incoterms = ref([]); const customsAgents = ref([]); @@ -146,7 +145,7 @@ function handleLocation(data, location) { </template> <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <QCheckbox :label="t('Enabled')" v-model="data.isActive" /> </div> @@ -164,7 +163,7 @@ function handleLocation(data, location) { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Consignee')" clearable v-model="data.nickname" /> </div> @@ -173,19 +172,18 @@ function handleLocation(data, location) { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.postalCode" @update:model-value="(location) => handleLocation(data, location)" ></VnLocation> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('Agency')" @@ -204,7 +202,7 @@ function handleLocation(data, location) { <VnInput :label="t('Mobile')" clearable v-model="data.mobile" /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('Incoterms')" diff --git a/src/pages/Customer/components/CustomerCreditContractsCreate.vue b/src/pages/Customer/components/CustomerCreditContractsCreate.vue index d902e7a97..c4434e870 100644 --- a/src/pages/Customer/components/CustomerCreditContractsCreate.vue +++ b/src/pages/Customer/components/CustomerCreditContractsCreate.vue @@ -39,7 +39,7 @@ const toCustomerCreditContracts = () => { </template> <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Credit')" diff --git a/src/pages/Customer/components/CustomerCreditCreate.vue b/src/pages/Customer/components/CustomerCreditCreate.vue deleted file mode 100644 index 729deb258..000000000 --- a/src/pages/Customer/components/CustomerCreditCreate.vue +++ /dev/null @@ -1,67 +0,0 @@ -<script setup> -import { ref } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - -import FetchData from 'components/FetchData.vue'; -import FormModel from 'components/FormModel.vue'; - -const { t } = useI18n(); -const route = useRoute(); -const router = useRouter(); - -const initialData = ref({}); - -const setClient = (data) => { - initialData.value.credit = data.credit; -}; - -const toCustomerCredits = () => { - router.push({ - name: 'CustomerCredits', - params: { - id: route.params.id, - }, - }); -}; -</script> - -<template> - <FetchData - :filter="filter" - @on-fetch="setClient" - auto-load - :url="`Clients/${route.params.id}/getCard`" - /> - - <FormModel - :form-initial-data="initialData" - :observe-form-changes="false" - :url-update="`/Clients/${route.params.id}`" - @on-data-saved="toCustomerCredits()" - > - <template #moreActions> - <QBtn - :label="t('globals.cancel')" - @click="toCustomerCredits" - color="primary" - flat - icon="close" - /> - </template> - - <template #form="{ data }"> - <QInput - :label="t('Credit')" - clearable - type="number" - v-model.number="data.credit" - /> - </template> - </FormModel> -</template> - -<i18n> -es: - Credit: Crédito -</i18n> diff --git a/src/pages/Customer/components/CustomerFileManagementCreate.vue b/src/pages/Customer/components/CustomerFileManagementCreate.vue index bc218d1b2..7c15e0b71 100644 --- a/src/pages/Customer/components/CustomerFileManagementCreate.vue +++ b/src/pages/Customer/components/CustomerFileManagementCreate.vue @@ -143,7 +143,7 @@ const toCustomerFileManagement = () => { <QCard class="q-pa-lg"> <QCardSection> <QForm> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Reference')" @@ -163,7 +163,7 @@ const toCustomerFileManagement = () => { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('Warehouse')" @@ -184,7 +184,7 @@ const toCustomerFileManagement = () => { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Description')" @@ -196,7 +196,7 @@ const toCustomerFileManagement = () => { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <QFile ref="inputFileRef" diff --git a/src/pages/Customer/components/CustomerFileManagementEdit.vue b/src/pages/Customer/components/CustomerFileManagementEdit.vue index d21305e32..80eaa44f9 100644 --- a/src/pages/Customer/components/CustomerFileManagementEdit.vue +++ b/src/pages/Customer/components/CustomerFileManagementEdit.vue @@ -119,7 +119,7 @@ const toCustomerFileManagement = () => { <QCard class="q-pa-lg"> <QCardSection> <QForm> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Reference')" @@ -139,7 +139,7 @@ const toCustomerFileManagement = () => { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('Warehouse')" @@ -160,7 +160,7 @@ const toCustomerFileManagement = () => { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Description')" @@ -172,7 +172,7 @@ const toCustomerFileManagement = () => { </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <QFile ref="inputFileRef" diff --git a/src/pages/Customer/components/CustomerGreugeCreate.vue b/src/pages/Customer/components/CustomerGreugeCreate.vue deleted file mode 100644 index fc315d808..000000000 --- a/src/pages/Customer/components/CustomerGreugeCreate.vue +++ /dev/null @@ -1,97 +0,0 @@ -<script setup> -import { onMounted, reactive, ref } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - -import FetchData from 'components/FetchData.vue'; -import FormModel from 'components/FormModel.vue'; -import VnRow from 'components/ui/VnRow.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnInputDate from 'components/common/VnInputDate.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; - -const { t } = useI18n(); -const route = useRoute(); -const router = useRouter(); - -const initialData = reactive({ - shipped: '2001-01-01T11:00:00.000Z', -}); - -const greugeTypes = ref([]); - -onMounted(() => { - initialData.clientFk = `${route.params.id}`; -}); - -const toCustomerGreuges = () => { - router.push({ - name: 'CustomerGreuges', - params: { - id: route.params.id, - }, - }); -}; -</script> - -<template> - <fetch-data @on-fetch="(data) => (greugeTypes = data)" auto-load url="greugeTypes" /> - - <FormModel - :form-initial-data="initialData" - :observe-form-changes="false" - @on-data-saved="toCustomerGreuges()" - model="client" - url-create="Greuges" - > - <template #moreActions> - <QBtn - :label="t('globals.cancel')" - @click="toCustomerGreuges" - color="primary" - flat - icon="close" - /> - </template> - - <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> - <VnInput - :label="t('Amount')" - clearable - type="number" - v-model="data.amount" - /> - <VnInputDate :label="t('Date')" v-model="data.shipped" /> - </VnRow> - - <VnRow class="row q-gutter-md q-mb-md"> - <VnInput :label="t('Comment')" clearable v-model="data.description" /> - <VnSelect - :label="t('Type')" - :options="greugeTypes" - hide-selected - option-label="name" - option-value="id" - v-model="data.greugeTypeFk" - /> - </VnRow> - </template> - </FormModel> -</template> - -<style lang="scss" scoped> -.add-icon { - cursor: pointer; - background-color: $primary; - border-radius: 50px; -} -</style> - -<i18n> -es: - Amount: Importe - Date: Fecha - Comment: Comentario - Type: Tipo -</i18n> diff --git a/src/pages/Customer/components/CustomerNewCustomsAgent.vue b/src/pages/Customer/components/CustomerNewCustomsAgent.vue index 3c95dcae6..ec9806334 100644 --- a/src/pages/Customer/components/CustomerNewCustomsAgent.vue +++ b/src/pages/Customer/components/CustomerNewCustomsAgent.vue @@ -22,7 +22,7 @@ const onDataSaved = (dataSaved) => { url-create="CustomsAgents" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('NIF')" :required="true" @@ -36,7 +36,7 @@ const onDataSaved = (dataSaved) => { v-model="data.fiscalName" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Street')" clearable v-model="data.street" /> <VnInput :label="t('Phone')" clearable v-model="data.phone" /> </VnRow> diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue index cc92d7907..16dd28767 100644 --- a/src/pages/Customer/components/CustomerNewPayment.vue +++ b/src/pages/Customer/components/CustomerNewPayment.vue @@ -2,18 +2,24 @@ import { onBeforeMount, reactive, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; +import axios from 'axios'; import { useDialogPluginComponent } from 'quasar'; +import { usePrintService } from 'composables/usePrintService'; +import useNotify from 'src/composables/useNotify.js'; import FetchData from 'components/FetchData.vue'; import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; +import VnInputNumber from 'components/common/VnInputNumber.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnInput from 'src/components/common/VnInput.vue'; const { t } = useI18n(); const route = useRoute(); +const { notify } = useNotify(); +const { sendEmail, openReport } = usePrintService(); const { dialogRef } = useDialogPluginComponent(); const $props = defineProps({ @@ -27,7 +33,7 @@ const $props = defineProps({ }, promise: { type: Function, - required: true, + default: null, }, }); @@ -36,11 +42,12 @@ const urlCreate = ref([]); const companyOptions = ref([]); const bankOptions = ref([]); const clientFindOne = ref([]); -const deliveredAmount = ref(null); -const amountToReturn = ref(null); -const viewRecipt = ref(true); -const sendEmail = ref(false); -const isLoading = ref(false); +const viewReceipt = ref(); +const shouldSendEmail = ref(false); +const maxAmount = ref(); +const accountingType = ref({}); +const isCash = ref(false); +const formModelRef = ref(false); const filterBanks = { fields: ['id', 'bank', 'accountingTypeFk'], @@ -67,65 +74,123 @@ onBeforeMount(() => { urlCreate.value = `Clients/${route.params.id}/createReceipt`; }); -const setPaymentType = (id) => { - initialData.payed = '2001-01-01T11:00:00.000Z'; - if (id === 1) initialData.description = 'Credit card'; - if (id === 2) initialData.description = 'Cash'; - if (id === 3 || id === 3117) initialData.description = ''; - if (id === 4) initialData.description = 'Transfer'; -}; +function setPaymentType(accounting) { + if (!accounting) return; + accountingType.value = accounting.accountingType; + + initialData.description = []; + initialData.payed = Date.vnNew(); + isCash.value = accountingType.value.code == 'cash'; + viewReceipt.value = isCash.value; + if (accountingType.value.daysInFuture) + initialData.payed.setDate( + initialData.payed.getDate() + accountingType.value.daysInFuture + ); + maxAmount.value = accountingType.value && accountingType.value.maxAmount; + + if (accountingType.value.code == 'compensation') + return (initialData.description = ''); + if (accountingType.value.receiptDescription) + initialData.description.push(accountingType.value.receiptDescription); + if (initialData.description) initialData.description.push(initialData.description); + + initialData.description = initialData.description.join(', '); +} const calculateFromAmount = (event) => { - amountToReturn.value = parseFloat(event) * -1 + parseFloat(deliveredAmount.value); + initialData.amountToReturn = + parseFloat(initialData.deliveredAmount) + parseFloat(event) * -1; }; const calculateFromDeliveredAmount = (event) => { - amountToReturn.value = parseFloat($props.totalCredit) * -1 + parseFloat(event); + initialData.amountToReturn = parseFloat(event) - initialData.amountPaid; }; -const setClientEmail = (data) => { - initialData.email = data.email; -}; +function onBeforeSave(data) { + const exceededAmount = data.amountPaid > maxAmount.value; + if (isCash.value && exceededAmount) + return notify(t('Amount exceeded', { maxAmount: maxAmount.value }), 'negative'); -const onDataSaved = async () => { - isLoading.value = true; - if ($props.promise) { - try { - await $props.promise(); - } finally { - isLoading.value = false; - if (closeButton.value) closeButton.value.click(); - } + if (isCash.value && shouldSendEmail.value && !data.email) + return notify(t('There is no assigned email for this client'), 'negative'); + + data.bankFk = data.bankFk.id; + return data; +} + +async function onDataSaved(formData, { id }) { + try { + if (shouldSendEmail.value && isCash.value) + await sendEmail(`Receipts/${id}/receipt-email`, { + recipient: formData.email, + }); + + if (viewReceipt.value) openReport(`Receipts/${id}/receipt-pdf`); + } finally { + if ($props.promise) $props.promise(); + if (closeButton.value) closeButton.value.click(); } -}; +} + +async function accountShortToStandard({ target: { value } }) { + if (!value) return (initialData.description = ''); + initialData.compensationAccount = value.replace('.', '0'.repeat(11 - value.length)); + const params = { bankAccount: initialData.compensationAccount }; + const { data } = await axios(`Clients/getClientOrSupplierReference`, { params }); + if (!data.clientId) { + initialData.description = t('Supplier Compensation Reference', { + supplierId: data.supplierId, + supplierName: data.supplierName, + }); + return; + } + initialData.description = t('Client Compensation Reference', { + clientId: data.clientId, + clientName: data.clientName, + }); +} + +async function getAmountPaid() { + const filter = { + where: { + clientFk: route.params.id, + companyFk: initialData.companyFk, + }, + }; + + const { data } = await axios(`ClientRisks`, { + params: { filter: JSON.stringify(filter) }, + }); + initialData.amountPaid = (data?.length && data[0].amount) || undefined; +} </script> <template> - <QDialog ref="dialogRef"> - <fetch-data + <QDialog ref="dialogRef" persistent> + <FetchData @on-fetch="(data) => (companyOptions = data)" auto-load url="Companies" /> - <fetch-data + <FetchData :filter="filterBanks" @on-fetch="(data) => (bankOptions = data)" auto-load url="Accountings" /> - <fetch-data + <FetchData :filter="filterClientFindOne" - @on-fetch="setClientEmail" + @on-fetch="({ email }) => (initialData.email = email)" auto-load url="Clients/findOne" /> - <FormModel - :default-actions="false" + ref="formModelRef" :form-initial-data="initialData" :observe-form-changes="false" :url-create="urlCreate" - @on-data-saved="onDataSaved()" + :mapper="onBeforeSave" + @on-data-saved="onDataSaved" > <template #form="{ data, validate }"> <span ref="closeButton" class="row justify-end close-icon" v-close-popup> @@ -134,7 +199,7 @@ const onDataSaved = async () => { <h5 class="q-mt-none">{{ t('New payment') }}</h5> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate :label="t('Date')" :required="true" @@ -149,19 +214,22 @@ const onDataSaved = async () => { option-label="code" option-value="id" v-model="data.companyFk" + @update:model-value="getAmountPaid()" /> </VnRow> - - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Bank')" - :options="bankOptions" - :required="true" - @update:model-value="setPaymentType($event)" - hide-selected - option-label="bank" - option-value="id" v-model="data.bankFk" + url="Accountings" + option-label="bank" + :include="{ relation: 'accountingType' }" + sort-by="id" + :limit="0" + @update:model-value=" + (value, options) => setPaymentType(value, options) + " + :emit-value="false" > <template #option="scope"> <QItem v-bind="scope.itemProps"> @@ -178,62 +246,54 @@ const onDataSaved = async () => { :required="true" @update:model-value="calculateFromAmount($event)" clearable - type="number" v-model.number="data.amountPaid" /> </VnRow> - - <div class="text-h6" v-if="data.bankFk === 3 || data.bankFk === 3117"> - {{ t('Compensation') }} - </div> - - <VnRow class="row q-gutter-md q-mb-md"> - <div class="col" v-if="data.bankFk === 3 || data.bankFk === 3117"> + <div v-if="data.bankFk?.accountingType?.code == 'compensation'"> + <div class="text-h6"> + {{ t('Compensation') }} + </div> + <VnRow> <VnInput :label="t('Compensation account')" clearable v-model="data.compensationAccount" + @blur="accountShortToStandard" /> - </div> - <VnInput - :label="t('Reference')" - :required="true" - clearable - v-model="data.description" - /> - </VnRow> + </VnRow> + </div> + <VnInput + :label="t('Reference')" + :required="true" + clearable + v-model="data.description" + /> - <div class="q-mt-lg" v-if="data.bankFk === 2"> + <div v-if="data.bankFk?.accountingType?.code == 'cash'"> <div class="text-h6">{{ t('Cash') }}</div> - - <VnRow class="row q-gutter-md q-mb-md"> - <VnInput + <VnRow> + <VnInputNumber :label="t('Delivered amount')" @update:model-value="calculateFromDeliveredAmount($event)" clearable - type="number" - v-model="deliveredAmount" + v-model="data.deliveredAmount" /> - <VnInput + <VnInputNumber :label="t('Amount to return')" - clearable disable - type="number" - v-model="amountToReturn" + v-model="data.amountToReturn" /> </VnRow> - - <VnRow class="row q-gutter-md q-mb-md"> - <QCheckbox v-model="viewRecipt" /> - <QCheckbox v-model="sendEmail" /> + <VnRow> + <QCheckbox v-model="viewReceipt" :label="t('View recipt')" /> + <QCheckbox v-model="shouldSendEmail" :label="t('Send email')" /> </VnRow> </div> - <div class="q-mt-lg row justify-end"> <QBtn - :disabled="isLoading" + :disabled="formModelRef.isLoading" :label="t('globals.cancel')" - :loading="isLoading" + :loading="formModelRef.isLoading" class="q-ml-sm" color="primary" flat @@ -241,9 +301,9 @@ const onDataSaved = async () => { v-close-popup /> <QBtn - :disabled="isLoading" + :disabled="formModelRef.isLoading" :label="t('globals.save')" - :loading="isLoading" + :loading="formModelRef.isLoading" color="primary" type="submit" /> @@ -268,4 +328,8 @@ es: Send email: Enviar correo Compensation: Compensación Compensation account: Cuenta para compensar + Supplier Compensation Reference: ({supplierId}) Ntro Proveedor {supplierName} + Client Compensation Reference: ({clientId}) Ntro Cliente {clientName} + There is no assigned email for this client: No hay correo asignado para este cliente + Amount exceeded: Según ley contra el fraude no se puede recibir cobros por importe igual o superior a {maxAmount} </i18n> diff --git a/src/pages/Customer/components/CustomerNoteCreate.vue b/src/pages/Customer/components/CustomerNoteCreate.vue deleted file mode 100644 index ef9982195..000000000 --- a/src/pages/Customer/components/CustomerNoteCreate.vue +++ /dev/null @@ -1,57 +0,0 @@ -<script setup> -import { onMounted, reactive } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useRoute, useRouter } from 'vue-router'; - -import FormModel from 'components/FormModel.vue'; -import VnRow from 'components/ui/VnRow.vue'; - -const { t } = useI18n(); -const route = useRoute(); -const router = useRouter(); - -const initialData = reactive({}); - -onMounted(() => { - initialData.clientFk = `${route.params.id}`; -}); - -const toCustomerNotes = () => { - router.push({ - name: 'CustomerNotes', - params: { - id: route.params.id, - }, - }); -}; -</script> - -<template> - <FormModel - :form-initial-data="initialData" - :observe-form-changes="false" - @on-data-saved="toCustomerNotes()" - url-create="ClientObservations" - > - <template #moreActions> - <QBtn - :label="t('globals.cancel')" - @click="toCustomerNotes" - color="primary" - flat - icon="close" - /> - </template> - - <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> - <QInput :label="t('Note')" type="textarea" v-model="data.text" /> - </VnRow> - </template> - </FormModel> -</template> - -<i18n> -es: - Note: Nota -</i18n> diff --git a/src/pages/Customer/components/CustomerRecoverieCreate.vue b/src/pages/Customer/components/CustomerRecoverieCreate.vue index e70f85308..593b9c5b3 100644 --- a/src/pages/Customer/components/CustomerRecoverieCreate.vue +++ b/src/pages/Customer/components/CustomerRecoverieCreate.vue @@ -49,12 +49,12 @@ const toCustomerRecoveries = () => { </template> <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate :label="t('Since')" v-model="data.started" /> <VnInputDate :label="t('To')" v-model="data.finished" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Amount')" clearable diff --git a/src/pages/Customer/components/CustomerSamplesCreate.vue b/src/pages/Customer/components/CustomerSamplesCreate.vue index be614aa0b..0470dc176 100644 --- a/src/pages/Customer/components/CustomerSamplesCreate.vue +++ b/src/pages/Customer/components/CustomerSamplesCreate.vue @@ -264,7 +264,7 @@ const toCustomerSamples = () => { /> </div> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput :label="t('Recipient')" diff --git a/src/pages/Department/Card/DepartmentBasicData.vue b/src/pages/Department/Card/DepartmentBasicData.vue index 165a959d0..4573f7b66 100644 --- a/src/pages/Department/Card/DepartmentBasicData.vue +++ b/src/pages/Department/Card/DepartmentBasicData.vue @@ -29,7 +29,7 @@ const clientsOptions = ref([]); class="full-width" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('department.name')" v-model="data.name" @@ -44,7 +44,7 @@ const clientsOptions = ref([]); clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('department.chat')" v-model="data.chatName" @@ -58,7 +58,7 @@ const clientsOptions = ref([]); clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('department.bossDepartment')" v-model="data.workerFk" @@ -80,7 +80,7 @@ const clientsOptions = ref([]); :rules="validate('department.clientFk')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox :label="t('department.telework')" v-model="data.isTeleworking" @@ -92,7 +92,7 @@ const clientsOptions = ref([]); :true-value="1" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox :label="t('department.worksInProduction')" v-model="data.isProduction" @@ -102,7 +102,7 @@ const clientsOptions = ref([]); v-model="data.hasToRefill" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox :label="t('department.hasToSendMail')" v-model="data.hasToSendMail" diff --git a/src/pages/Department/Card/DepartmentDescriptor.vue b/src/pages/Department/Card/DepartmentDescriptor.vue index b49f5f9e2..e914f6af6 100644 --- a/src/pages/Department/Card/DepartmentDescriptor.vue +++ b/src/pages/Department/Card/DepartmentDescriptor.vue @@ -24,7 +24,7 @@ const $props = defineProps({ const route = useRoute(); const router = useRouter(); - +const DepartmentDescriptorRef = ref(); const { t } = useI18n(); const { notify } = useNotify(); @@ -55,18 +55,20 @@ const { openConfirmationModal } = useVnConfirm(); </script> <template> <CardDescriptor + ref="DepartmentDescriptorRef" module="Department" - data-key="departmentData" :url="`Departments/${entityId}`" :title="data.title" :subtitle="data.subtitle" :summary="$props.summary" + :to-module="{ name: 'WorkerDepartment' }" @on-fetch=" (data) => { department = data; setData(data); } " + data-key="department" > <template #menu="{}"> <QItem diff --git a/src/pages/Entry/Card/EntryBasicData.vue b/src/pages/Entry/Card/EntryBasicData.vue index 2640d72e4..e5d6f50d9 100644 --- a/src/pages/Entry/Card/EntryBasicData.vue +++ b/src/pages/Entry/Card/EntryBasicData.vue @@ -67,7 +67,7 @@ const onFilterTravelSelected = (formData, id) => { :clear-store-on-unmount="false" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('entry.basicData.supplier')" v-model="data.supplierFk" @@ -121,13 +121,13 @@ const onFilterTravelSelected = (formData, id) => { </template> </VnSelectDialog> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.reference" :label="t('entry.basicData.reference')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.invoiceNumber" :label="t('entry.basicData.invoiceNumber')" @@ -143,7 +143,7 @@ const onFilterTravelSelected = (formData, id) => { :required="true" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('entry.basicData.currency')" v-model="data.currencyFk" @@ -159,7 +159,7 @@ const onFilterTravelSelected = (formData, id) => { min="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('entry.basicData.observation')" type="textarea" @@ -169,7 +169,7 @@ const onFilterTravelSelected = (formData, id) => { fill-input /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox v-model="data.isOrdered" :label="t('entry.basicData.ordered')" diff --git a/src/pages/Entry/Card/EntryBuysImport.vue b/src/pages/Entry/Card/EntryBuysImport.vue index e0da663f0..8431e1096 100644 --- a/src/pages/Entry/Card/EntryBuysImport.vue +++ b/src/pages/Entry/Card/EntryBuysImport.vue @@ -197,7 +197,7 @@ const redirectToBuysView = () => { </div> </Teleport> <QCard class="q-pa-lg"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QFile ref="inputFileRef" :label="t('entry.buys.file')" @@ -219,13 +219,13 @@ const redirectToBuysView = () => { </QFile> </VnRow> <div v-if="importData.file"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('entry.buys.reference')" v-model="importData.ref" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('entry.buys.observations')" v-model="importData.observation" diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue index 9fadd2d06..436f5b9cd 100644 --- a/src/pages/Entry/Card/EntryCard.vue +++ b/src/pages/Entry/Card/EntryCard.vue @@ -10,8 +10,10 @@ import EntryFilter from '../EntryFilter.vue'; :descriptor="EntryDescriptor" :filter-panel="EntryFilter" search-data-key="EntryList" - search-url="Entries/filter" - searchbar-label="Search entries" - searchbar-info="You can search by entry reference" + :searchbar-props="{ + url: 'Entries/filter', + label: 'Search entries', + info: 'You can search by entry reference', + }" /> </template> diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue index 3efdf1bf7..b22d6ba53 100644 --- a/src/pages/Entry/Card/EntryDescriptor.vue +++ b/src/pages/Entry/Card/EntryDescriptor.vue @@ -115,7 +115,6 @@ watch; :subtitle="data.subtitle" @on-fetch="setData" data-key="entry" - :summary="$attrs" > <template #menu="{ entity }"> <QItem v-ripple clickable @click="showEntryReport(entity)"> diff --git a/src/pages/Entry/EntryBuysTableDialog.vue b/src/pages/Entry/EntryBuysTableDialog.vue index c2b04c291..9a76770aa 100644 --- a/src/pages/Entry/EntryBuysTableDialog.vue +++ b/src/pages/Entry/EntryBuysTableDialog.vue @@ -20,11 +20,17 @@ const $props = defineProps({ const entityId = computed(() => $props.id || route.params.id); const entriesTableColumns = computed(() => [ + { + align: 'left', + name: 'id', + field: 'id', + label: t('globals.id'), + }, { align: 'left', name: 'itemFk', field: 'itemFk', - label: t('globals.id'), + label: t('entry.latestBuys.tableVisibleColumns.itemFk'), }, { align: 'left', @@ -76,11 +82,11 @@ const entriesTableColumns = computed(() => [ </QCardSection> <QCardActions align="right"> <QBtn - :label="t('Print buys')" + :label="t('printLabels')" color="primary" icon="print" :loading="isLoading" - @click="openReport(`Entries/${entityId}/buy-label`)" + @click="openReport(`Entries/${entityId}/print`)" unelevated autofocus /> @@ -109,6 +115,19 @@ const entriesTableColumns = computed(() => [ <QTd v-for="col in props.cols" :key="col.name"> {{ col.value }} </QTd> + <QBtn + icon="print" + v-if="props.row.stickers > 0" + :loading="isLoading" + @click=" + openReport( + `Entries/${props.row.id}/buy-label` + ) + " + unelevated + > + <QTooltip>{{ t('printLabel') }}</QTooltip> + </QBtn> </QTr> </template> </QTable> diff --git a/src/pages/Entry/EntryCreate.vue b/src/pages/Entry/EntryCreate.vue index 4f2d13643..1e8490158 100644 --- a/src/pages/Entry/EntryCreate.vue +++ b/src/pages/Entry/EntryCreate.vue @@ -78,7 +78,7 @@ const redirectToEntryBasicData = (_, { id }) => { @on-data-saved="redirectToEntryBasicData" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Supplier')" class="full-width" @@ -102,7 +102,7 @@ const redirectToEntryBasicData = (_, { id }) => { </template> </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Travel')" class="full-width" @@ -131,7 +131,7 @@ const redirectToEntryBasicData = (_, { id }) => { </template> </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Company')" class="full-width" diff --git a/src/pages/Entry/EntryLatestBuys.vue b/src/pages/Entry/EntryLatestBuys.vue index 3f199314d..7c4354b65 100644 --- a/src/pages/Entry/EntryLatestBuys.vue +++ b/src/pages/Entry/EntryLatestBuys.vue @@ -1,5 +1,5 @@ <script setup> -import { onMounted, onUnmounted } from 'vue'; +import { onMounted, onUnmounted, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import RightMenu from 'src/components/common/RightMenu.vue'; import VnTable from 'components/VnTable/VnTable.vue'; @@ -15,12 +15,13 @@ const columns = [ { align: 'center', label: t('entry.latestBuys.tableVisibleColumns.image'), - name: 'image', + name: 'itemFk', columnField: { component: VnImg, - attrs: (id) => { + attrs: ({ row }) => { return { - id, + id: row.id, + size: '50x50', width: '50px', }; }, @@ -169,6 +170,7 @@ const columns = [ format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landing)), }, ]; +const tableRef = ref(); onMounted(async () => { stateStore.rightDrawer = true; @@ -191,6 +193,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); order="id DESC" :columns="columns" redirect="entry" + :row-click="({ entryFk }) => tableRef.redirect(entryFk)" auto-load :right-search="false" /> diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue index 4272ce10e..bd5ace677 100644 --- a/src/pages/Entry/EntryList.vue +++ b/src/pages/Entry/EntryList.vue @@ -192,7 +192,7 @@ onMounted(async () => { :filter="entryFilter" :create="{ urlCreate: 'Entries', - title: 'Create entry', + title: t('Create entry'), onDataSaved: ({ id }) => tableRef.redirect(id), formInitialData: {}, }" @@ -210,4 +210,5 @@ es: Virtual entry: Es una redada Search entries: Buscar entradas You can search by entry reference: Puedes buscar por referencia de la entrada + Create entry: Crear entrada </i18n> diff --git a/src/pages/Entry/EntryMain.vue b/src/pages/Entry/EntryMain.vue deleted file mode 100644 index c1f2a31db..000000000 --- a/src/pages/Entry/EntryMain.vue +++ /dev/null @@ -1,18 +0,0 @@ -<script setup> -import LeftMenu from 'src/components/LeftMenu.vue'; - -import { useStateStore } from 'stores/useStateStore'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Entry/MyEntries.vue b/src/pages/Entry/MyEntries.vue index d4b73b479..1c56427f4 100644 --- a/src/pages/Entry/MyEntries.vue +++ b/src/pages/Entry/MyEntries.vue @@ -1,74 +1,92 @@ <script setup> -import { computed, onMounted } from 'vue'; +import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; -import { useStateStore } from 'stores/useStateStore'; import { toDate } from 'src/filters/index'; import { useQuasar } from 'quasar'; import EntryBuysTableDialog from './EntryBuysTableDialog.vue'; import VnTable from 'components/VnTable/VnTable.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -const stateStore = useStateStore(); const { t } = useI18n(); const quasar = useQuasar(); - -onMounted(async () => { - stateStore.rightDrawer = true; -}); - const columns = computed(() => [ { align: 'left', name: 'id', label: t('customer.extendedList.tableVisibleColumns.id'), - chip: { - condition: () => true, - }, - isId: true, - isTitle: false, + columnFilter: false, + isTitle: true, }, { - align: 'left', + visible: false, + align: 'right', label: t('shipped'), name: 'shipped', - isTitle: false, - create: true, - cardVisible: true, - component: 'date', - columnField: { - component: null, + columnFilter: { + name: 'fromShipped', + label: t('fromShipped'), + component: 'date', }, format: ({ shipped }) => toDate(shipped), }, { + visible: false, align: 'left', + label: t('shipped'), + name: 'shipped', + columnFilter: { + name: 'toShipped', + label: t('toShipped'), + component: 'date', + }, + format: ({ shipped }) => toDate(shipped), + cardVisible: true, + }, + { + align: 'right', + label: t('shipped'), + name: 'shipped', + columnFilter: false, + format: ({ shipped }) => toDate(shipped), + }, + { + align: 'right', label: t('landed'), name: 'landed', - isTitle: false, - create: true, - cardVisible: false, - component: 'date', - columnField: { - component: null, - }, + columnFilter: false, format: ({ landed }) => toDate(landed), }, + + { + align: 'right', + label: t('globals.wareHouseIn'), + name: 'warehouseInFk', + format: (row) => row.warehouseInName, + cardVisible: true, + columnFilter: { + component: 'select', + attrs: { + url: 'warehouses', + fields: ['id', 'name'], + optionLabel: 'name', + optionValue: 'id', + }, + alias: 't', + inWhere: true, + }, + }, { align: 'left', - label: t('globals.wareHouseIn'), - name: 'warehouseInName', - isTitle: false, - cardVisible: true, - create: false, + label: t('globals.daysOnward'), + name: 'days', + visible: false, }, { align: 'right', name: 'tableActions', - computed, actions: [ { - title: t('printBuys'), + title: t('printLabels'), icon: 'print', action: (row) => printBuys(row.id), }, @@ -87,36 +105,19 @@ const printBuys = (rowId) => { </script> <template> <VnSearchbar - data-key="EntryList" + data-key="myEntriesList" url="Entries/filter" :label="t('Search entries')" :info="t('You can search by entry reference')" /> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnTable - ref="myEntriesRef" - data-key="myEntriesList" - url="Entries/filter" - :order="['landed DESC', 'id DESC']" - :columns="columns" - default-mode="card" - auto-load - :right-search="true" - > - <template #moreFilterPanel="{ params }"> - <VnInput - :label="t('globals.daysOnward')" - v-model="params.days" - class="q-px-xs row" - dense - filled - outlined - ></VnInput> - </template> - </VnTable> - </div> - </QPage> + <VnTable + data-key="myEntriesList" + url="Entries/filter" + :columns="columns" + default-mode="card" + order="shipped DESC" + auto-load + /> </template> <i18n> diff --git a/src/pages/Entry/locale/en.yml b/src/pages/Entry/locale/en.yml index 677c3c055..f0965b097 100644 --- a/src/pages/Entry/locale/en.yml +++ b/src/pages/Entry/locale/en.yml @@ -8,4 +8,7 @@ entryFilter: reference: Reference landed: Landed shipped: Shipped -printBuys: Print buys +fromShipped: Shipped(from) +toShipped: Shipped(to) +printLabels: Print stickers +printLabel: Print sticker diff --git a/src/pages/Entry/locale/es.yml b/src/pages/Entry/locale/es.yml index 10b77c2ee..aba04571e 100644 --- a/src/pages/Entry/locale/es.yml +++ b/src/pages/Entry/locale/es.yml @@ -12,4 +12,7 @@ entryFilter: landed: F. llegada shipped: F. salida -Print buys: Imprimir etiquetas +fromShipped: F. salida(desde) +toShipped: F. salida(hasta) +printLabels: Imprimir etiquetas +printLabel: Imprimir etiqueta diff --git a/src/pages/InvoiceIn/Card/InvoiceInCard.vue b/src/pages/InvoiceIn/Card/InvoiceInCard.vue index 912713f23..a95f289b0 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInCard.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInCard.vue @@ -2,6 +2,7 @@ import VnCard from 'components/common/VnCard.vue'; import InvoiceInDescriptor from './InvoiceInDescriptor.vue'; import InvoiceInFilter from '../InvoiceInFilter.vue'; +import InvoiceInSearchbar from '../InvoiceInSearchbar.vue'; const filter = { include: [ @@ -28,8 +29,9 @@ const filter = { :descriptor="InvoiceInDescriptor" :filter-panel="InvoiceInFilter" search-data-key="InvoiceInList" - search-url="InvoiceIns/filter" - searchbar-label="Search invoice" - searchbar-info="You can search by invoice reference" - /> + > + <template #searchbar> + <InvoiceInSearchbar /> + </template> + </VnCard> </template> diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue index 68dc5be4b..cba2a31d2 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue @@ -1,6 +1,6 @@ <script setup> import { ref, reactive, computed, onBeforeMount } from 'vue'; -import { useRouter, onBeforeRouteLeave } from 'vue-router'; +import { useRouter, onBeforeRouteUpdate } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; import axios from 'axios'; @@ -129,33 +129,23 @@ onBeforeMount(async () => { totalAmount.value = data.totalDueDay; }); -onBeforeRouteLeave(async (to, from) => { - invoiceInCorrection.correcting.length = 0; - invoiceInCorrection.corrected = null; - if (to.params.id !== from.params.id) await setInvoiceCorrection(entityId.value); +onBeforeRouteUpdate(async (to, from) => { + if (to.params.id !== from.params.id) { + await setInvoiceCorrection(to.params.id); + const { data } = await axios.get(`InvoiceIns/${to.params.id}/getTotals`); + totalAmount.value = data.totalDueDay; + } }); async function setInvoiceCorrection(id) { - const [{ data: correctingData }, { data: correctedData }] = await Promise.all([ - axios.get('InvoiceInCorrections', { - params: { - filter: { - where: { - correctingFk: id, - }, - }, - }, - }), - axios.get('InvoiceInCorrections', { - params: { - filter: { - where: { - correctedFk: id, - }, - }, - }, - }), - ]); + invoiceInCorrection.correcting.length = 0; + invoiceInCorrection.corrected = null; + const { data: correctingData } = await axios.get('InvoiceInCorrections', { + params: { filter: { where: { correctingFk: id } } }, + }); + const { data: correctedData } = await axios.get('InvoiceInCorrections', { + params: { filter: { where: { correctedFk: id } } }, + }); if (correctingData[0]) invoiceInCorrection.corrected = correctingData[0].correctedFk; @@ -207,8 +197,13 @@ async function cloneInvoice() { const isAdministrative = () => hasAny(['administrative']); -const isAgricultural = () => - invoiceIn.value?.supplier?.sageWithholdingFk === config.value[0]?.sageWithholdingFk; +const isAgricultural = () => { + if (!config.value) return false; + return ( + invoiceIn.value?.supplier?.sageFarmerWithholdingFk === + config?.value[0]?.sageWithholdingFk + ); +}; function showPdfInvoice() { if (isAgricultural()) openReport(`InvoiceIns/${entityId.value}/invoice-in-pdf`); @@ -374,7 +369,7 @@ const createInvoiceInCorrection = async () => { </template> </VnLv> </template> - <template #action="{ entity }"> + <template #actions="{ entity }"> <QCardActions> <QBtn size="md" @@ -442,7 +437,7 @@ const createInvoiceInCorrection = async () => { readonly /> <VnSelect - :label="`${useCapitalize(t('globals.class'))}*`" + :label="`${useCapitalize(t('globals.class'))}`" v-model="correctionFormData.invoiceClass" :options="siiTypeInvoiceOuts" option-value="id" @@ -452,7 +447,7 @@ const createInvoiceInCorrection = async () => { </QItemSection> <QItemSection> <VnSelect - :label="`${useCapitalize(t('globals.type'))}*`" + :label="`${useCapitalize(t('globals.type'))}`" v-model="correctionFormData.invoiceType" :options="cplusRectificationTypes" option-value="id" @@ -460,7 +455,7 @@ const createInvoiceInCorrection = async () => { :required="true" /> <VnSelect - :label="`${useCapitalize(t('globals.reason'))}*`" + :label="`${useCapitalize(t('globals.reason'))}`" v-model="correctionFormData.invoiceReason" :options="invoiceCorrectionTypes" option-value="id" @@ -488,6 +483,9 @@ const createInvoiceInCorrection = async () => { .q-card { max-width: 45em; } + .q-field:nth-child(1) { + padding-bottom: 20px; + } } @media (max-width: $breakpoint-xs) { diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue index d2b43c57a..7dbd0fe9e 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue @@ -8,9 +8,10 @@ import { useArrayData } from 'src/composables/useArrayData'; import CrudModel from 'src/components/CrudModel.vue'; import FetchData from 'src/components/FetchData.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; import { toCurrency } from 'src/filters'; import useNotify from 'src/composables/useNotify.js'; +import VnInputDate from 'src/components/common/VnInputDate.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const route = useRoute(); const { notify } = useNotify(); @@ -22,9 +23,6 @@ const rowsSelected = ref([]); const banks = ref([]); const invoiceInFormRef = ref(); const invoiceId = +route.params.id; - -const placeholder = 'yyyy/mm/dd'; - const filter = { where: { invoiceInFk: invoiceId } }; const columns = computed(() => [ @@ -104,42 +102,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, > <template #body-cell-duedate="{ row }"> <QTd> - <QInput - v-model="row.dueDated" - mask="date" - :placeholder="placeholder" - clearable - clear-icon="close" - > - <template #append> - <QIcon name="event" class="cursor-pointer"> - <QPopupProxy - cover - transition-show="scale" - transition-hide="scale" - > - <QDate v-model="row.dueDated" landscape> - <div - class="row items-center justify-end q-gutter-sm" - > - <QBtn - :label="t('globals.cancel')" - color="primary" - flat - v-close-popup - /> - <QBtn - :label="t('globals.confirm')" - color="primary" - flat - v-close-popup - /> - </div> - </QDate> - </QPopupProxy> - </QIcon> - </template> - </QInput> + <VnInputDate v-model="row.dueDated" /> </QTd> </template> <template #body-cell-bank="{ row, col }"> @@ -164,7 +127,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, </template> <template #body-cell-amount="{ row }"> <QTd> - <VnCurrency + <VnInputNumber v-model="row.amount" :is-outlined="false" clearable @@ -174,7 +137,7 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, </template> <template #body-cell-foreignvalue="{ row }"> <QTd> - <QInput + <VnInputNumber :class="{ 'no-pointer-events': !isNotEuro(invoiceIn.currency.code), }" @@ -207,51 +170,11 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, <QSeparator /> <QList> <QItem> - <QInput + <VnInputDate class="full-width" :label="t('Date')" v-model="props.row.dueDated" - mask="date" - :placeholder="placeholder" - clearable - clear-icon="close" - > - <template #append> - <QIcon name="event" class="cursor-pointer"> - <QPopupProxy - cover - transition-show="scale" - transition-hide="scale" - > - <QDate - v-model="props.row.dueDated" - landscape - > - <div - class="row items-center justify-end q-gutter-sm" - > - <QBtn - :label=" - t('globals.cancel') - " - color="primary" - flat - v-close-popup - /> - <QBtn - :label=" - t('globals.confirm') - " - color="primary" - flat - v-close-popup - /> - </div> - </QDate> - </QPopupProxy> - </QIcon> - </template> - </QInput> + /> </QItem> <QItem> <VnSelect @@ -274,16 +197,14 @@ const getTotalAmount = (rows) => rows.reduce((acc, { amount }) => acc + +amount, </VnSelect> </QItem> <QItem> - <QInput + <VnInputNumber :label="t('Amount')" class="full-width" v-model="props.row.amount" - clearable - clear-icon="close" /> </QItem> <QItem> - <QInput + <VnInputNumber :label="t('Foreign value')" class="full-width" :class="{ diff --git a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue index a7b9110f5..481698832 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInIntrastat.vue @@ -7,6 +7,7 @@ import CrudModel from 'src/components/CrudModel.vue'; import FetchData from 'src/components/FetchData.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import { useArrayData } from 'src/composables/useArrayData'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); @@ -72,7 +73,13 @@ const columns = computed(() => [ ]); const getTotal = (data, key) => - data.reduce((acc, cur) => acc + +String(cur[key]).replace(',', '.'), 0); + data.reduce((acc, cur) => acc + +String(cur[key] || 0).replace(',', '.'), 0); + +const formatOpt = (row, { model, options }, prop) => { + const obj = row[model]; + const option = options.find(({ id }) => id == obj); + return option ? `${obj}:${option[prop]}` : ''; +}; </script> <template> <FetchData @@ -92,7 +99,7 @@ const getTotal = (data, key) => ref="invoiceInFormRef" data-key="InvoiceInIntrastats" url="InvoiceInIntrastats" - :auto-load="!currency" + auto-load :data-required="{ invoiceInFk: invoiceInId }" :filter="filter" v-model:selected="rowsSelected" @@ -109,11 +116,7 @@ const getTotal = (data, key) => > <template #body-cell="{ row, col }"> <QTd> - <QInput - v-model="row[col.name]" - clearable - clear-icon="close" - /> + <VnInputNumber v-model="row[col.name]" /> </QTd> </template> <template #body-cell-code="{ row, col }"> @@ -124,6 +127,9 @@ const getTotal = (data, key) => option-value="id" option-label="description" :filter-options="['id', 'description']" + :hide-selected="false" + :fill-input="false" + :display-value="formatOpt(row, col, 'description')" > <template #option="scope"> <QItem v-bind="scope.itemProps"> @@ -194,7 +200,7 @@ const getTotal = (data, key) => ]" :key="index" > - <QInput + <VnInputNumber :label="t(value)" class="full-width" v-model="props.row[value]" @@ -247,7 +253,11 @@ const getTotal = (data, key) => } } </style> -<style lang="scss" scoped></style> +<style lang="scss" scoped> +:deep(.q-table tr .q-td:nth-child(2) input) { + display: none; +} +</style> <i18n> en: amount: Amount diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue index cdf012b2a..644b472e2 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue @@ -66,7 +66,7 @@ const vatColumns = ref([ field: (row) => taxRate(row.taxableBase, row.taxTypeSage?.rate), format: (value) => toCurrency(value, currency.value), sortable: true, - align: 'center', + align: 'left', }, { name: 'currency', @@ -120,7 +120,6 @@ const intrastatColumns = ref([ }, sortable: true, align: 'left', - style: 'width: 10px', }, { name: 'amount', @@ -128,7 +127,6 @@ const intrastatColumns = ref([ field: (row) => toCurrency(row.amount, currency.value), sortable: true, align: 'left', - style: 'width: 10px', }, { name: 'net', @@ -339,6 +337,16 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; </QTh> </QTr> </template> + <template #body-cell-vat="{ value: vatCell }"> + <QTd :title="vatCell" shrink> + {{ vatCell }} + </QTd> + </template> + <template #body-cell-transaction="{ value: transactionCell }"> + <QTd :title="transactionCell" shrink> + {{ transactionCell }} + </QTd> + </template> <template #bottom-row> <QTr class="bg"> <QTd></QTd> @@ -347,7 +355,7 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; }}</QTd> <QTd></QTd> <QTd></QTd> - <QTd class="text-center">{{ + <QTd>{{ toCurrency(getTotalTax(entity.invoiceInTax, currency)) }}</QTd> <QTd></QTd> @@ -405,6 +413,11 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; </QTh> </QTr> </template> + <template #body-cell-code="{ value: codeCell }"> + <QTd :title="codeCell" shrink> + {{ codeCell }} + </QTd> + </template> <template #bottom-row> <QTr class="bg"> <QTd></QTd> @@ -423,6 +436,10 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`; .bg { background-color: var(--vn-accent-color); } +.q-chip { + color: var(--vn-text-color); +} + @media (min-width: $breakpoint-md) { .summaryBody { .vat { diff --git a/src/pages/InvoiceIn/Card/InvoiceInVat.vue b/src/pages/InvoiceIn/Card/InvoiceInVat.vue index 58f6e0d01..4dac5058e 100644 --- a/src/pages/InvoiceIn/Card/InvoiceInVat.vue +++ b/src/pages/InvoiceIn/Card/InvoiceInVat.vue @@ -9,7 +9,8 @@ import { toCurrency } from 'src/filters'; import FetchData from 'src/components/FetchData.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; import CrudModel from 'src/components/CrudModel.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const quasar = useQuasar(); @@ -162,8 +163,14 @@ async function addExpense() { } } const getTotalTaxableBase = (rows) => - rows.reduce((acc, { taxableBase }) => acc + +taxableBase, 0); + rows.reduce((acc, { taxableBase }) => acc + +(taxableBase || 0), 0); const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0); + +const formatOpt = (row, { model, options }, prop) => { + const obj = row[model]; + const option = options.find(({ id }) => id == obj); + return option ? `${obj}:${option[prop]}` : ''; +}; </script> <template> <FetchData @@ -199,7 +206,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) :grid="$q.screen.lt.sm" > <template #body-cell-expense="{ row, col }"> - <QTd auto-width> + <QTd> <VnSelect v-model="row[col.model]" :options="col.options" @@ -217,6 +224,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) name="close" @click.stop="value = null" class="cursor-pointer" + size="xs" /> <QIcon @click.stop.prevent="newExpenseRef.show()" @@ -234,7 +242,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) </template> <template #body-cell-taxablebase="{ row }"> <QTd> - <VnCurrency + <VnInputNumber :class="{ 'no-pointer-events': isNotEuro(invoiceIn.currency.code), }" @@ -254,8 +262,9 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) :option-value="col.optionValue" :option-label="col.optionLabel" :filter-options="['id', 'vat']" - :autofocus="col.tabIndex == 1" - input-debounce="0" + :hide-selected="false" + :fill-input="false" + :display-value="formatOpt(row, col, 'vat')" > <template #option="scope"> <QItem v-bind="scope.itemProps"> @@ -280,6 +289,9 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) :filter-options="['id', 'transaction']" :autofocus="col.tabIndex == 1" input-debounce="0" + :hide-selected="false" + :fill-input="false" + :display-value="formatOpt(row, col, 'transaction')" > <template #option="scope"> <QItem v-bind="scope.itemProps"> @@ -298,7 +310,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) </template> <template #body-cell-foreignvalue="{ row }"> <QTd> - <QInput + <VnInputNumber :class="{ 'no-pointer-events': !isNotEuro(invoiceIn.currency.code), }" @@ -346,7 +358,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) </VnSelect> </QItem> <QItem> - <VnCurrency + <VnInputNumber :label="t('Taxable base')" :class="{ 'no-pointer-events': isNotEuro( @@ -411,7 +423,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) {{ toCurrency(taxRate(props.row), currency) }} </QItem> <QItem> - <QInput + <VnInputNumber :label="t('Foreign value')" class="full-width" :class="{ @@ -443,7 +455,11 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) </QCardSection> <QCardSection class="q-pt-none"> <QItem> - <QInput :label="`${t('Code')}*`" v-model="newExpense.code" /> + <VnInput + :label="`${t('Code')}*`" + v-model="newExpense.code" + :required="true" + /> <QCheckbox dense size="sm" @@ -452,7 +468,7 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) /> </QItem> <QItem> - <QInput + <VnInput :label="`${t('Descripction')}*`" v-model="newExpense.description" /> @@ -474,11 +490,16 @@ const getTotalRate = (rows) => rows.reduce((acc, cur) => acc + +taxRate(cur), 0) /> </QPageSticky> </template> + <style lang="scss" scoped> .bg { background-color: var(--vn-light-gray); } +:deep(.q-table tr td:nth-child(n + 4):nth-child(-n + 5) input) { + display: none; +} + @media (max-width: $breakpoint-xs) { .q-dialog { .q-card { diff --git a/src/pages/InvoiceIn/InvoiceInCreate.vue b/src/pages/InvoiceIn/InvoiceInCreate.vue index 4dec9ac7d..e6863beb1 100644 --- a/src/pages/InvoiceIn/InvoiceInCreate.vue +++ b/src/pages/InvoiceIn/InvoiceInCreate.vue @@ -26,8 +26,7 @@ const newInvoiceIn = reactive({ companyFk: user.value.companyFk || null, issued: Date.vnNew(), }); -const suppliersOptions = ref([]); -const companiesOptions = ref([]); +const companies = ref([]); const redirectToInvoiceInBasicData = (__, { id }) => { router.push({ name: 'InvoiceInBasicData', params: { id } }); @@ -35,19 +34,12 @@ const redirectToInvoiceInBasicData = (__, { id }) => { </script> <template> - <FetchData - url="Suppliers" - :filter="{ fields: ['id', 'nickname'] }" - order="nickname" - @on-fetch="(data) => (suppliersOptions = data)" - auto-load - /> <FetchData ref="companiesRef" url="Companies" :filter="{ fields: ['id', 'code'] }" order="code" - @on-fetch="(data) => (companiesOptions = data)" + @on-fetch="(data) => (companies = data)" auto-load /> <template v-if="stateStore.isHeaderMounted()"> @@ -69,9 +61,10 @@ const redirectToInvoiceInBasicData = (__, { id }) => { <template #form="{ data, validate }"> <VnRow> <VnSelect + url="Suppliers" + :fields="['id', 'nickname']" :label="t('Supplier')" v-model="data.supplierFk" - :options="suppliersOptions" option-value="id" option-label="nickname" hide-selected @@ -98,7 +91,7 @@ const redirectToInvoiceInBasicData = (__, { id }) => { <VnSelect :label="t('Company')" v-model="data.companyFk" - :options="companiesOptions" + :options="companies" option-value="id" option-label="code" map-options diff --git a/src/pages/InvoiceIn/InvoiceInFilter.vue b/src/pages/InvoiceIn/InvoiceInFilter.vue index 57aaeab54..2f87c2b2e 100644 --- a/src/pages/InvoiceIn/InvoiceInFilter.vue +++ b/src/pages/InvoiceIn/InvoiceInFilter.vue @@ -6,14 +6,20 @@ import VnSelect from 'components/common/VnSelect.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import FetchData from 'components/FetchData.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); defineProps({ dataKey: { type: String, required: true } }); -const suppliers = ref([]); +const activities = ref([]); </script> <template> + <FetchData + url="SupplierActivities" + auto-load + @on-fetch="(data) => (activities = data)" + /> <VnFilterPanel :data-key="dataKey" :search-button="true"> <template #tags="{ tag, formatFn }"> <div class="q-gutter-x-xs"> @@ -22,6 +28,22 @@ const suppliers = ref([]); </div> </template> <template #body="{ params, searchFn }"> + <QItem> + <QItemSection> + <VnSelect + v-model="params.supplierFk" + url="Suppliers" + :fields="['id', 'nickname']" + :label="t('params.supplierFk')" + option-value="id" + option-label="nickname" + dense + outlined + rounded + :filter-options="['id', 'name']" + /> + </QItemSection> + </QItem> <QItem> <QItemSection> <VnInput @@ -29,11 +51,7 @@ const suppliers = ref([]); v-model="params.supplierRef" is-outlined lazy-rules - > - <template #prepend> - <QIcon name="vn:client" size="sm"></QIcon> - </template> - </VnInput> + /> </QItemSection> </QItem> <QItem> @@ -43,57 +61,27 @@ const suppliers = ref([]); v-model="params.fi" is-outlined lazy-rules - > - <template #prepend> - <QIcon name="badge" size="sm"></QIcon> - </template> - </VnInput> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnSelect - v-model="params.supplierFk" - url="Suppliers" - :fields="['id', 'nickname']" - :label="t('params.supplierFk')" - option-value="id" - option-label="nickname" - :options="suppliers" - dense - outlined - rounded - > - </VnSelect> + /> </QItemSection> </QItem> <QItem> <QItemSection> <VnInput - :label="t('params.account')" - v-model="params.account" + :label="t('params.serialNumber')" + v-model="params.serialNumber" is-outlined lazy-rules - > - <template #prepend> - <QIcon name="person" size="sm" /> - </template> - </VnInput> + /> </QItemSection> </QItem> <QItem> <QItemSection> - <VnCurrency v-model="params.amount" is-outlined /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnInputDate :label="t('From')" v-model="params.from" is-outlined /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnInputDate :label="t('To')" v-model="params.to" is-outlined /> + <VnInput + :label="t('params.serial')" + v-model="params.serial" + is-outlined + lazy-rules + /> </QItemSection> </QItem> <QItem> @@ -105,7 +93,36 @@ const suppliers = ref([]); /> </QItemSection> </QItem> - <QItem class="q-mb-md"> + <QItem> + <QItemSection> + <VnInput + :label="t('params.account')" + v-model="params.account" + is-outlined + lazy-rules + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnInput + :label="t('params.awb')" + v-model="params.awbCode" + is-outlined + lazy-rules + /> + </QItemSection> + </QItem> + <QItem> + <QItemSection> + <VnInputNumber + :label="t('Amount')" + v-model="params.amount" + is-outlined + /> + </QItemSection> + </QItem> + <QItem> <QItemSection> <QCheckbox :label="t('params.isBooked')" @@ -114,48 +131,28 @@ const suppliers = ref([]); toggle-indeterminate /> </QItemSection> + <QItemSection> + <QCheckbox + :label="t('params.correctingFk')" + v-model="params.correctingFk" + @update:model-value="searchFn()" + toggle-indeterminate + /> + </QItemSection> </QItem> <QExpansionItem :label="t('More options')" expand-separator> <QItem> <QItemSection> - <VnInput - :label="t('params.serialNumber')" - v-model="params.serialNumber" + <VnInputDate + :label="t('From')" + v-model="params.from" is-outlined - lazy-rules - > - <template #prepend> - <QIcon name="badge" size="sm"></QIcon> - </template> - </VnInput> + /> </QItemSection> </QItem> <QItem> <QItemSection> - <VnInput - :label="t('params.serial')" - v-model="params.serial" - is-outlined - lazy-rules - > - <template #prepend> - <QIcon name="badge" size="sm"></QIcon> - </template> - </VnInput> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnInput - :label="t('params.awb')" - v-model="params.awbCode" - is-outlined - lazy-rules - > - <template #prepend> - <QIcon name="badge" size="sm"></QIcon> - </template> - </VnInput> + <VnInputDate :label="t('To')" v-model="params.to" is-outlined /> </QItemSection> </QItem> </QExpansionItem> @@ -166,7 +163,7 @@ const suppliers = ref([]); <i18n> en: params: - search: ID + search: Id or supplier name supplierRef: Supplier ref. supplierFk: Supplier fi: Supplier fiscal id @@ -177,12 +174,17 @@ en: dued: Dued serialNumber: Serial Number serial: Serial - account: Account + account: Ledger account isBooked: is booked - correctedFk: Rectificatives + correctedFk: Rectified + issued: Issued + to: To + awbCode: AWB + correctingFk: Rectificative + supplierActivityFk: Supplier activity es: params: - search: Contiene + search: Id o nombre proveedor supplierRef: Ref. proveedor supplierFk: Proveedor clientFk: Cliente @@ -193,10 +195,12 @@ es: amount: Importe issued: Emitida isBooked: Conciliada - account: Cuenta + account: Cuenta contable created: Creada dued: Vencida - correctedFk: Rectificativas + correctedFk: Rectificada + correctingFk: Rectificativa + supplierActivityFk: Actividad proveedor From: Desde To: Hasta Amount: Importe diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue index 0e5216314..234cfb50f 100644 --- a/src/pages/InvoiceIn/InvoiceInList.vue +++ b/src/pages/InvoiceIn/InvoiceInList.vue @@ -1,140 +1,175 @@ <script setup> -import { ref, onMounted, onUnmounted } from 'vue'; +import { ref, computed, onMounted, onUnmounted } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; import { useStateStore } from 'stores/useStateStore'; import { downloadFile } from 'src/composables/downloadFile'; import { toDate, toCurrency } from 'src/filters/index'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import CardList from 'src/components/ui/CardList.vue'; import InvoiceInFilter from './InvoiceInFilter.vue'; -import { getUrl } from 'src/composables/getUrl'; import InvoiceInSummary from './Card/InvoiceInSummary.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; +import InvoiceInSearchbar from 'src/pages/InvoiceIn/InvoiceInSearchbar.vue'; +import VnTable from 'src/components/VnTable/VnTable.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnInputDate from 'src/components/common/VnInputDate.vue'; const stateStore = useStateStore(); -const router = useRouter(); const { viewSummary } = useSummaryDialog(); -let url = ref(); const { t } = useI18n(); -onMounted(async () => { - stateStore.rightDrawer = true; - url.value = await getUrl(''); -}); +onMounted(async () => (stateStore.rightDrawer = true)); onUnmounted(() => (stateStore.rightDrawer = false)); -function navigate(id) { - router.push({ path: `/invoice-in/${id}` }); -} -</script> +const tableRef = ref(); +const cols = computed(() => [ + { + align: 'left', + name: 'id', + label: 'Id', + }, + { + align: 'left', + name: 'supplierFk', + label: t('invoiceIn.list.supplier'), + columnFilter: { + component: 'select', + attrs: { + url: 'Suppliers', + fields: ['id', 'name'], + }, + }, + columnClass: 'expand', + }, + { + align: 'left', + name: 'supplierRef', + label: t('invoiceIn.list.supplierRef'), + }, + { + align: 'left', + name: 'serialNumber', + label: t('invoiceIn.list.serialNumber'), + }, + { + align: 'left', + name: 'serial', + label: t('invoiceIn.list.serial'), + }, + { + align: 'left', + label: t('invoiceIn.list.issued'), + name: 'issued', + component: null, + columnFilter: { + component: 'date', + }, + format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.issued)), + }, + { + align: 'left', + name: 'isBooked', + label: t('invoiceIn.list.isBooked'), + columnFilter: false, + }, + { + align: 'left', + name: 'awbCode', + label: t('invoiceIn.list.awb'), + }, + { + align: 'left', + name: 'amount', + label: t('invoiceIn.list.amount'), + format: ({ amount }) => toCurrency(amount), + }, + { + align: 'right', + name: 'tableActions', + actions: [ + { + title: t('components.smartCard.openSummary'), + icon: 'preview', + type: 'submit', + action: (row) => viewSummary(row.id, InvoiceInSummary), + }, + { + title: t('globals.download'), + icon: 'download', + type: 'submit', + isPrimary: true, + action: (row) => downloadFile(row.dmsFk), + }, + ], + }, +]); +</script> <template> - <VnSearchbar - data-key="InvoiceInList" - :label="t('Search invoice')" - :info="t('You can search by invoice reference')" - /> + <InvoiceInSearchbar /> <RightMenu> <template #right-panel> <InvoiceInFilter data-key="InvoiceInList" /> </template> </RightMenu> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - data-key="InvoiceInList" - url="InvoiceIns/filter" - order="issued DESC, id DESC" - auto-load + <VnTable + ref="tableRef" + data-key="InvoiceInList" + url="InvoiceIns/filter" + :order="['issued DESC', 'id DESC']" + :create="{ + urlCreate: 'InvoiceIns', + title: t('globals.createInvoiceIn'), + onDataSaved: ({ id }) => tableRef.redirect(id), + formInitialData: {}, + }" + redirect="invoice-in" + :columns="cols" + :right-search="false" + :disable-option="{ card: true }" + :auto-load="!!$route.query.params" + > + <template #column-supplierFk="{ row }"> + <span class="link" @click.stop> + {{ row.supplierName }} + <SupplierDescriptorProxy :id="row.supplierFk" /> + </span> + </template> + <template #more-create-dialog="{ data }"> + <VnSelect + v-model="data.supplierFk" + url="Suppliers" + :fields="['id', 'nickname']" + :label="t('Supplier')" + option-value="id" + option-label="nickname" + :filter-options="['id', 'name']" + :required="true" > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :key="row.id" - :title="row.supplierRef" - @click="navigate(row.id)" - :id="row.id" - > - <template #list-items> - <VnLv - :label="t('invoiceIn.list.supplierRef')" - :value="row.supplierRef" - /> - <VnLv - :label="t('invoiceIn.list.supplier')" - :value="row.supplierName" - @click.stop - > - <template #value> - <span class="link"> - {{ row.supplierName }} - <SupplierDescriptorProxy :id="row.supplierFk" /> - </span> - </template> - </VnLv> - <VnLv - :label="t('invoiceIn.list.serialNumber')" - :value="row.serialNumber" - /> - <VnLv - :label="t('invoiceIn.list.serial')" - :value="row.serial" - /> - <VnLv - :label="t('invoiceIn.list.issued')" - :value="toDate(row.issued)" - /> - <VnLv :label="t('invoiceIn.list.awb')" :value="row.awbCode" /> - <VnLv - :label="t('invoiceIn.list.amount')" - :value="toCurrency(row.amount)" - /> - <VnLv - :label="t('invoiceIn.list.isBooked')" - :value="!!row.isBooked" - /> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openCard')" - @click.stop="navigate(row.id)" - outline - type="reset" - /> - - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, InvoiceInSummary)" - color="primary" - type="submit" - class="q-mt-sm" - /> - <QBtn - :label="t('Download')" - class="q-mt-sm" - @click.stop="downloadFile(row.dmsFk)" - type="submit" - color="primary" - /> - </template> - </CardList> + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel>{{ scope.opt?.nickname }}</QItemLabel> + <QItemLabel caption> #{{ scope.opt?.id }} </QItemLabel> + </QItemSection> + </QItem> </template> - </VnPaginate> - </div> - </QPage> - <QPageSticky position="bottom-right" :offset="[20, 20]"> - <QBtn color="primary" icon="add" size="lg" round :href="`/#/invoice-in/create`" /> - </QPageSticky> + </VnSelect> + <VnInput + :label="t('invoiceIn.summary.supplierRef')" + v-model="data.supplierRef" + /> + <VnSelect + url="Companies" + :label="t('Company')" + :fields="['id', 'code']" + v-model="data.companyFk" + option-value="id" + option-label="code" + :required="true" + /> + <VnInputDate :label="t('invoiceIn.summary.issued')" v-model="data.issued" /> + </template> + </VnTable> </template> - -<i18n> -es: - Search invoice: Buscar factura recibida - You can search by invoice reference: Puedes buscar por referencia de la factura - Download: Descargar -</i18n> diff --git a/src/pages/InvoiceIn/InvoiceInMain.vue b/src/pages/InvoiceIn/InvoiceInMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/InvoiceIn/InvoiceInMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/InvoiceIn/InvoiceInSearchbar.vue b/src/pages/InvoiceIn/InvoiceInSearchbar.vue new file mode 100644 index 000000000..f2731b005 --- /dev/null +++ b/src/pages/InvoiceIn/InvoiceInSearchbar.vue @@ -0,0 +1,18 @@ +<script setup> +import VnSearchbar from 'components/ui/VnSearchbar.vue'; +import { useI18n } from 'vue-i18n'; +const { t } = useI18n(); +</script> +<template> + <VnSearchbar + data-key="InvoiceInList" + :label="t('Search invoice')" + :info="t('Search invoices in by id or supplier fiscal name')" + url="InvoiceIns/filter" + /> +</template> +<i18n> +es: + Search invoice: Buscar factura recibida + Search invoices in by id or supplier fiscal name: Buscar facturas recibidas por id o por nombre fiscal del proveedor +</i18n> diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml deleted file mode 100644 index d7e38d7fa..000000000 --- a/src/pages/InvoiceIn/locale/es.yml +++ /dev/null @@ -1,2 +0,0 @@ -Search invoice: Buscar factura recibida -You can search by invoice reference: Puedes buscar por referencia de la factura diff --git a/src/pages/InvoiceOut/Card/InvoiceOutCard.vue b/src/pages/InvoiceOut/Card/InvoiceOutCard.vue index e187a2df2..17b4216da 100644 --- a/src/pages/InvoiceOut/Card/InvoiceOutCard.vue +++ b/src/pages/InvoiceOut/Card/InvoiceOutCard.vue @@ -10,8 +10,10 @@ import InvoiceOutFilter from '../InvoiceOutFilter.vue'; :descriptor="InvoiceOutDescriptor" :filter-panel="InvoiceOutFilter" search-data-key="InvoiceOutList" - search-url="InvoiceOuts/filter" - searchbar-label="Search invoice" - searchbar-info="You can search by invoice reference" + :searchbar-props="{ + url: 'InvoiceOuts/filter', + label: 'Search invoice', + info: 'You can search by invoice reference', + }" /> </template> diff --git a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue index 42b8d92d9..5e4be407e 100644 --- a/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue +++ b/src/pages/InvoiceOut/Card/InvoiceOutDescriptor.vue @@ -84,7 +84,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. /> </template> <template #actions="{ entity }"> - <QCardActions> + <QCardActions class="flex justify-center"> <QBtn v-if="entity.client" size="md" @@ -100,7 +100,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity. color="primary" :to="{ name: 'TicketList', - query: { q: ticketFilter(entity) }, + query: { table: ticketFilter(entity) }, }" > <QTooltip>{{ t('invoiceOut.card.ticketList') }}</QTooltip> diff --git a/src/pages/InvoiceOut/InvoiceOutFilter.vue b/src/pages/InvoiceOut/InvoiceOutFilter.vue index 103e175ec..d0d42ea9b 100644 --- a/src/pages/InvoiceOut/InvoiceOutFilter.vue +++ b/src/pages/InvoiceOut/InvoiceOutFilter.vue @@ -6,7 +6,7 @@ import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const props = defineProps({ @@ -58,7 +58,7 @@ function setWorkers(data) { </QItem> <QItem> <QItemSection> - <VnCurrency + <VnInputNumber :label="t('Amount')" v-model="params.amount" is-outlined diff --git a/src/pages/InvoiceOut/InvoiceOutList.vue b/src/pages/InvoiceOut/InvoiceOutList.vue index 5a611d388..822f6bb33 100644 --- a/src/pages/InvoiceOut/InvoiceOutList.vue +++ b/src/pages/InvoiceOut/InvoiceOutList.vue @@ -1,5 +1,5 @@ <script setup> -import { onMounted, onUnmounted, ref, computed } from 'vue'; +import { onMounted, onUnmounted, ref, computed, watchEffect } from 'vue'; import { useI18n } from 'vue-i18n'; import VnSelect from 'src/components/common/VnSelect.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue'; @@ -12,7 +12,7 @@ import InvoiceOutSummary from './Card/InvoiceOutSummary.vue'; import { toCurrency, toDate } from 'src/filters/index'; import { useStateStore } from 'stores/useStateStore'; import { QBtn } from 'quasar'; -import { watchEffect } from 'vue'; +import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue'; const { t } = useI18n(); const stateStore = useStateStore(); @@ -63,7 +63,7 @@ const columns = computed(() => [ }, { align: 'left', - name: 'clientSocialName', + name: 'clientFk', label: t('invoiceOutModule.customer'), cardVisible: true, component: 'select', @@ -214,15 +214,24 @@ watchEffect(selectedRows); selection: 'multiple', }" > + <template #column-clientFk="{ row }"> + <span class="link" @click.stop> + {{ row.clientSocialName }} + <CustomerDescriptorProxy :id="row.clientFk" /> + </span> + </template> <template #more-create-dialog="{ data }"> - <VnSelect - url="Tickets" - v-model="data.ticketFk" - :label="t('invoiceOutList.tableVisibleColumns.ticket')" - :options="ticketsOptions" - option-label="nickname" - option-value="id" - /> + <div class="flex no-wrap flex-center"> + <VnSelect + url="Tickets" + v-model="data.ticketFk" + :label="t('invoiceOutList.tableVisibleColumns.ticket')" + :options="ticketsOptions" + option-label="nickname" + option-value="id" + /> + <span class="q-ml-md">O</span> + </div> <VnSelect url="Clients" v-model="data.clientFk" @@ -231,10 +240,6 @@ watchEffect(selectedRows); option-label="name" option-value="id" /> - <VnInputDate - :label="t('invoiceOutList.tableVisibleColumns.dueDate')" - v-model="data.maxShipped" - /> <VnSelect url="InvoiceOutSerials" v-model="data.invoiceOutSerial" @@ -243,6 +248,10 @@ watchEffect(selectedRows); option-label="description" option-value="code" /> + <VnInputDate + :label="t('invoiceOutList.tableVisibleColumns.dueDate')" + v-model="data.maxShipped" + /> <VnSelect url="TaxAreas" v-model="data.area" diff --git a/src/pages/InvoiceOut/InvoiceOutMain.vue b/src/pages/InvoiceOut/InvoiceOutMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/InvoiceOut/InvoiceOutMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue index dfc051563..774b42478 100644 --- a/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue +++ b/src/pages/InvoiceOut/InvoiceOutNegativeBases.vue @@ -6,6 +6,9 @@ import { toCurrency } from 'src/filters'; import VnTable from 'src/components/VnTable/VnTable.vue'; import { useInvoiceOutGlobalStore } from 'src/stores/invoiceOutGlobal.js'; import { useArrayData } from 'src/composables/useArrayData'; +import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue'; +import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue'; +import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue'; const { t } = useI18n(); const tableRef = ref(); @@ -71,6 +74,9 @@ const columns = computed(() => [ align: 'left', name: 'amount', label: t('invoiceOutModule.amount'), + columnFilter: { + type: 'number', + }, format: (row) => toCurrency(row.amount), cardVisible: true, }, @@ -168,6 +174,24 @@ const downloadCSV = async () => { :is-editable="false" :use-model="true" > + <template #column-clientId="{ row }"> + <span class="link" @click.stop> + {{ row.clientId }} + <CustomerDescriptorProxy :id="row.clientId" /> + </span> + </template> + <template #column-ticketFk="{ row }"> + <span class="link" @click.stop> + {{ row.ticketFk }} + <TicketDescriptorProxy :id="row.ticketFk" /> + </span> + </template> + <template #column-workerName="{ row }"> + <span class="link" @click.stop> + {{ row.workerName }} + <WorkerDescriptorProxy :id="row.comercialId" /> + </span> + </template> </VnTable> </template> diff --git a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue index 9eeac8355..94eab2aab 100644 --- a/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue +++ b/src/pages/InvoiceOut/InvoiceOutNegativeBasesFilter.vue @@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; -import VnCurrency from 'src/components/common/VnCurrency.vue'; +import VnInputNumber from 'src/components/common/VnInputNumber.vue'; const { t } = useI18n(); const props = defineProps({ @@ -19,7 +19,7 @@ const props = defineProps({ <VnFilterPanel :data-key="props.dataKey" :search-button="true" - :unremovable-params="['from', 'to']" + :un-removable-params="['from', 'to']" :hidden-tags="['from', 'to']" > <template #tags="{ tag, formatFn }"> @@ -86,7 +86,7 @@ const props = defineProps({ </QItem> <QItem> <QItemSection> - <VnCurrency + <VnInputNumber v-model="params.amount" :label="t('invoiceOut.negativeBases.amount')" is-outlined diff --git a/src/pages/Item/Card/CreateGenusForm.vue b/src/pages/Item/Card/CreateGenusForm.vue index 637a1137e..66f5130d4 100644 --- a/src/pages/Item/Card/CreateGenusForm.vue +++ b/src/pages/Item/Card/CreateGenusForm.vue @@ -31,7 +31,7 @@ onMounted(async () => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput ref="genusInputRef" :label="t('Latin genus name')" diff --git a/src/pages/Item/Card/CreateIntrastatForm.vue b/src/pages/Item/Card/CreateIntrastatForm.vue index 3fd1ffe22..5fe254759 100644 --- a/src/pages/Item/Card/CreateIntrastatForm.vue +++ b/src/pages/Item/Card/CreateIntrastatForm.vue @@ -33,7 +33,7 @@ onMounted(async () => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput ref="identifierInputRef" :label="t('createIntrastatForm.identifier')" diff --git a/src/pages/Item/Card/CreateSpecieForm.vue b/src/pages/Item/Card/CreateSpecieForm.vue index 2731820ba..120544fd9 100644 --- a/src/pages/Item/Card/CreateSpecieForm.vue +++ b/src/pages/Item/Card/CreateSpecieForm.vue @@ -31,7 +31,7 @@ onMounted(async () => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput ref="specieInputRef" :label="t('Latin species name')" diff --git a/src/pages/Item/Card/ItemBasicData.vue b/src/pages/Item/Card/ItemBasicData.vue index bf5bb652c..abab402b8 100644 --- a/src/pages/Item/Card/ItemBasicData.vue +++ b/src/pages/Item/Card/ItemBasicData.vue @@ -16,7 +16,6 @@ const route = useRoute(); const { t } = useI18n(); const itemTypesOptions = ref([]); -const itemsWithNameOptions = ref([]); const intrastatsOptions = ref([]); const expensesOptions = ref([]); @@ -36,15 +35,6 @@ const onIntrastatCreated = (response, formData) => { @on-fetch="(data) => (itemTypesOptions = data)" auto-load /> - <FetchData - url="Items/withName" - :filter="{ - fields: ['id', 'name'], - order: 'id DESC', - }" - @on-fetch="(data) => (itemsWithNameOptions = data)" - auto-load - /> <FetchData url="Intrastats" :filter="{ @@ -71,9 +61,9 @@ const onIntrastatCreated = (response, formData) => { :clear-store-on-unmount="false" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect - :label="t('basicData.type')" + :label="t('itemBasicData.type')" v-model="data.typeFk" :options="itemTypesOptions" option-value="id" @@ -93,19 +83,21 @@ const onIntrastatCreated = (response, formData) => { </QItem> </template> </VnSelect> - <VnInput :label="t('basicData.reference')" v-model="data.comment" /> - <VnInput :label="t('basicData.relevancy')" v-model="data.relevancy" /> + <VnInput :label="t('itemBasicData.reference')" v-model="data.comment" /> + <VnInput :label="t('itemBasicData.relevancy')" v-model="data.relevancy" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> - <VnInput :label="t('basicData.stems')" v-model="data.stems" /> + <VnRow> + <VnInput :label="t('itemBasicData.stems')" v-model="data.stems" /> <VnInput - :label="t('basicData.multiplier')" + :label="t('itemBasicData.multiplier')" v-model="data.stemMultiplier" /> <VnSelectDialog - :label="t('basicData.generic')" + :label="t('itemBasicData.generic')" v-model="data.genericFk" - :options="itemsWithNameOptions" + url="Items/withName" + :fields="['id', 'name']" + sort-by="id DESC" option-value="id" option-label="name" map-options @@ -128,9 +120,9 @@ const onIntrastatCreated = (response, formData) => { </template> </VnSelectDialog> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelectDialog - :label="t('basicData.intrastat')" + :label="t('itemBasicData.intrastat')" v-model="data.intrastatFk" :options="intrastatsOptions" option-value="id" @@ -157,7 +149,7 @@ const onIntrastatCreated = (response, formData) => { </VnSelectDialog> <div class="col"> <VnSelect - :label="t('basicData.expfense')" + :label="t('itemBasicData.expense')" v-model="data.expenseFk" :options="expensesOptions" option-value="id" @@ -168,64 +160,67 @@ const onIntrastatCreated = (response, formData) => { /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput - :label="t('basicData.weightByPiece')" + :label="t('itemBasicData.weightByPiece')" v-model.number="data.weightByPiece" :min="0" type="number" :required="true" /> <VnInput - :label="t('basicData.boxUnits')" + :label="t('itemBasicData.boxUnits')" v-model.number="data.packingOut" :min="0" type="number" /> <VnInput - :label="t('basicData.recycledPlastic')" + :label="t('itemBasicData.recycledPlastic')" v-model.number="data.recycledPlastic" :min="0" type="number" /> <VnInput - :label="t('basicData.nonRecycledPlastic')" + :label="t('itemBasicData.nonRecycledPlastic')" v-model.number="data.nonRecycledPlastic" :min="0" type="number" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> - <QCheckbox v-model="data.isActive" :label="t('basicData.isActive')" /> - <QCheckbox v-model="data.hasKgPrice" :label="t('basicData.hasKgPrice')" /> + <VnRow> + <QCheckbox v-model="data.isActive" :label="t('itemBasicData.isActive')" /> + <QCheckbox + v-model="data.hasKgPrice" + :label="t('itemBasicData.hasKgPrice')" + /> <div> <QCheckbox v-model="data.isFragile" - :label="t('basicData.isFragile')" + :label="t('itemBasicData.isFragile')" class="q-mr-sm" /> <QIcon name="info" class="cursor-pointer" size="xs"> <QTooltip max-width="300px"> - {{ t('basicData.isFragileTooltip') }} + {{ t('itemBasicData.isFragileTooltip') }} </QTooltip> </QIcon> </div> <div> <QCheckbox v-model="data.isPhotoRequested" - :label="t('basicData.isPhotoRequested')" + :label="t('itemBasicData.isPhotoRequested')" class="q-mr-sm" /> <QIcon name="info" class="cursor-pointer" size="xs"> <QTooltip> - {{ t('basicData.isPhotoRequestedTooltip') }} + {{ t('itemBasicData.isPhotoRequestedTooltip') }} </QTooltip> </QIcon> </div> </VnRow> <VnRow> <VnInput - :label="t('basicData.description')" + :label="t('itemBasicData.description')" type="textarea" v-model="data.description" fill-input diff --git a/src/pages/Item/Card/ItemBotanical.vue b/src/pages/Item/Card/ItemBotanical.vue index 15492de9f..416c7f78b 100644 --- a/src/pages/Item/Card/ItemBotanical.vue +++ b/src/pages/Item/Card/ItemBotanical.vue @@ -67,7 +67,7 @@ onMounted(async () => { :clear-store-on-unmount="false" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelectDialog :label="t('Genus')" v-model="data.genusFk" diff --git a/src/pages/Item/Card/ItemCard.vue b/src/pages/Item/Card/ItemCard.vue index 66d46f576..1162327c1 100644 --- a/src/pages/Item/Card/ItemCard.vue +++ b/src/pages/Item/Card/ItemCard.vue @@ -10,8 +10,10 @@ import ItemListFilter from '../ItemListFilter.vue'; :descriptor="ItemDescriptor" :filter-panel="ItemListFilter" search-data-key="ItemList" - search-url="Items/filter" - searchbar-label="searchbar.label" - searchbar-info="searchbar.info" + :searchbar-props="{ + url: 'Items/filter', + label: 'searchbar.labelr', + info: 'searchbar.info', + }" /> </template> diff --git a/src/pages/Item/Card/ItemDescriptor.vue b/src/pages/Item/Card/ItemDescriptor.vue index f3eba8c82..8381f0624 100644 --- a/src/pages/Item/Card/ItemDescriptor.vue +++ b/src/pages/Item/Card/ItemDescriptor.vue @@ -48,7 +48,6 @@ const entityId = computed(() => { return $props.id || route.params.id; }); const regularizeStockFormDialog = ref(null); -const item = ref(null); const available = ref(null); const visible = ref(null); const _warehouseFk = ref(null); @@ -113,7 +112,7 @@ const openCloneDialog = async () => { .dialog({ component: VnConfirm, componentProps: { - title: t("All it's properties will be copied"), + title: t('All its properties will be copied'), message: t('Do you want to clone this item?'), }, }) @@ -131,12 +130,7 @@ const openCloneDialog = async () => { :subtitle="data.subtitle" :summary="$props.summary" :url="`Items/${entityId}/getCard`" - @on-fetch=" - (data) => { - item = data; - setData(data); - } - " + @on-fetch="setData" > <template #menu="{}"> <QItem v-ripple clickable @click="openRegularizeStockForm()"> @@ -221,7 +215,7 @@ const openCloneDialog = async () => { <i18n> es: Regularize stock: Regularizar stock - All it's properties will be copied: Todas sus propiedades serán copiadas + All its properties will be copied: Todas sus propiedades serán copiadas Do you want to clone this item?: ¿Desea clonar este artículo? </i18n> diff --git a/src/pages/Item/Card/ItemDescriptorImage.vue b/src/pages/Item/Card/ItemDescriptorImage.vue index aceede880..d923dd28f 100644 --- a/src/pages/Item/Card/ItemDescriptorImage.vue +++ b/src/pages/Item/Card/ItemDescriptorImage.vue @@ -64,7 +64,7 @@ const handlePhotoUpdated = (evt = false) => { <template> <div class="relative-position"> - <VnImg ref="image" :id="$props.entityId" @refresh="handlePhotoUpdated(true)"> + <VnImg ref="image" :id="$props.entityId" zoom-resolution="1600x900"> <template #error> <div class="absolute-full picture text-center q-pa-md flex flex-center"> <div> diff --git a/src/pages/Item/Card/ItemDiary.vue b/src/pages/Item/Card/ItemDiary.vue index 4c0959153..68633caa2 100644 --- a/src/pages/Item/Card/ItemDiary.vue +++ b/src/pages/Item/Card/ItemDiary.vue @@ -1,7 +1,7 @@ <script setup> -import { onMounted, computed, onUnmounted, reactive, ref } from 'vue'; +import { onMounted, computed, onUnmounted, reactive, ref, nextTick, watch } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRoute } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'; @@ -17,9 +17,11 @@ import { toDateFormat } from 'src/filters/date.js'; import { dashIfEmpty } from 'src/filters'; import { date } from 'quasar'; import { useState } from 'src/composables/useState'; +import axios from 'axios'; const { t } = useI18n(); const route = useRoute(); +const router = useRouter(); const stateStore = useStateStore(); const state = useState(); @@ -33,6 +35,7 @@ const itemsBalanceFilter = reactive({ const itemBalances = ref([]); const warehouseFk = ref(null); const _showWhatsBeforeInventory = ref(false); +const inventoriedDate = ref(null); const columns = computed(() => [ { @@ -98,7 +101,7 @@ const showWhatsBeforeInventory = computed({ set: (val) => { _showWhatsBeforeInventory.value = val; if (!val) itemsBalanceFilter.where.date = null; - else itemsBalanceFilter.where.date = new Date(); + else itemsBalanceFilter.where.date = inventoriedDate.value ?? new Date(); }, }); @@ -113,18 +116,36 @@ const getBadgeAttrs = (_date) => { return attrs; }; +const scrollToToday = async () => { + await nextTick(); + const today = Date.vnNew(); + today.setHours(0, 0, 0, 0); + const todayCell = document.querySelector(`td[data-date="${today.toISOString()}"]`); + if (todayCell) { + todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } +}; + +const formatDateForAttribute = (dateValue) => { + if (dateValue instanceof Date) return date.formatDate(dateValue, 'YYYY-MM-DD'); + return dateValue; +}; + const originTypeMap = { entry: { descriptor: EntryDescriptorProxy, icon: 'vn:entry', + color: 'green', }, ticket: { descriptor: TicketDescriptorProxy, icon: 'vn:ticket', + color: 'red', }, order: { descriptor: OrderDescriptorProxy, icon: 'vn:basket', + color: 'yellow', }, }; @@ -142,10 +163,21 @@ onMounted(async () => { if (route.query.warehouseFk) warehouseFk.value = route.query.warehouseFk; else if (user.value) warehouseFk.value = user.value.warehouseFk; itemsBalanceFilter.where.warehouseFk = warehouseFk.value; + const { data } = await axios.get('Configs/findOne'); + inventoriedDate.value = data.inventoried; await fetchItemBalances(); + await scrollToToday(); }); onUnmounted(() => (stateStore.rightDrawer = false)); + +watch( + () => router.currentRoute.value.params.id, + (newId) => { + itemsBalanceFilter.where.itemFk = newId; + itemBalancesRef.value.fetch(); + } +); </script> <template> @@ -215,7 +247,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </QTd> </template> <template #body-cell-date="{ row }"> - <QTd @click.stop> + <QTd @click.stop :data-date="formatDateForAttribute(row.shipped)"> <QBadge v-bind="getBadgeAttrs(row.shipped)" class="q-ma-none" @@ -237,12 +269,13 @@ onUnmounted(() => (stateStore.rightDrawer = false)); > {{ row.originId }} </component> + <QIcon + :name="originTypeMap[row.originType]?.icon" + class="fill-icon q-mr-sm" + size="sm" + :color="originTypeMap[row.originType]?.color" + /> <span class="link"> - <QIcon - :name="originTypeMap[row.originType]?.icon" - class="fill-icon q-mr-sm" - size="xs" - /> {{ row.originId }} </span> </QTd> @@ -264,7 +297,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); > {{ row.entityId }} </component> - <span class="link"> + <span :class="{ link: row.entityId }"> {{ dashIfEmpty(row.entityName) }} </span> </QBadge> diff --git a/src/pages/Item/Card/ItemLastEntries.vue b/src/pages/Item/Card/ItemLastEntries.vue index a3ae99da6..b211790ca 100644 --- a/src/pages/Item/Card/ItemLastEntries.vue +++ b/src/pages/Item/Card/ItemLastEntries.vue @@ -1,5 +1,5 @@ <script setup> -import { onMounted, computed, onUnmounted, reactive, ref } from 'vue'; +import { onMounted, computed, onUnmounted, ref, watch } from 'vue'; import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import { dateRange } from 'src/filters'; @@ -11,6 +11,7 @@ import { toDateTimeFormat } from 'src/filters/date.js'; import { dashIfEmpty } from 'src/filters'; import { toCurrency } from 'filters/index'; import { useArrayData } from 'composables/useArrayData'; +import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; const { t } = useI18n(); const route = useRoute(); @@ -35,26 +36,8 @@ const exprBuilder = (param, value) => { } }; -const datedRange = reactive({ - from: null, - to: null, -}); - -const from = computed({ - get: () => datedRange.from, - set: (val) => { - updateFrom(val); - updateFilter(); - }, -}); - -const to = computed({ - get: () => datedRange.to, - set: (val) => { - updateTo(val); - updateFilter(); - }, -}); +const from = ref(); +const to = ref(); const arrayData = useArrayData('ItemLastEntries', { url: 'Items/lastEntriesFilter', @@ -162,41 +145,48 @@ const fetchItemLastEntries = async () => { itemLastEntries.value = data; }; -const updateFrom = async (date) => { - date.setHours(0, 0, 0, 0); - datedRange.from = date.toISOString(); -}; - -const updateTo = async (date) => { - date.setHours(23, 59, 59, 59); - datedRange.to = date.toISOString(); +const getDate = (date, type) => { + if (type == 'from') { + date.setHours(0, 0, 0, 0); + } else if (type == 'to') { + date.setHours(23, 59, 59, 999); + } + return date.toISOString(); }; const updateFilter = async () => { - arrayData.store.userFilter.where.landed = { - between: [datedRange.from, datedRange.to], - }; + let filter; + if (!from.value && to.value) filter = { lte: to.value }; + else if (from.value && !to.value) filter = { gte: from.value }; + else if (from.value && to.value) filter = { between: [from.value, to.value] }; + + arrayData.store.userFilter.where.landed = filter; await fetchItemLastEntries(); }; onMounted(async () => { const _from = Date.vnNew(); _from.setDate(_from.getDate() - 75); - updateFrom(_from); - + from.value = getDate(_from, 'from'); const _to = Date.vnNew(); _to.setDate(_to.getDate() + 10); - updateTo(_to); + to.value = getDate(Date.vnNew(), 'to'); updateFilter(); + + watch([from, to], ([nFrom, nTo], [oFrom, oTo]) => { + if (nFrom && nFrom != oFrom) nFrom = getDate(new Date(nFrom), 'from'); + if (nTo && nTo != oTo) nTo = getDate(new Date(nTo), 'to'); + updateFilter(); + }); }); onUnmounted(() => (stateStore.rightDrawer = false)); </script> <template> - <QToolbar class="justify-end"> - <div id="st-data" class="row"> + <VnSubToolbar> + <template #st-data> <VnInputDate :label="t('lastEntries.since')" dense @@ -204,11 +194,9 @@ onUnmounted(() => (stateStore.rightDrawer = false)); class="q-mr-lg" /> <VnInputDate :label="t('lastEntries.to')" dense v-model="to" /> - </div> - <QSpace /> - <div id="st-actions"></div> - </QToolbar> - <QPage class="column items-center q-pa-md"> + </template> + </VnSubToolbar> + <QPage class="column items-center q-pa-xd"> <QTable :rows="itemLastEntries" :columns="columns" diff --git a/src/pages/Item/Card/ItemTags.vue b/src/pages/Item/Card/ItemTags.vue index b3cdfffb1..40c9941e9 100644 --- a/src/pages/Item/Card/ItemTags.vue +++ b/src/pages/Item/Card/ItemTags.vue @@ -42,9 +42,10 @@ const onItemTagsFetched = async (itemTags) => { }); }; -const handleTagSelected = (rows, index, tag) => { +const handleTagSelected = (rows, index, tagId) => { + const tag = tagOptions.value.find((t) => t.id === tagId); rows[index].tag = tag; - rows[index].tagFk = tag.id; + rows[index].tagFk = tagId; rows[index].value = null; getSelectedTagValues(rows[index]); }; @@ -94,7 +95,6 @@ const insertTag = (rows) => { :filter="{ fields: ['id', 'itemFk', 'tagFk', 'value', 'priority'], where: { itemFk: route.params.id }, - order: 'priority ASC', include: { relation: 'tag', scope: { @@ -102,16 +102,13 @@ const insertTag = (rows) => { }, }, }" + order="priority" auto-load @on-fetch="onItemTagsFetched" > <template #body="{ rows, validate }"> - <QCard class="q-pl-lg q-py-md"> - <VnRow - v-for="(row, index) in rows" - :key="index" - class="row q-gutter-md q-mb-md" - > + <QCard class="q-px-lg q-pt-md q-pb-sm"> + <VnRow v-for="(row, index) in rows" :key="index"> <VnSelect :label="t('itemTags.tag')" :options="tagOptions" @@ -119,7 +116,7 @@ const insertTag = (rows) => { option-label="name" hide-selected @update:model-value=" - ($event) => handleTagSelected(rows, index, $event) + (val) => handleTagSelected(rows, index, val) " :required="true" :rules="validate('itemTag.tagFk')" @@ -146,7 +143,6 @@ const insertTag = (rows) => { v-model="row.value" :label="t('itemTags.value')" :is-clearable="false" - style="width: 100%" /> <VnInput :label="t('itemTags.relevancy')" @@ -155,7 +151,7 @@ const insertTag = (rows) => { :required="true" :rules="validate('itemTag.priority')" /> - <div class="col-1 row justify-center items-center"> + <div class="row justify-center items-center" style="flex: 0"> <QIcon @click="itemTagsRef.remove([row])" class="fill-icon-on-hover" @@ -169,7 +165,7 @@ const insertTag = (rows) => { </QIcon> </div> </VnRow> - <VnRow> + <VnRow class="justify-center items-center"> <QIcon @click="insertTag(rows)" class="cursor-pointer" @@ -177,6 +173,7 @@ const insertTag = (rows) => { color="primary" name="add" size="sm" + style="flex: 0" > <QTooltip> {{ t('itemTags.addTag') }} diff --git a/src/pages/Item/ItemCreate.vue b/src/pages/Item/ItemCreate.vue index baa51414c..6b6234b70 100644 --- a/src/pages/Item/ItemCreate.vue +++ b/src/pages/Item/ItemCreate.vue @@ -85,7 +85,7 @@ onBeforeMount(async () => { @on-data-saved="redirectToItemBasicData" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.provisionalName" :label="t('item.create.name')" @@ -107,7 +107,7 @@ onBeforeMount(async () => { hide-selected /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('item.create.type')" v-model="data.typeFk" @@ -154,7 +154,7 @@ onBeforeMount(async () => { </template> </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('item.create.origin')" v-model="data.originFk" diff --git a/src/pages/Item/ItemListFilter.vue b/src/pages/Item/ItemListFilter.vue index a51f9ebb4..62c0c56dc 100644 --- a/src/pages/Item/ItemListFilter.vue +++ b/src/pages/Item/ItemListFilter.vue @@ -56,6 +56,7 @@ const onCategoryChange = async (categoryFk, search) => { const getSelectedTagValues = async (tag) => { try { + if (!tag?.selectedTag?.id) return; tag.value = null; const filter = { fields: ['value'], diff --git a/src/pages/Item/ItemMain.vue b/src/pages/Item/ItemMain.vue deleted file mode 100644 index c1f2a31db..000000000 --- a/src/pages/Item/ItemMain.vue +++ /dev/null @@ -1,18 +0,0 @@ -<script setup> -import LeftMenu from 'src/components/LeftMenu.vue'; - -import { useStateStore } from 'stores/useStateStore'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Item/ItemRequestDenyForm.vue b/src/pages/Item/ItemRequestDenyForm.vue index f26edb845..be70fb799 100644 --- a/src/pages/Item/ItemRequestDenyForm.vue +++ b/src/pages/Item/ItemRequestDenyForm.vue @@ -36,7 +36,7 @@ onMounted(async () => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInput ref="textAreaRef" diff --git a/src/pages/Item/ItemTypeCreate.vue b/src/pages/Item/ItemTypeCreate.vue index af3dc34ea..b7b06bbe6 100644 --- a/src/pages/Item/ItemTypeCreate.vue +++ b/src/pages/Item/ItemTypeCreate.vue @@ -53,11 +53,11 @@ const redirectToItemTypeBasicData = (_, { id }) => { @on-data-saved="redirectToItemTypeBasicData" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.code" :label="t('itemType.shared.code')" /> <VnInput v-model="data.name" :label="t('itemType.shared.name')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect v-model="data.workerFk" :label="t('itemType.shared.worker')" @@ -75,7 +75,7 @@ const redirectToItemTypeBasicData = (_, { id }) => { hide-selected /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect v-model="data.temperatureFk" :label="t('itemType.shared.temperature')" diff --git a/src/pages/Item/locale/en.yml b/src/pages/Item/locale/en.yml index 0e855523c..c32ee493c 100644 --- a/src/pages/Item/locale/en.yml +++ b/src/pages/Item/locale/en.yml @@ -25,7 +25,7 @@ itemDiary: showBefore: Show what's before the inventory since: Since warehouse: Warehouse -basicData: +itemBasicData: type: Type reference: Reference relevancy: Relevancy diff --git a/src/pages/Item/locale/es.yml b/src/pages/Item/locale/es.yml index 451b75698..d32cb7885 100644 --- a/src/pages/Item/locale/es.yml +++ b/src/pages/Item/locale/es.yml @@ -25,7 +25,7 @@ itemDiary: showBefore: Mostrar lo anterior al inventario since: Desde warehouse: Almacén -basicData: +itemBasicData: type: Tipo reference: Referencia relevancy: Relevancia diff --git a/src/pages/ItemType/Card/ItemTypeBasicData.vue b/src/pages/ItemType/Card/ItemTypeBasicData.vue index 0bdfab951..51e24272d 100644 --- a/src/pages/ItemType/Card/ItemTypeBasicData.vue +++ b/src/pages/ItemType/Card/ItemTypeBasicData.vue @@ -42,11 +42,11 @@ const temperaturesOptions = ref([]); auto-load > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.code" :label="t('shared.code')" /> <VnInput v-model="data.name" :label="t('shared.name')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect v-model="data.workerFk" :label="t('shared.worker')" @@ -64,7 +64,7 @@ const temperaturesOptions = ref([]); hide-selected /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect v-model="data.temperatureFk" :label="t('shared.temperature')" diff --git a/src/pages/Login/LoginMain.vue b/src/pages/Login/LoginMain.vue index 5a3490f50..44b868ebd 100644 --- a/src/pages/Login/LoginMain.vue +++ b/src/pages/Login/LoginMain.vue @@ -1,6 +1,6 @@ <script setup> import { ref } from 'vue'; -import { Notify, useQuasar } from 'quasar'; +import { Notify } from 'quasar'; import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; @@ -11,7 +11,6 @@ import VnLogo from 'components/ui/VnLogo.vue'; import VnInput from 'src/components/common/VnInput.vue'; import axios from 'axios'; -const quasar = useQuasar(); const session = useSession(); const loginCache = useLogin(); const router = useRouter(); @@ -28,35 +27,10 @@ async function onSubmit() { }; try { const { data } = await axios.post('Accounts/login', params); - if (!data) return; - const { - data: { multimediaToken }, - } = await axios.get('VnUsers/ShareToken', { - headers: { Authorization: data.token }, - }); - if (!multimediaToken) return; - - const login = { - ...data, - created: Date.now(), - tokenMultimedia: multimediaToken.id, - keepLogin: keepLogin.value, - }; - await session.login(login); - - quasar.notify({ - message: t('login.loginSuccess'), - type: 'positive', - }); - - const currentRoute = router.currentRoute.value; - if (currentRoute.query && currentRoute.query.redirect) { - router.push(currentRoute.query.redirect); - } else { - router.push({ name: 'Dashboard' }); - } + data.keepLogin = keepLogin.value; + await session.setLogin(data); } catch (res) { if (res.response?.data?.error?.code === 'REQUIRES_2FA') { Notify.create({ @@ -97,7 +71,8 @@ async function onSubmit() { :rules="[(val) => (val && val.length > 0) || t('login.fieldRequired')]" class="red" /> - <div> + <QToggle v-model="keepLogin" :label="t('login.keepLogin')" /> + <div class="column flex-center q-mt-lg"> <QBtn :label="t('login.submit')" type="submit" @@ -106,11 +81,15 @@ async function onSubmit() { rounded unelevated /> + <RouterLink + class="q-mt-md text-primary" + :to="`/recoverPassword?user=${username}`" + > + {{ t('I do not remember my password') }} + </RouterLink> </div> - <QToggle v-model="keepLogin" :label="t('login.keepLogin')" /> </QForm> </template> - <style lang="scss" scoped> .formCard { max-width: 350px; @@ -126,3 +105,7 @@ async function onSubmit() { } } </style> +<i18n> +es: + I do not remember my password: No recuerdo mi contraseña +</i18n> diff --git a/src/pages/Login/RecoverPassword.vue b/src/pages/Login/RecoverPassword.vue new file mode 100644 index 000000000..5e0fd367a --- /dev/null +++ b/src/pages/Login/RecoverPassword.vue @@ -0,0 +1,59 @@ +<script setup> +import { ref } from 'vue'; +import { useQuasar } from 'quasar'; +import { useI18n } from 'vue-i18n'; +import { useRouter, useRoute } from 'vue-router'; +import axios from 'axios'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnOutForm from 'src/components/ui/VnOutForm.vue'; + +const quasar = useQuasar(); +const router = useRouter(); +const route = useRoute(); +const { t } = useI18n(); + +const user = ref(route.query.user); + +async function onSubmit() { + try { + await axios.post('VnUsers/recoverPassword', { user: user.value, app: 'lilium' }); + router.push('Login'); + quasar.notify({ + message: t('globals.notificationSent'), + type: 'positive', + }); + } catch (e) { + quasar.notify({ + message: e.response?.data?.error.message, + type: 'negative', + }); + } +} +</script> +<template> + <VnOutForm @submit="onSubmit" :title="t('globals.pageTitles.recoverPassword')"> + <template #default> + <VnInput + v-model="user" + :label="t('recoverPassword.userOrEmail')" + :hint="t('recoverPassword.explanation')" + autofocus + required + > + <template #prepend> + <QIcon name="contact_mail" /> + </template> + </VnInput> + </template> + <template #buttons> + <QBtn + :label="t('globals.pageTitles.recoverPassword')" + type="submit" + color="primary" + class="full-width q-mt-md" + rounded + unelevated + /> + </template> + </VnOutForm> +</template> diff --git a/src/pages/Login/ResetPassword.vue b/src/pages/Login/ResetPassword.vue new file mode 100644 index 000000000..eff718e97 --- /dev/null +++ b/src/pages/Login/ResetPassword.vue @@ -0,0 +1,99 @@ +<script setup> +import { ref, onMounted } from 'vue'; +import { useQuasar } from 'quasar'; +import { useI18n } from 'vue-i18n'; +import { useRouter, useRoute } from 'vue-router'; +import axios from 'axios'; + +import VnInput from 'components/common/VnInput.vue'; +import VnOutForm from 'components/ui/VnOutForm.vue'; + +const quasar = useQuasar(); +const router = useRouter(); +const route = useRoute(); +const { t } = useI18n(); + +const newPassword = ref(); +const repeatPassword = ref(); +const passRequirements = ref({}); + +onMounted(async () => { + passRequirements.value = (await axios('UserPasswords/findOne')).data; +}); + +async function onSubmit() { + if (newPassword.value != repeatPassword.value) + return quasar.notify({ + message: t('resetPassword.passwordNotMatch'), + type: 'negative', + }); + + const headers = { + Authorization: route.query.access_token, + }; + + try { + console.log('newPassword: ', newPassword); + await axios.post( + 'VnUsers/reset-password', + { newPassword: newPassword.value }, + { headers } + ); + router.push('Login'); + quasar.notify({ + message: t('resetPassword.passwordChanged'), + type: 'positive', + }); + } catch (e) { + quasar.notify({ + message: e.response?.data?.error.message, + type: 'negative', + }); + } +} +</script> +<template> + <VnOutForm @submit="onSubmit" :title="t('globals.pageTitles.resetPassword')"> + <template #default> + <VnInput + type="password" + :label="t('login.password')" + v-model="newPassword" + :info=" + t('passwordRequirements', { + length: passRequirements.length, + nAlpha: passRequirements.nAlpha, + nUpper: passRequirements.nUpper, + nDigits: passRequirements.nDigits, + nPunct: passRequirements.nPunct, + }) + " + required + > + <template #prepend> + <QIcon name="password" /> + </template> + </VnInput> + <VnInput + type="password" + :label="t('resetPassword.repeatPassword')" + v-model="repeatPassword" + required + > + <template #prepend> + <QIcon name="password" /> + </template> + </VnInput> + </template> + <template #buttons> + <QBtn + :label="t('globals.pageTitles.resetPassword')" + type="submit" + color="primary" + class="full-width q-mt-md" + rounded + unelevated + /> + </template> + </VnOutForm> +</template> diff --git a/src/pages/Login/TwoFactor.vue b/src/pages/Login/TwoFactor.vue index b3a139149..dd404094f 100644 --- a/src/pages/Login/TwoFactor.vue +++ b/src/pages/Login/TwoFactor.vue @@ -7,6 +7,8 @@ import axios from 'axios'; import { useSession } from 'src/composables/useSession'; import { useLogin } from 'src/composables/useLogin'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnOutForm from 'src/components/ui/VnOutForm.vue'; const quasar = useQuasar(); const session = useSession(); @@ -24,21 +26,10 @@ async function onSubmit() { try { params.code = code.value; const { data } = await axios.post('VnUsers/validate-auth', params); - if (!data) return; - await session.login(data.token, params.keepLogin); - quasar.notify({ - message: t('login.loginSuccess'), - type: 'positive', - }); - - const currentRoute = router.currentRoute.value; - if (currentRoute.query && currentRoute.query.redirect) { - router.push(currentRoute.query.redirect); - } else { - router.push({ name: 'Dashboard' }); - } + data.keepLogin = params.keepLogin; + await session.setLogin(data); } catch (e) { quasar.notify({ message: e.response?.data?.error.message, @@ -48,24 +39,22 @@ async function onSubmit() { } </script> <template> - <QForm @submit="onSubmit" class="q-gutter-y-md q-pa-lg formCard"> - <div class="column items-center"> - <QIcon name="phonelink_lock" size="xl" color="primary" /> - <h5 class="text-center q-my-md">{{ t('twoFactor.insert') }}</h5> - </div> - <VnInput - v-model="code" - :hint="t('twoFactor.explanation')" - mask="# # # # # #" - fill-mask - unmasked-value - autofocus - > - <template #prepend> - <QIcon name="lock" /> - </template> - </VnInput> - <div class="q-mt-xl"> + <VnOutForm @submit="onSubmit" :title="t('twoFactor.insert')"> + <template #default> + <VnInput + v-model="code" + :hint="t('twoFactor.explanation')" + mask="# # # # # #" + fill-mask + unmasked-value + autofocus + > + <template #prepend> + <QIcon name="lock" /> + </template> + </VnInput> + </template> + <template #buttons> <QBtn :label="t('twoFactor.validate')" type="submit" @@ -74,18 +63,6 @@ async function onSubmit() { rounded unelevated /> - </div> - </QForm> + </template> + </VnOutForm> </template> -<style lang="scss" scoped> -.formCard { - max-width: 350px; - min-width: 300px; -} - -@media (max-width: $breakpoint-xs-max) { - .formCard { - min-width: 100%; - } -} -</style> diff --git a/src/pages/Monitor/MonitorMain.vue b/src/pages/Monitor/MonitorMain.vue deleted file mode 100644 index c1f2a31db..000000000 --- a/src/pages/Monitor/MonitorMain.vue +++ /dev/null @@ -1,18 +0,0 @@ -<script setup> -import LeftMenu from 'src/components/LeftMenu.vue'; - -import { useStateStore } from 'stores/useStateStore'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Monitor/SalesTicketsTable.vue b/src/pages/Monitor/SalesTicketsTable.vue index 1ca68240b..b301c1145 100644 --- a/src/pages/Monitor/SalesTicketsTable.vue +++ b/src/pages/Monitor/SalesTicketsTable.vue @@ -1,8 +1,6 @@ <script setup> -import { ref, computed, onMounted, reactive } from 'vue'; +import { ref, computed, reactive } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; - import FetchData from 'components/FetchData.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; @@ -11,18 +9,14 @@ import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.v import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue'; import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue'; import TicketSummary from 'src/pages/Ticket/Card/TicketSummary.vue'; -import VnInput from 'src/components/common/VnInput.vue'; -import VnSelect from 'src/components/common/VnSelect.vue'; -import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnTable from 'components/VnTable/VnTable.vue'; - import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { toDateFormat, toTimeFormat } from 'src/filters/date.js'; import { toCurrency, dateRange } from 'src/filters'; + const DEFAULT_AUTO_REFRESH = 1000; const { t } = useI18n(); const autoRefresh = ref(false); -const router = useRouter(); const paginateRef = ref(null); const workersActiveOptions = ref([]); const provincesOptions = ref([]); @@ -57,46 +51,6 @@ function exprBuilder(param, value) { const filter = { order: ['totalProblems DESC'] }; let params = reactive({}); -const applyColumnFilter = async (col) => { - try { - const paramKey = col.columnFilter?.filterParamKey || col.field; - params[paramKey] = col.columnFilter.filterValue; - await paginateRef.value.addFilter(null, params); - } catch (err) { - console.error('Error applying column filter', err); - } -}; - -const getInputEvents = (col) => { - return col.columnFilter.type === 'select' || col.columnFilter.type === 'date' - ? { 'update:modelValue': () => applyColumnFilter(col) } - : { - 'keyup.enter': () => applyColumnFilter(col), - }; -}; - -const fetchParams = ($params = {}) => { - const excludedParams = ['search', 'clientFk', 'orderFk', 'refFk', 'scopeDays']; - - const hasExcludedParams = excludedParams.some((param) => { - return $params && $params[param] != undefined; - }); - const hasParams = Object.entries($params).length; - if (!hasParams || !hasExcludedParams) $params.scopeDays = 1; - - if (typeof $params.scopeDays === 'number') { - const from = Date.vnNew(); - from.setHours(0, 0, 0, 0); - - const to = new Date(from.getTime()); - to.setDate(to.getDate() + $params.scopeDays); - to.setHours(23, 59, 59, 999); - - Object.assign($params, { from, to }); - } - return { tableOrder: 'totalProblems DESC', ...$params }; -}; - const columns = computed(() => [ { label: t('salesTicketsTable.problems'), @@ -379,13 +333,6 @@ const redirectToSales = (id) => { const url = `#/ticket/${id}/sale`; window.open(url, '_blank'); }; - -// onMounted(async () => { -// const filteredColumns = columns.value.filter((col) => col.name !== 'rowActions'); -// allColumnNames.value = filteredColumns.map((col) => col.name); -// params = fetchParams(); -// await paginateRef.value.addFilter(null, params); -// }); </script> <template> diff --git a/src/pages/Order/Card/OrderForm.vue b/src/pages/Order/Card/OrderBasicData.vue similarity index 84% rename from src/pages/Order/Card/OrderForm.vue rename to src/pages/Order/Card/OrderBasicData.vue index e4dfcd0e0..4bc9e2e43 100644 --- a/src/pages/Order/Card/OrderForm.vue +++ b/src/pages/Order/Card/OrderBasicData.vue @@ -1,5 +1,5 @@ <script setup> -import { useRoute, useRouter } from 'vue-router'; +import { useRoute } from 'vue-router'; import { ref } from 'vue'; import { useI18n } from 'vue-i18n'; import axios from 'axios'; @@ -7,6 +7,7 @@ import { useState } from 'composables/useState'; import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnSelect from 'components/common/VnSelect.vue'; +import VnInput from 'components/common/VnInput.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; @@ -15,7 +16,6 @@ const route = useRoute(); const state = useState(); const ORDER_MODEL = 'order'; -const router = useRouter(); const isNew = Boolean(!route.params.id); const clientList = ref([]); const agencyList = ref([]); @@ -64,13 +64,6 @@ const fetchOrderDetails = (order) => { fetchAgencyList(order?.landed, order?.addressFk); }; -const orderMapper = (order) => { - return { - addressId: order.addressFk, - agencyModeId: order.agencyModeFk, - landed: new Date(order.landed).toISOString(), - }; -}; const orderFilter = { include: [ { relation: 'agencyMode', scope: { fields: ['name'] } }, @@ -106,10 +99,6 @@ const onClientChange = async (clientId) => { console.error('Error al cambiar el cliente:', error); } }; - -async function onDataSaved({ id }) { - await router.push({ path: `/order/${id}/catalog` }); -} </script> <template> @@ -117,15 +106,14 @@ async function onDataSaved({ id }) { <div class="q-pa-md"> <FormModel :url="`Orders/${route.params.id}`" - @on-data-saved="onDataSaved" + :url-update="`Orders/${route.params.id}/updateBasicData`" :model="ORDER_MODEL" - :mapper="orderMapper" :filter="orderFilter" @on-fetch="fetchOrderDetails" auto-load > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect url="Clients" :label="t('order.form.clientFk')" @@ -171,7 +159,7 @@ async function onDataSaved({ id }) { </template> </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate placeholder="dd-mm-aaa" :label="t('order.form.landed')" @@ -180,8 +168,6 @@ async function onDataSaved({ id }) { () => fetchAgencyList(data.landed, data.addressFk) " /> - </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> <VnSelect :label="t('order.form.agencyModeFk')" v-model="data.agencyModeFk" @@ -189,9 +175,29 @@ async function onDataSaved({ id }) { option-value="agencyModeFk" option-label="agencyMode" hide-selected - :disable="!agencyList?.length" - > - </VnSelect> + :disable="!agencyList?.length && data.isConfirmed === 1" + clearable + emit-value + map-options + :model-value=" + !data.isConfirmed && + agencyList?.length && + agencyList.some( + (agency) => agency.agencyModeFk === data.agency_id + ) + ? data.agencyModeFk + : null + " + /> + </VnRow> + <VnRow> + <VnInput + :label="t('globals.notes')" + type="textarea" + v-model="data.note" + fill-input + autogrow + /> </VnRow> </template> </FormModel> diff --git a/src/pages/Order/Card/OrderCard.vue b/src/pages/Order/Card/OrderCard.vue index 5b6896656..67c0f1de5 100644 --- a/src/pages/Order/Card/OrderCard.vue +++ b/src/pages/Order/Card/OrderCard.vue @@ -1,16 +1,35 @@ <script setup> +import { computed } from 'vue'; +import { useRoute } from 'vue-router'; import VnCard from 'components/common/VnCard.vue'; import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue'; import OrderFilter from './OrderFilter.vue'; import OrderSearchbar from './OrderSearchbar.vue'; +import OrderCatalogFilter from './OrderCatalogFilter.vue'; +const config = { + OrderCatalog: OrderCatalogFilter, +}; +const route = useRoute(); + +const routeName = computed(() => route.name); +const customRouteRedirectName = computed(() => { + const route = config[routeName.value]; + if (route) return null; + return 'OrderList'; +}); +const customFilterPanel = computed(() => { + const filterPanel = config[routeName.value] ?? OrderFilter; + return filterPanel; +}); </script> + <template> <VnCard data-key="Order" base-url="Orders" :descriptor="OrderDescriptor" - :filter-panel="OrderFilter" - search-data-key="OrderList" + :filter-panel="customFilterPanel" + :search-data-key="customRouteRedirectName" > <template #searchbar> <OrderSearchbar /> diff --git a/src/pages/Order/OrderCatalog.vue b/src/pages/Order/Card/OrderCatalog.vue similarity index 77% rename from src/pages/Order/OrderCatalog.vue rename to src/pages/Order/Card/OrderCatalog.vue index 2cf6e1c29..68bf9511f 100644 --- a/src/pages/Order/OrderCatalog.vue +++ b/src/pages/Order/Card/OrderCatalog.vue @@ -1,17 +1,24 @@ <script setup> import { useStateStore } from 'stores/useStateStore'; -import { useRoute } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import { onMounted, onUnmounted, ref } from 'vue'; +import axios from 'axios'; import { useI18n } from 'vue-i18n'; import VnPaginate from 'components/ui/VnPaginate.vue'; import CatalogItem from 'components/ui/CatalogItem.vue'; import OrderCatalogFilter from 'pages/Order/Card/OrderCatalogFilter.vue'; +import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; const route = useRoute(); +const router = useRouter(); const stateStore = useStateStore(); const { t } = useI18n(); +const tags = ref([]); -onMounted(() => (stateStore.rightDrawer = true)); +onMounted(() => { + stateStore.rightDrawer = true; + checkOrderConfirmation(); +}); onUnmounted(() => (stateStore.rightDrawer = false)); const catalogParams = { @@ -19,7 +26,12 @@ const catalogParams = { orderBy: JSON.stringify({ field: 'relevancy DESC, name', way: 'ASC', isTag: false }), }; -const tags = ref([]); +async function checkOrderConfirmation() { + const response = await axios.get(`Orders/${route.params.id}`); + if (response.data.isConfirmed === 1) { + router.push(`/order/${route.params.id}/line`); + } +} function extractTags(items) { const resultTags = []; @@ -52,6 +64,15 @@ function extractValueTags(items) { </script> <template> + <VnSearchbar + data-key="OrderCatalogList" + :user-params="catalogParams" + :static-params="['orderFk', 'orderBy']" + :redirect="false" + url="Orders/CatalogFilter" + :label="t('Search items')" + :info="t('You can search items by name or id')" + /> <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> <QScrollArea class="fit text-grey-8"> <OrderCatalogFilter @@ -68,7 +89,6 @@ function extractValueTags(items) { url="Orders/CatalogFilter" :limit="50" :user-params="catalogParams" - auto-load @on-fetch="extractTags" :update-router="false" > @@ -106,3 +126,8 @@ function extractValueTags(items) { text-align: center; } </style> + +<i18n> +es: + You can search items by name or id: Puedes buscar items por nombre o id +</i18n> diff --git a/src/pages/Order/Card/OrderCatalogFilter.vue b/src/pages/Order/Card/OrderCatalogFilter.vue index c354ec94b..850abb755 100644 --- a/src/pages/Order/Card/OrderCatalogFilter.vue +++ b/src/pages/Order/Card/OrderCatalogFilter.vue @@ -7,8 +7,8 @@ import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; import VnFilterPanelChip from 'components/ui/VnFilterPanelChip.vue'; -import { useValidator } from 'src/composables/useValidator'; import VnInput from 'src/components/common/VnInput.vue'; +import getParamWhere from 'src/filters/getParamWhere'; const { t } = useI18n(); @@ -27,19 +27,26 @@ const props = defineProps({ required: true, }, }); - const categoryList = ref(null); -const selectedCategoryFk = ref(null); -const typeList = ref(null); +const selectedCategoryFk = ref(getParamWhere(route, 'categoryFk')); +const typeList = ref([]); const selectedTypeFk = ref(null); -const validationsStore = useValidator(); -const selectedOrder = ref(null); -const selectedOrderField = ref(null); -const moreFields = ref([]); -const moreFieldsOrder = ref([]); const selectedTag = ref(null); const tagValues = ref([{}]); const tagOptions = ref([]); +const vnFilterPanelRef = ref(); +const orderByList = ref([ + { id: 'relevancy DESC, name', name: t('params.relevancy'), priority: 999 }, + { id: 'showOrder, price', name: t('params.colorAndPrice'), priority: 999 }, + { id: 'name', name: t('params.name'), priority: 999 }, + { id: 'price', name: t('params.price'), priority: 999 }, +]); +const orderWayList = ref([ + { id: 'ASC', name: t('params.ASC') }, + { id: 'DESC', name: t('params.DESC') }, +]); +const orderBySelected = ref('relevancy DESC, name'); +const orderWaySelected = ref('ASC'); const createValue = (val, done) => { if (val.length > 2) { @@ -72,7 +79,7 @@ const selectCategory = (params, category, search) => { search(); }; -const loadTypes = async (categoryFk) => { +const loadTypes = async (categoryFk = selectedCategoryFk.value) => { const { data } = await axios.get(`Orders/${route.params.id}/getItemTypeAvailable`, { params: { itemCategoryId: categoryFk }, }); @@ -84,7 +91,14 @@ const selectedCategory = computed(() => (category) => category?.id === selectedCategoryFk.value ) ); - +function filterFn(val, update) { + update(() => { + const needle = val.toLowerCase(); + tagOptions.value = props.tagValue.filter( + (v) => v.toLowerCase().indexOf(needle) > -1 + ); + }); +} const selectedType = computed(() => { return (typeList.value || []).find((type) => type?.id === selectedTypeFk.value); }); @@ -95,7 +109,8 @@ function exprBuilder(param, value) { case 'typeFk': return { [param]: value }; case 'search': - return { 'i.name': { like: `%${value}%` } }; + if (/^\d+$/.test(value)) return { 'i.id': value }; + else return { 'i.name': { like: `%${value}%` } }; } } @@ -132,36 +147,6 @@ const removeTagChip = (selection, params, search) => { search(); }; -const onOrderChange = (value, params) => { - const tagObj = JSON.parse(params.orderBy); - tagObj.way = value.name; - params.orderBy = JSON.stringify(tagObj); -}; - -const onOrderFieldChange = (value, params) => { - const tagObj = JSON.parse(params.orderBy); - switch (value) { - case 'Relevancy': - tagObj.name = value + ' DESC, name'; - params.orderBy = JSON.stringify(tagObj); - break; - case 'ColorAndPrice': - tagObj.name = 'showOrder, price'; - params.orderBy = JSON.stringify(tagObj); - break; - case 'Name': - tagObj.name = 'name'; - params.orderBy = JSON.stringify(tagObj); - break; - case 'Price': - tagObj.name = 'price'; - params.orderBy = JSON.stringify(tagObj); - break; - } -}; - -const _moreFields = ['ASC', 'DESC']; -const _moreFieldsTypes = ['Relevancy', 'ColorAndPrice', 'Name', 'Price']; const setCategoryList = (data) => { categoryList.value = (data || []) .filter((category) => category.display) @@ -169,8 +154,8 @@ const setCategoryList = (data) => { ...category, icon: `vn:${(category.icon || '').split('-')[1]}`, })); - moreFields.value = useLang(_moreFields); - moreFieldsOrder.value = useLang(_moreFieldsTypes); + + selectedCategoryFk.value && loadTypes(); }; const getCategoryClass = (category, params) => { @@ -179,27 +164,22 @@ const getCategoryClass = (category, params) => { } }; -const useLang = (values) => { - const { models } = validationsStore; - const properties = models.Item?.properties || {}; - return values.map((name) => { - let prop = properties[name]; - const label = t(`params.${name}`); - return { - name, - label, - type: prop ? prop.type : null, - }; - }); -}; +function addOrder(value, field, params) { + let { orderBy } = params; + orderBy = JSON.parse(orderBy); + orderBy[field] = value; + params.orderBy = JSON.stringify(orderBy); + vnFilterPanelRef.value.search(); +} </script> <template> <FetchData url="ItemCategories" limit="30" auto-load @on-fetch="setCategoryList" /> <VnFilterPanel + ref="vnFilterPanelRef" :data-key="props.dataKey" :hidden-tags="['orderFk', 'orderBy']" - :unremovable-params="['orderFk', 'orderBy']" + :un-removable-params="['orderFk', 'orderBy']" :expr-builder="exprBuilder" :custom-tags="['tagGroups']" @remove="clearFilter" @@ -289,33 +269,29 @@ const useLang = (values) => { </QItemSection> </QItem> <QSeparator /> - <QItem class="q-my-md"> - <QItemSection> - <VnSelect - :label="t('Order')" - v-model="selectedOrder" - :options="moreFields" - option-label="label" - option-value="way" - dense - outlined - rounded - @update:model-value="(value) => onOrderChange(value, params)" - /> - </QItemSection> - </QItem> <QItem class="q-mb-md"> <QItemSection> <VnSelect :label="t('Order by')" - v-model="selectedOrderField" - :options="moreFieldsOrder" - option-label="label" - option-value="name" + v-model="orderBySelected" + :options="orderByList" dense outlined rounded - @update:model-value="(value) => onOrderFieldChange(value, params)" + @update:model-value="(value) => addOrder(value, 'field', params)" + /> + </QItemSection> + </QItem> + <QItem class="q-my-md"> + <QItemSection> + <VnSelect + :label="t('Order')" + v-model="orderWaySelected" + :options="orderWayList" + dense + outlined + rounded + @update:model-value="(value) => addOrder(value, 'way', params)" /> </QItemSection> </QItem> @@ -352,7 +328,7 @@ const useLang = (values) => { v-if="!selectedTag" :label="t('params.value')" v-model="value.value" - :options="tagValue || []" + :options="tagOptions || []" option-value="value" option-label="value" dense @@ -362,6 +338,8 @@ const useLang = (values) => { use-input class="filter-input" @new-value="createValue" + @filter="filterFn" + @update:model-value="applyTagFilter(params, searchFn)" /> <VnSelect v-else-if="selectedTag === 1" @@ -377,6 +355,7 @@ const useLang = (values) => { use-input class="filter-input" @new-value="createValue" + @update:model-value="applyTagFilter(params, searchFn)" /> <VnInput v-else @@ -386,6 +365,7 @@ const useLang = (values) => { outlined rounded class="filter-input" + @keyup.enter="applyTagFilter(params, searchFn)" /> <QIcon name="delete" @@ -400,7 +380,7 @@ const useLang = (values) => { @click="tagValues.push({})" /> </QItem> - <QItem> + <!-- <QItem> <QItemSection class="q-py-sm"> <QBtn :label="t('Search')" @@ -414,7 +394,7 @@ const useLang = (values) => { @click.stop="applyTagFilter(params, searchFn)" /> </QItemSection> - </QItem> + </QItem> --> <QSeparator /> </template> </VnFilterPanel> @@ -477,10 +457,10 @@ en: order: Order ASC: Ascendant DESC: Descendant - Relevancy: Relevancy - ColorAndPrice: Color and price - Name: Name - Price: Price + relevancy: Relevancy + colorAndPrice: Color and price + name: Name + price: Price es: params: type: Tipo @@ -490,10 +470,10 @@ es: order: Orden ASC: Ascendiente DESC: Descendiente - Relevancy: Relevancia - ColorAndPrice: Color y precio - Name: Nombre - Price: Precio + relevancy: Relevancia + colorAndPrice: Color y precio + name: Nombre + price: Precio Order: Orden Order by: Ordenar por Plant: Planta diff --git a/src/pages/Order/Card/OrderCatalogItemDialog.vue b/src/pages/Order/Card/OrderCatalogItemDialog.vue index 047816127..3f97443ca 100644 --- a/src/pages/Order/Card/OrderCatalogItemDialog.vue +++ b/src/pages/Order/Card/OrderCatalogItemDialog.vue @@ -5,10 +5,12 @@ import { useI18n } from 'vue-i18n'; import axios from 'axios'; import { useRoute } from 'vue-router'; import useNotify from 'composables/useNotify'; +import { useArrayData } from 'composables/useArrayData'; const { t } = useI18n(); -const route = useRoute(); const { notify } = useNotify(); +const emit = defineEmits(['added']); +const route = useRoute(); const props = defineProps({ prices: { type: Array, @@ -16,9 +18,8 @@ const props = defineProps({ }, }); -const emit = defineEmits(['added']); - const fields = ref((props.prices || []).map((item) => ({ ...item, quantity: 0 }))); +const descriptorData = useArrayData('orderData'); const addToOrder = async () => { const items = (fields.value || []).filter((item) => Number(item.quantity) > 0); @@ -28,19 +29,20 @@ const addToOrder = async () => { }); notify(t('globals.dataSaved'), 'positive'); emit('added'); + descriptorData.fetch({}); }; </script> <template> - <div class="container order-catalog-item q-pb-md"> + <div class="container order-catalog-item q-pa-md"> <QForm @submit="addToOrder"> <QMarkupTable class="shadow-0"> <tbody> <tr v-for="item in fields" :key="item.warehouse"> - <td class="text-bold q-py-lg"> + <td class="text-bold q-pr-md td" style="width: 35%"> {{ item.warehouse }} </td> - <td class="text-right"> + <td class="text-right" style="width: 35%"> <span class="link" @click=" @@ -75,8 +77,11 @@ const addToOrder = async () => { </template> <style lang="scss" scoped> -.container { - max-width: 448px; - width: 100%; +// .container { +// max-width: 768px; +// width: 100%; +// } +.td { + width: 200px; } </style> diff --git a/src/pages/Order/Card/OrderDescriptor.vue b/src/pages/Order/Card/OrderDescriptor.vue index 4d84a32fc..a035971b0 100644 --- a/src/pages/Order/Card/OrderDescriptor.vue +++ b/src/pages/Order/Card/OrderDescriptor.vue @@ -4,13 +4,13 @@ import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import { toCurrency, toDate } from 'src/filters'; import { useState } from 'src/composables/useState'; - import useCardDescription from 'src/composables/useCardDescription'; -import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; + import CardDescriptor from 'components/ui/CardDescriptor.vue'; import VnLv from 'src/components/ui/VnLv.vue'; -import OrderDescriptorMenu from 'pages/Order/Card/OrderDescriptorMenu.vue'; import FetchData from 'components/FetchData.vue'; +import OrderDescriptorMenu from 'pages/Order/Card/OrderDescriptorMenu.vue'; +import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; const DEFAULT_ITEMS = 0; @@ -25,6 +25,8 @@ const $props = defineProps({ const route = useRoute(); const state = useState(); const { t } = useI18n(); +const data = ref(useCardDescription()); +const getTotalRef = ref(); const entityId = computed(() => { return $props.id || route.params.id; @@ -57,11 +59,11 @@ const filter = { ], }; -const data = ref(useCardDescription()); const setData = (entity) => { if (!entity) return; + getTotalRef.value && getTotalRef.value.fetch(); data.value = useCardDescription(entity?.client?.name, entity?.id); - state.set('OrderDescriptor', entity); + state.set('orderData', entity); }; const getConfirmationValue = (isConfirmed) => { @@ -69,13 +71,17 @@ const getConfirmationValue = (isConfirmed) => { }; const total = ref(null); + +function ticketFilter(order) { + return JSON.stringify({ id: order.id }); +} </script> <template> <FetchData + ref="getTotalRef" :url="`Orders/${entityId}/getTotal`" @on-fetch="(response) => (total = response)" - auto-load /> <CardDescriptor ref="descriptor" @@ -120,7 +126,7 @@ const total = ref(null); color="primary" :to="{ name: 'TicketList', - query: { params: JSON.stringify({ orderFk: entity.id }) }, + query: { table: ticketFilter(entity) }, }" > <QTooltip>{{ t('order.summary.orderTicketList') }}</QTooltip> diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue index 347affb04..be47eed54 100644 --- a/src/pages/Order/Card/OrderFilter.vue +++ b/src/pages/Order/Card/OrderFilter.vue @@ -21,15 +21,13 @@ const salesPersonFilter = { fields: ['id', 'nickname'], }; const salesPersonList = ref(null); -const sourceFilter = { fields: ['value'] }; -const sourceList = ref(null); +const sourceList = ref([]); </script> <template> <FetchData url="AgencyModes/isActive" :filter="agencyFilter" - limit="30" sort-by="name ASC" auto-load @on-fetch="(data) => (agencyList = data)" @@ -37,7 +35,6 @@ const sourceList = ref(null); <FetchData url="Workers/search" :filter="salesPersonFilter" - limit="30" sort-by="nickname ASC" @on-fetch="(data) => (salesPersonList = data)" :params="{ departmentCodes: ['VT'] }" @@ -45,8 +42,7 @@ const sourceList = ref(null); /> <FetchData url="Orders/getSourceValues" - :filter="sourceFilter" - limit="30" + :filter="{ fields: ['value'] }" sort-by="value ASC" @on-fetch="(data) => (sourceList = data)" auto-load @@ -59,148 +55,88 @@ const sourceList = ref(null); </div> </template> <template #body="{ params }"> - <QItem> - <QItemSection> - <VnInput - is-outlined - :label="t('customerId')" - v-model="params.clientFk" - lazy-rules - > - <template #prepend> - <QIcon name="badge" size="sm"></QIcon> - </template> - </VnInput> - </QItemSection> - </QItem> - <QItem> - <QItemSection v-if="agencyList"> - <VnSelect - :label="t('agency')" - v-model="params.agencyModeFk" - :options="agencyList" - option-value="id" - option-label="name" - dense - outlined - rounded - emit-value - map-options - use-input - :input-debounce="0" - /> - </QItemSection> - <QItemSection v-else> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - </QItem> - <QItem> - <QItemSection v-if="salesPersonList"> - <VnSelect - :label="t('salesPerson')" - v-model="params.workerFk" - :options="salesPersonList" - option-value="id" - option-label="name" - dense - outlined - rounded - emit-value - map-options - use-input - :input-debounce="0" - > - <template #option="{ itemProps, opt }"> - <QItem v-bind="itemProps"> - <QItemSection> - <QItemLabel>{{ opt.name }}</QItemLabel> - <QItemLabel caption> - {{ opt.nickname }},{{ opt.code }} - </QItemLabel> - </QItemSection> - </QItem> - </template> - </VnSelect> - </QItemSection> - <QItemSection v-else> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnInputDate - v-model="params.from" - :label="t('fromLanded')" - dense - outlined - rounded - /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnInputDate - v-model="params.to" - :label="t('toLanded')" - dense - outlined - rounded - /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <VnInput - :label="t('orderId')" - v-model="params.orderFk" - lazy-rules - is-outlined - /> - </QItemSection> - </QItem> - <QItem> - <QItemSection v-if="sourceList"> - <VnSelect - :label="t('application')" - v-model="params.sourceApp" - :options="sourceList" - option-label="value" - emit-value - map-options - use-input - dense - outlined - rounded - :input-debounce="0" - /> - </QItemSection> - <QItemSection v-else> - <QSkeleton type="QInput" class="full-width" /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <QCheckbox - v-model="params.myTeam" - :label="t('myTeam')" - toggle-indeterminate - /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <QCheckbox - v-model="params.isConfirmed" - :label="t('isConfirmed')" - toggle-indeterminate - /> - </QItemSection> - </QItem> - <QItem> - <QItemSection> - <QCheckbox v-model="params.showEmpty" :label="t('showEmpty')" /> - </QItemSection> - </QItem> + <div class="q-px-md q-gutter-y-sm"> + <VnInput + :label="t('customerId')" + v-model="params.clientFk" + lazy-rules + dense + outlined + rounded + /> + <VnSelect + :label="t('agency')" + v-model="params.agencyModeFk" + :options="agencyList" + :input-debounce="0" + dense + outlined + rounded + /> + <VnSelect + :label="t('salesPerson')" + v-model="params.workerFk" + url="Workers/search" + :filter="{ departmentCodes: ['VT'] }" + sort-by="nickname ASC" + option-label="nickname" + dense + outlined + rounded + > + <template #option="{ itemProps, opt }"> + <QItem v-bind="itemProps"> + <QItemSection> + <QItemLabel>{{ opt.name }}</QItemLabel> + <QItemLabel caption> + {{ opt.nickname }},{{ opt.code }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + <VnInputDate + v-model="params.from" + :label="t('fromLanded')" + dense + outlined + rounded + /> + <VnInputDate + v-model="params.to" + :label="t('toLanded')" + dense + outlined + rounded + /> + <VnInput + :label="t('orderId')" + v-model="params.orderFk" + lazy-rules + is-outlined + /> + <VnSelect + :label="t('application')" + v-model="params.sourceApp" + :options="sourceList" + option-label="value" + dense + outlined + rounded + :input-debounce="0" + /> + <QCheckbox + v-model="params.myTeam" + :label="t('myTeam')" + toggle-indeterminate + /> + <QCheckbox + v-model="params.isConfirmed" + :label="t('isConfirmed')" + toggle-indeterminate + /> + <QCheckbox v-model="params.showEmpty" :label="t('showEmpty')" /> + </div> </template> </VnFilterPanel> </template> diff --git a/src/pages/Order/OrderLines.vue b/src/pages/Order/Card/OrderLines.vue similarity index 70% rename from src/pages/Order/OrderLines.vue rename to src/pages/Order/Card/OrderLines.vue index 21b4efb9d..dab4a959c 100644 --- a/src/pages/Order/OrderLines.vue +++ b/src/pages/Order/Card/OrderLines.vue @@ -1,23 +1,26 @@ <script setup> -import { useRoute } from 'vue-router'; +import { useRoute, useRouter } from 'vue-router'; import { useI18n } from 'vue-i18n'; -import { ref, computed } from 'vue'; +import { ref, computed, watch } from 'vue'; import { useQuasar } from 'quasar'; +import axios from 'axios'; +import { useStateStore } from 'stores/useStateStore'; +import { useArrayData } from 'composables/useArrayData'; +import { toCurrency, toDate } from 'src/filters'; import VnConfirm from 'components/ui/VnConfirm.vue'; -import { toCurrency, toDate } from 'src/filters'; -import axios from 'axios'; import VnTable from 'src/components/VnTable/VnTable.vue'; import FetchData from 'src/components/FetchData.vue'; import VnImg from 'src/components/ui/VnImg.vue'; import VnLv from 'src/components/ui/VnLv.vue'; import FetchedTags from 'src/components/ui/FetchedTags.vue'; -import { useStateStore } from 'stores/useStateStore'; +const router = useRouter(); const stateStore = useStateStore(); const route = useRoute(); const { t } = useI18n(); const quasar = useQuasar(); +const descriptorData = useArrayData('orderData'); const componentKey = ref(0); const tableLinesRef = ref(); const order = ref(); @@ -25,6 +28,8 @@ const orderSummary = ref({ total: null, vat: null, }); +const getTotalRef = ref(); +const getVATRef = ref(); const lineFilter = ref({ include: [ @@ -59,6 +64,13 @@ const lineFilter = ref({ fields: ['id', 'name'], }, }, + { + relation: 'order', + scope: { + fields: ['id', 'isConfirmed'], + where: { id: route.params.id }, + }, + }, ], where: { orderFk: route.params.id }, }); @@ -70,9 +82,9 @@ const columns = computed(() => [ name: 'image', columnField: { component: VnImg, - attrs: (id) => { + attrs: ({ row }) => { return { - id, + id: row.id, width: '50px', }; }, @@ -104,6 +116,7 @@ const columns = computed(() => [ component: null, }, format: (row) => row?.item?.name, + columnClass: 'expand', }, { align: 'left', @@ -147,7 +160,6 @@ const columns = computed(() => [ align: 'left', name: 'amount', label: t('lines.amount'), - format: (row) => toCurrency(row.amount), }, { align: 'right', @@ -155,8 +167,9 @@ const columns = computed(() => [ name: 'tableActions', actions: [ { - title: t('delete'), + title: t('Delete'), icon: 'delete', + show: (row) => !row.order.isConfirmed, action: (row) => confirmRemove(row), isPrimary: true, }, @@ -176,8 +189,6 @@ function confirmRemove(item) { } async function remove(item) { - console.log('item: ', item); - console.log('id: ', route.params.id); await axios.post('OrderRows/removes', { actualOrderId: route.params.id, rows: [item.id], @@ -187,6 +198,9 @@ async function remove(item) { type: 'positive', }); tableLinesRef.value.reload(); + descriptorData.fetch({}); + getTotalRef.value.fetch(); + getVATRef.value.fetch(); } async function confirmOrder() { @@ -195,7 +209,22 @@ async function confirmOrder() { message: t('globals.confirm'), type: 'positive', }); + router.push({ + name: 'TicketList', + query: { + table: JSON.stringify({ clientFk: descriptorData.store.data.clientFk }), + }, + }); } + +watch( + () => router.currentRoute.value.params.id, + () => { + lineFilter.value.where.orderFk = router.currentRoute.value.params.id; + + tableLinesRef.value.reload(); + } +); </script> <template> @@ -206,78 +235,80 @@ async function confirmOrder() { auto-load /> <FetchData + ref="getTotalRef" :key="componentKey" :url="`Orders/${route.params.id}/getTotal`" @on-fetch="(data) => (orderSummary.total = data)" auto-load /> <FetchData + ref="getVATRef" :key="componentKey" :url="`Orders/${route.params.id}/getVAT`" @on-fetch="(data) => (orderSummary.vat = data)" auto-load /> <QDrawer side="right" :width="270" v-model="stateStore.rightDrawer"> - <QCard class="order-lines-summary q-pa-lg"> + <QCard + class="order-lines-summary q-pa-lg" + v-if="orderSummary.vat && orderSummary.total" + > <p class="header text-right block"> {{ t('summary') }} </p> <VnLv - v-if="orderSummary.vat && orderSummary.total" :label="t('subtotal') + ': '" :value="toCurrency(orderSummary.total - orderSummary.vat)" /> - <VnLv - v-if="orderSummary.vat" - :label="t('VAT') + ': '" - :value="toCurrency(orderSummary?.vat)" - /> - <VnLv - v-if="orderSummary.total" - :label="t('total') + ': '" - :value="toCurrency(orderSummary?.total)" - /> + <VnLv :label="t('VAT') + ': '" :value="toCurrency(orderSummary?.vat)" /> + <VnLv :label="t('total') + ': '" :value="toCurrency(orderSummary?.total)" /> </QCard> </QDrawer> - <QPage :key="componentKey" class="column items-center"> - <div class="order-list full-width"> - <div v-if="!orderSummary.total" class="no-result"> - {{ t('globals.noResults') }} - </div> - <VnTable - ref="tableLinesRef" - data-key="OrderLines" - url="OrderRows" - :columns="columns" - :right-search="false" - :use-model="true" - auto-load - :user-filter="lineFilter" - > - <template #column-image="{ row }"> - <div class="image-wrapper"> - <VnImg :id="parseInt(row?.item?.image)" class="rounded" /> - </div> - </template> - <template #column-itemFk="{ row }"> - <div class="row column full-width justify-between items-start"> - {{ row?.item?.name }} - <div v-if="row?.item?.subName" class="subName"> - {{ row?.item?.subName.toUpperCase() }} - </div> - </div> - <FetchedTags :item="row?.item" :max-length="6" /> - </template> - </VnTable> - </div> - <QPageSticky :offset="[20, 20]" v-if="!order?.isConfirmed" style="z-index: 2"> - <QBtn fab icon="check" color="primary" @click="confirmOrder()" /> - <QTooltip> - {{ t('confirm') }} - </QTooltip> - </QPageSticky> - </QPage> + <VnTable + ref="tableLinesRef" + data-key="OrderLines" + url="OrderRows" + :columns="columns" + :right-search="false" + :use-model="true" + auto-load + :user-filter="lineFilter" + > + <template #column-image="{ row }"> + <div class="image-wrapper"> + <VnImg :id="parseInt(row?.item?.image)" class="rounded" /> + </div> + </template> + + <template #column-itemFk="{ row }"> + <div class="row column full-width justify-between items-start"> + {{ row?.item?.name }} + <div v-if="row?.item?.subName" class="subName"> + {{ row?.item?.subName.toUpperCase() }} + </div> + </div> + <FetchedTags :item="row?.item" :max-length="6" /> + </template> + <template #column-amount="{ row }"> + {{ toCurrency(row.quantity * row.price) }} + </template> + <template #column-tableActions="{ row }"> + <QIcon + v-if="row.order?.isConfirmed === 0" + name="delete" + icon="delete" + @click="confirmRemove(row)" + class="cursor-pointer" + /> + </template> + </VnTable> + <QPageSticky :offset="[20, 20]" v-if="!order?.isConfirmed" style="z-index: 2"> + <QBtn fab icon="check" color="primary" @click="confirmOrder()" /> + <QTooltip> + {{ t('confirm') }} + </QTooltip> + </QPageSticky> </template> <style lang="scss" scoped> diff --git a/src/pages/Order/Card/OrderSummary.vue b/src/pages/Order/Card/OrderSummary.vue index cb708fb1d..09c47d4a7 100644 --- a/src/pages/Order/Card/OrderSummary.vue +++ b/src/pages/Order/Card/OrderSummary.vue @@ -180,15 +180,17 @@ const detailsColumns = ref([ <ItemDescriptorProxy :id="props.row.item?.id" /> </span> </QTd> - <QTd key="description" :props="props" class="description"> - <div class="name"> - <span>{{ props.row.item.name }}</span> - <span - v-if="props.row.item.subName" - class="subName" - > - {{ props.row.item.subName }} - </span> + <QTd key="description" :props="props"> + <div class="description"> + <div class="name"> + {{ props.row.item.name }} + <span + v-if="props.row.item.subName" + class="subName" + > + {{ props.row.item.subName }} + </span> + </div> </div> <FetchedTags :item="props.row.item" :max-length="5" /> </QTd> @@ -228,24 +230,13 @@ const detailsColumns = ref([ } .description { - display: flex; - flex-direction: column; - justify-content: center; text-align: left; - height: auto; - padding-top: 12px; - padding-bottom: 12px; + padding-top: 15px; + padding-bottom: 15px; .name { - display: flex; - align-items: center; - padding-bottom: 8px; - - & > * { - flex: 1; - } - .subName { + margin-left: 5%; text-transform: uppercase; color: var(--vn-label-color); } diff --git a/src/pages/Order/Card/OrderVolume.vue b/src/pages/Order/Card/OrderVolume.vue new file mode 100644 index 000000000..b16022c2f --- /dev/null +++ b/src/pages/Order/Card/OrderVolume.vue @@ -0,0 +1,140 @@ +<script setup> +import axios from 'axios'; +import { useRoute } from 'vue-router'; +import { useI18n } from 'vue-i18n'; +import { ref } from 'vue'; +import { dashIfEmpty } from 'src/filters'; + +import FetchData from 'components/FetchData.vue'; +import FetchedTags from 'components/ui/FetchedTags.vue'; +import ItemDescriptorProxy from 'pages/Item/Card/ItemDescriptorProxy.vue'; +import VnLv from 'components/ui/VnLv.vue'; +import VnTable from 'components/VnTable/VnTable.vue'; + +const route = useRoute(); +const { t } = useI18n(); +const volumeSummary = ref(null); +const volumeRef = ref(); +const volumes = ref([]); +const volumeFilter = ref({ + include: [ + { + relation: 'item', + }, + ], + where: { orderFk: route.params.id }, +}); + +const columns = [ + { + name: 'itemFk', + label: t('item'), + align: 'left', + }, + { + name: 'description', + label: t('globals.description'), + align: 'left', + }, + { + name: 'quantity', + label: t('quantity'), + align: 'left', + }, + { + name: 'volume', + label: t('volume'), + align: 'left', + }, +]; + +const loadVolumes = async (rows) => { + if (!rows) return; + const { data } = await axios.get(`Orders/${route.params.id}/getVolumes`); + rows.forEach((order) => { + (data.volumes || []).forEach((volume) => { + if (order.itemFk === volume.itemFk) order.volume = volume.volume; + }); + }); + volumes.value = rows; +}; +</script> + +<template> + <FetchData + :url="`Orders/${route.params.id}/getTotalVolume`" + @on-fetch="(data) => (volumeSummary = data)" + auto-load + /> + <QCard v-if="volumeSummary" class="order-volume-summary q-pa-lg"> + <VnLv :label="t('total')" :value="`${volumeSummary?.totalVolume} m³`" /> + <VnLv + :label="t('boxes')" + :value="`${dashIfEmpty(volumeSummary?.totalBoxes)} U`" + /> + </QCard> + <VnTable + ref="volumeRef" + data-key="OrderCatalogVolume" + url="OrderRows" + :columns="columns" + auto-load + :user-filter="volumeFilter" + order="itemFk" + @on-fetch="(data) => loadVolumes(data)" + :right-search="false" + :column-search="false" + > + <template #column-itemFk="{ row }"> + <span class="link"> + {{ row.itemFk }} + <ItemDescriptorProxy :id="row.itemFk" /> + </span> + </template> + <template #column-description="{ row }"> + <FetchedTags :item="row.item" :max-length="5" /> + </template> + <template #column-volume="{ rowIndex }"> + {{ volumes?.[rowIndex]?.volume }} + </template> + </VnTable> +</template> + +<style lang="scss"> +.order-volume-summary { + .vn-label-value { + display: flex; + justify-content: flex-end; + gap: 2%; + + .label { + color: var(--vn-label-color); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .value { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } +} +</style> +<i18n> +en: + summary: Summary + total: Total + boxes: Boxes + item: Item + quantity: Quantity + volume: m³ per quantity +es: + summary: Resumen + total: Total + boxes: Cajas + item: Artículo + quantity: Cantidad + volume: m³ por cantidad +</i18n> diff --git a/src/pages/Order/OrderList.vue b/src/pages/Order/OrderList.vue index 68c4e57a7..9870be9b3 100644 --- a/src/pages/Order/OrderList.vue +++ b/src/pages/Order/OrderList.vue @@ -3,19 +3,21 @@ import axios from 'axios'; import { useI18n } from 'vue-i18n'; import { computed, ref } from 'vue'; import { dashIfEmpty, toCurrency, toDate } from 'src/filters'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; import OrderSummary from 'pages/Order/Card/OrderSummary.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import VnTable from 'src/components/VnTable/VnTable.vue'; import VnInputDate from 'src/components/common/VnInputDate.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; +import OrderSearchbar from './Card/OrderSearchbar.vue'; +import RightMenu from 'src/components/common/RightMenu.vue'; +import OrderFilter from './Card/OrderFilter.vue'; const { t } = useI18n(); const { viewSummary } = useSummaryDialog(); const tableRef = ref(); -const clientList = ref([]); const agencyList = ref([]); -const selectedAddress = ref(); +const addressesList = ref([]); +const clientId = ref(); const columns = computed(() => [ { @@ -29,7 +31,7 @@ const columns = computed(() => [ }, { align: 'left', - name: 'clientName', + name: 'clientFk', label: t('module.customer'), isTitle: true, cardVisible: true, @@ -41,20 +43,26 @@ const columns = computed(() => [ columnField: { component: null, }, + format: (row) => row?.clientName, }, { align: 'left', - name: 'name', + name: 'salesPersonFk', label: t('module.salesPerson'), - component: 'select', - attrs: { - url: 'Workers/activeWithInheritedRole', - fields: ['id', 'name'], - where: { role: 'salesPerson' }, - }, - columnField: { - component: null, + columnFilter: { + component: 'select', + inWhere: true, + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesPerson' }, + useLike: false, + optionValue: 'id', + optionLabel: 'name', + optionFilter: 'firstName', + }, }, + format: (row) => row?.name, }, { align: 'left', @@ -92,17 +100,21 @@ const columns = computed(() => [ }, { align: 'left', - name: 'agencyName', + name: 'agencyModeFk', label: t('module.agency'), - component: 'select', + format: (row) => row?.agencyName, + columnFilter: { + component: 'select', + attrs: { + url: 'agencyModes', + fields: ['id', 'name'], + find: { + value: 'agencyModeFk', + label: 'agencyName', + }, + }, + }, cardVisible: true, - attrs: { - url: 'Agencies', - fields: ['id', 'name'], - }, - columnField: { - component: null, - }, }, { align: 'left', @@ -125,23 +137,36 @@ const columns = computed(() => [ }, ]); -async function fetchClientAddress(id, data) { - console.log('data: ', data); - const clientData = await axios.get(`Clients/${id}`); - selectedAddress.value = clientData.data.defaultAddressFk; - data.addressId = selectedAddress.value; +async function fetchClientAddress(id, formData) { + const { data } = await axios.get(`Clients/${id}`, { + params: { filter: { include: { relation: 'addresses' } } }, + }); + addressesList.value = data.addresses; + formData.addressId = data.defaultAddressFk; + fetchAgencies(formData); +} + +async function fetchAgencies({ landed, addressId }) { + if (!landed || !addressId) return (agencyList.value = []); + + const { data } = await axios.get('Agencies/landsThatDay', { + params: { addressFk: addressId, landed }, + }); + agencyList.value = data; } </script> <template> - <VnSearchbar - data-key="OrderList" - :label="t('Search order')" - :info="t('You can search orders by reference')" - /> + <OrderSearchbar /> + <RightMenu> + <template #right-panel> + <OrderFilter data-key="OrderList" /> + </template> + </RightMenu> <VnTable ref="tableRef" data-key="OrderList" url="Orders/filter" + :order="['landed DESC', 'clientFk ASC', 'id DESC']" :create="{ urlCreate: 'Orders/new', title: 'Create Order', @@ -153,36 +178,49 @@ async function fetchClientAddress(id, data) { addressId: null, }, }" + :user-params="{ showEmpty: false }" + :right-search="false" :columns="columns" redirect="order" - auto-load > <template #more-create-dialog="{ data }"> <VnSelect url="Clients" - v-model="data.id" + :include="{ relation: 'addresses' }" + v-model="clientId" :label="t('module.customer')" - :options="clientList" - option-value="id" - option-label="name" @update:model-value="(id) => fetchClientAddress(id, data)" /> <VnSelect - url="Clients" - v-model="selectedAddress" + v-model="data.addressId" + :options="addressesList" :label="t('module.address')" - :options="selectedAddress" - option-value="defaultAddressFk" - option-label="street" + option-value="id" + option-label="nickname" + @update:model-value="() => fetchAgencies(data)" + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel> + {{ scope.opt?.nickname }}: {{ scope.opt?.street }}, + {{ scope.opt?.city }}</QItemLabel + > + </QItemSection> + </QItem> + </template> + </VnSelect> + <VnInputDate + v-model="data.landed" + :label="t('module.landed')" + @update:model-value="() => fetchAgencies(data)" /> - <VnInputDate v-model="data.landed" :label="t('module.landed')" /> <VnSelect - url="Agencies" v-model="data.agencyModeId" :label="t('module.agency')" :options="agencyList" - option-value="id" - option-label="name" + option-value="agencyModeFk" + option-label="agencyMode" /> </template> </VnTable> diff --git a/src/pages/Order/OrderMain.vue b/src/pages/Order/OrderMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/Order/OrderMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Order/OrderVolume.vue b/src/pages/Order/OrderVolume.vue deleted file mode 100644 index 35d68de16..000000000 --- a/src/pages/Order/OrderVolume.vue +++ /dev/null @@ -1,156 +0,0 @@ -<script setup> -import { useRoute } from 'vue-router'; -import { useI18n } from 'vue-i18n'; -import { ref } from 'vue'; - -import VnPaginate from 'components/ui/VnPaginate.vue'; -import FetchData from 'components/FetchData.vue'; -import VnLv from 'components/ui/VnLv.vue'; -import CardList from 'components/ui/CardList.vue'; -import FetchedTags from 'components/ui/FetchedTags.vue'; - -import { dashIfEmpty } from 'src/filters'; -import axios from 'axios'; - -const route = useRoute(); -const { t } = useI18n(); -const volumeSummary = ref(null); - -const loadVolumes = async (rows) => { - const { data } = await axios.get(`Orders/${route.params.id}/getVolumes`); - (rows || []).forEach((order) => { - (data.volumes || []).forEach((volume) => { - if (order.itemFk === volume.itemFk) { - order.volume = volume.volume; - } - }); - }); -}; -</script> - -<template> - <FetchData - :url="`Orders/${route.params.id}/getTotalVolume`" - @on-fetch="(data) => (volumeSummary = data)" - auto-load - /> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <div - v-if="!volumeSummary?.totalVolume && !volumeSummary?.totalBoxes" - class="no-result" - > - {{ t('globals.noResults') }} - </div> - <QCard v-else class="order-volume-summary q-pa-lg"> - <p class="header text-right block"> - {{ t('summary') }} - </p> - <VnLv :label="t('total')" :value="`${volumeSummary?.totalVolume} m³`" /> - <VnLv - :label="t('boxes')" - :value="`${dashIfEmpty(volumeSummary?.totalBoxes)} U`" - /> - </QCard> - <VnPaginate - data-key="OrderCatalogVolume" - url="OrderRows" - :limit="20" - auto-load - :filter="{ - include: { - relation: 'item', - }, - where: { orderFk: route.params.id }, - }" - order="itemFk" - @on-fetch="(data) => loadVolumes(data)" - > - <template #body="{ rows }"> - <div class="catalog-list q-mt-xl"> - <CardList - v-for="row in rows" - :key="row.id" - :id="row.id" - :title="row?.item?.name" - class="cursor-inherit" - > - <template #list-items> - <div class="q-mb-sm"> - <FetchedTags :item="row.item" :max-length="5" /> - </div> - <VnLv :label="t('item')" :value="row.item.id" /> - <VnLv :label="t('subName')"> - <template #value> - <span class="text-uppercase"> - {{ row.item.subName }} - </span> - </template> - </VnLv> - <VnLv :label="t('quantity')" :value="row.quantity" /> - <VnLv :label="t('volume')" :value="row.volume" /> - </template> - </CardList> - </div> - </template> - </VnPaginate> - </div> - </QPage> -</template> - -<style lang="scss"> -.order-volume-summary { - .vn-label-value { - display: flex; - justify-content: flex-end; - gap: 2%; - - .label { - color: var(--vn-label-color); - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - .value { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } -} -</style> -<style lang="scss" scoped> -.header { - color: $primary; - font-weight: bold; - margin-bottom: 25px; - font-size: 20px; - display: inline-block; -} - -.no-result { - font-size: 24px; - font-weight: bold; - color: var(--vn-label-color); - text-align: center; -} -</style> -<i18n> -en: - summary: Summary - total: Total - boxes: Boxes - item: Item - subName: Subname - quantity: Quantity - volume: m³ per quantity -es: - summary: Resumen - total: Total - boxes: Cajas - item: Artículo - subName: Subname - quantity: Cantidad - volume: m³ por cantidad -</i18n> diff --git a/src/pages/Parking/Card/ParkingCard.vue b/src/pages/Parking/Card/ParkingCard.vue index 620f4bb2d..ad37eb630 100644 --- a/src/pages/Parking/Card/ParkingCard.vue +++ b/src/pages/Parking/Card/ParkingCard.vue @@ -16,8 +16,10 @@ const filter = { :descriptor="ParkingDescriptor" :filter-panel="ParkingFilter" search-data-key="ParkingList" - search-url="Parkings" - searchbar-label="parking.searchBar.label" - searchbar-info="parking.searchBar.info" + :searchbar-props="{ + url: 'Parkings', + label: 'parking.searchBar.label', + info: 'parking.searchBar.info', + }" /> </template> diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue index e1eebabf7..9935fc6eb 100644 --- a/src/pages/Route/Agency/Card/AgencyCard.vue +++ b/src/pages/Route/Agency/Card/AgencyCard.vue @@ -8,8 +8,10 @@ import VnCard from 'components/common/VnCard.vue'; base-url="Agencies" :descriptor="AgencyDescriptor" search-data-key="AgencyList" - search-url="Agencies" - searchbar-label="agency.searchBar.label" - searchbar-info="agency.searchBar.info" + :searchbar-props="{ + url: 'Agencies', + label: 'agency.searchBar.label', + info: 'agency.searchBar.info', + }" /> </template> diff --git a/src/pages/Route/Agency/Card/AgencyWorkcenter.vue b/src/pages/Route/Agency/Card/AgencyWorkcenter.vue index f5beaab53..3531ad288 100644 --- a/src/pages/Route/Agency/Card/AgencyWorkcenter.vue +++ b/src/pages/Route/Agency/Card/AgencyWorkcenter.vue @@ -98,7 +98,7 @@ async function deleteWorCenter(id) { @on-data-saved="paginate.fetch()" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect v-model="data.workCenterFk" option-value="id" diff --git a/src/pages/Route/Card/RouteDescriptor.vue b/src/pages/Route/Card/RouteDescriptor.vue index 2fa0e77e0..cbabaf648 100644 --- a/src/pages/Route/Card/RouteDescriptor.vue +++ b/src/pages/Route/Card/RouteDescriptor.vue @@ -76,7 +76,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity :subtitle="data.subtitle" data-key="routeData" @on-fetch="setData" - :summary="$attrs" > <template #body="{ entity }"> <VnLv :label="t('Date')" :value="toDate(entity?.created)" /> diff --git a/src/pages/Route/Card/RouteDescriptorMenu.vue b/src/pages/Route/Card/RouteDescriptorMenu.vue index b661d1cd7..6092bcd95 100644 --- a/src/pages/Route/Card/RouteDescriptorMenu.vue +++ b/src/pages/Route/Card/RouteDescriptorMenu.vue @@ -3,6 +3,7 @@ import axios from 'axios'; import { useQuasar } from 'quasar'; import { useI18n } from 'vue-i18n'; import { useRouter } from 'vue-router'; +import { useSession } from 'src/composables/useSession'; import VnConfirm from 'components/ui/VnConfirm.vue'; const props = defineProps({ @@ -11,10 +12,20 @@ const props = defineProps({ required: true, }, }); - const router = useRouter(); const quasar = useQuasar(); const { t } = useI18n(); +const routeId = props.route.id; + +async function openRouteReport() { + const url = new URL(window.location).origin; + const { getTokenMultimedia } = useSession(); + const token = getTokenMultimedia(); + window.open( + `${url}/api/Routes/${routeId}/driver-route-pdf?access_token=${token}`, + '_blank' + ); +} function confirmRemove() { quasar @@ -29,20 +40,50 @@ function confirmRemove() { .onOk(async () => await router.push({ name: 'RouteList' })); } +async function sendMail() { + const params = { + id: routeId, + recipient: props?.route?.worker?.user?.emailUser?.email, + }; + await axios.post(`Routes/${routeId}/driver-route-email`, params); +} + +async function actualizeVolume() { + const params = { isOk: true }; + await axios.post(`Routes/${routeId}/updateVolume`, params); + quasar.notify({ + message: t('globals.dataUpdated'), + type: 'positive', + }); +} + async function remove() { - if (!props.route.id) { - return; - } - await axios.delete(`Routes/${props.route.id}`); + await axios.delete(`Routes/${routeId}`); quasar.notify({ message: t('globals.dataDeleted'), type: 'positive', }); } - -// TODO: Add reports </script> <template> + <QItem @click="openRouteReport" v-ripple clickable> + <QItemSection avatar> + <QIcon name="description" /> + </QItemSection> + <QItemSection>{{ t('seeReport') }}</QItemSection> + </QItem> + <QItem @click="sendMail" v-ripple clickable> + <QItemSection avatar> + <QIcon name="outgoing_mail" /> + </QItemSection> + <QItemSection>{{ t('sendMail') }}</QItemSection> + </QItem> + <QItem @click="actualizeVolume" v-ripple clickable> + <QItemSection avatar> + <QIcon name="package_2" /> + </QItemSection> + <QItemSection>{{ t('actualizeVolume') }}</QItemSection> + </QItem> <QItem @click="confirmRemove" v-ripple clickable> <QItemSection avatar> <QIcon name="delete" /> @@ -56,8 +97,14 @@ en: confirmDeletion: Confirm deletion confirmDeletionMessage: Are you sure you want to delete this route? deleteRoute: Delete route + seeReport: See route report + sendMail: Send route report + actualizeVolume: Actualize volume es: confirmDeletion: Confirmar eliminación, confirmDeletionMessage: Seguro que quieres eliminar esta ruta? deleteRoute: Eliminar ruta + seeReport: Ver informe de ruta + sendMail: Enviar informe de ruta + actualizeVolume: Actualizar volumen </i18n> diff --git a/src/pages/Route/Card/RouteFilter.vue b/src/pages/Route/Card/RouteFilter.vue index f0215370f..a6cd149f1 100644 --- a/src/pages/Route/Card/RouteFilter.vue +++ b/src/pages/Route/Card/RouteFilter.vue @@ -1,7 +1,5 @@ <script setup> -import { ref } from 'vue'; import { useI18n } from 'vue-i18n'; -import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'components/ui/VnFilterPanel.vue'; import VnSelect from 'components/common/VnSelect.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; @@ -16,39 +14,9 @@ const props = defineProps({ }); const emit = defineEmits(['search']); - -const workerList = ref([]); -const agencyList = ref([]); -const vehicleList = ref([]); -const warehouseList = ref([]); </script> <template> - <FetchData - url="Workers/search" - :filter="{ fields: ['id', 'nickname'] }" - sort-by="nickname ASC" - limit="30" - @on-fetch="(data) => (workerList = data)" - auto-load - /> - <FetchData - url="AgencyModes/isActive" - :filter="{ fields: ['id', 'name'] }" - sort-by="name ASC" - limit="30" - @on-fetch="(data) => (agencyList = data)" - auto-load - /> - <FetchData - url="Vehicles" - :filter="{ fields: ['id', 'numberPlate'] }" - sort-by="numberPlate ASC" - limit="30" - @on-fetch="(data) => (vehicleList = data)" - auto-load - /> - <FetchData url="Warehouses" @on-fetch="(data) => (warehouseList = data)" auto-load /> <VnFilterPanel :data-key="props.dataKey" :search-button="true" @@ -62,19 +30,17 @@ const warehouseList = ref([]); </template> <template #body="{ params }"> <QItem class="q-my-sm"> - <QItemSection v-if="workerList"> + <QItemSection> <VnSelect :label="t('Worker')" v-model="params.workerFk" - :options="workerList" + url="Workers/search" + sort-by="nickname ASC" option-value="id" option-label="nickname" dense outlined rounded - emit-value - map-options - use-input :input-debounce="0" > <template #option="{ itemProps, opt }"> @@ -91,19 +57,17 @@ const warehouseList = ref([]); </QItemSection> </QItem> <QItem class="q-my-sm"> - <QItemSection v-if="agencyList"> + <QItemSection> <VnSelect :label="t('Agency')" v-model="params.agencyModeFk" - :options="agencyList" + url="AgencyModes/isActive" + sort-by="name ASC" option-value="id" option-label="name" dense outlined rounded - emit-value - map-options - use-input :input-debounce="0" /> </QItemSection> @@ -147,19 +111,18 @@ const warehouseList = ref([]); </QItemSection> </QItem> <QItem class="q-my-sm"> - <QItemSection v-if="vehicleList"> + <QItemSection> <VnSelect :label="t('Vehicle')" v-model="params.vehicleFk" - :options="vehicleList" + url="Vehicles" + sort-by="numberPlate ASC" option-value="id" option-label="numberPlate" + option-filter-value="numberPlate" dense outlined rounded - emit-value - map-options - use-input :input-debounce="0" /> </QItemSection> @@ -170,19 +133,16 @@ const warehouseList = ref([]); </QItemSection> </QItem> <QItem class="q-my-sm"> - <QItemSection v-if="vehicleList"> + <QItemSection> <VnSelect :label="t('Warehouse')" v-model="params.warehouseFk" - :options="warehouseList" + url="Warehouses" option-value="id" option-label="name" dense outlined rounded - emit-value - map-options - use-input :input-debounce="0" /> </QItemSection> diff --git a/src/pages/Route/Card/RouteForm.vue b/src/pages/Route/Card/RouteForm.vue index a1bae8b02..8c89718fa 100644 --- a/src/pages/Route/Card/RouteForm.vue +++ b/src/pages/Route/Card/RouteForm.vue @@ -26,9 +26,6 @@ const defaultInitialData = { isOk: false, }; const maxDistance = ref(); -const workerList = ref([]); -const agencyList = ref([]); -const vehicleList = ref([]); const routeFilter = { fields: [ @@ -79,30 +76,6 @@ const onSave = (data, response) => { </script> <template> <VnSubToolbar v-if="isNew" /> - <FetchData - url="Workers/search" - :filter="{ fields: ['id', 'nickname'] }" - sort-by="nickname ASC" - limit="30" - @on-fetch="(data) => (workerList = data)" - auto-load - /> - <FetchData - url="AgencyModes/isActive" - :filter="{ fields: ['id', 'name'] }" - sort-by="name" - limit="30" - @on-fetch="(data) => (agencyList = data)" - auto-load - /> - <FetchData - url="Vehicles" - :filter="{ fields: ['id', 'numberPlate'] }" - sort-by="numberPlate ASC" - limit="30" - @on-fetch="(data) => (vehicleList = data)" - auto-load - /> <FetchData url="RouteConfigs/findOne" @on-fetch="({ kmMax }) => (maxDistance = kmMax)" @@ -120,16 +93,14 @@ const onSave = (data, response) => { @on-data-saved="onSave" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Worker')" v-model="data.workerFk" - :options="workerList" + url="Workers/search" + sort-by="nickname ASC" option-value="id" option-label="nickname" - emit-value - map-options - use-input :input-debounce="0" > <template #option="{ itemProps, opt }"> @@ -146,45 +117,36 @@ const onSave = (data, response) => { <VnSelect :label="t('Vehicle')" v-model="data.vehicleFk" - :options="vehicleList" + url="Vehicles" + sort-by="numberPlate ASC" option-value="id" option-label="numberPlate" - emit-value - map-options - use-input :input-debounce="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Agency')" v-model="data.agencyModeFk" - :options="agencyList" + url="AgencyModes/isActive" + sort-by="name" option-value="id" option-label="name" - emit-value - map-options - use-input :input-debounce="0" /> <VnInputDate v-model="data.created" :label="t('Created')" /> </VnRow> <template v-if="!isNew"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.kmStart" :label="t('Km Start')" clearable /> <QInput v-model.number="data.kmEnd" :label="t('Km End')" - :rules="[ - (val) => - val < maxDistance || - t('Distance must be lesser than 4000'), - ]" clearable type="number" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputTime v-model="data.started" :label="t('Hour started')" @@ -205,15 +167,13 @@ const onSave = (data, response) => { </div> </VnRow> </template> - <VnRow class="row q-gutter-md q-mb-md"> - <VnInput - v-model="data.description" - :label="t('Description')" - type="textarea" - :rows="3" - clearable - /> - </VnRow> + <VnInput + v-model="data.description" + :label="t('Description')" + type="textarea" + :rows="3" + clearable + /> </template> </FormModel> </template> @@ -229,5 +189,7 @@ es: Description: Descripción Is served: Se ha servido Created: Creado - Distance must be lesser than {maxDistance}: La distancia debe ser inferior a {maxDistance} + The km can not exceed: La distancia debe ser inferior a {maxDistance} +en: + The km can not exceed: Distance must be lesser than {maxDistance} </i18n> diff --git a/src/pages/Route/Card/RouteSearchbar.vue b/src/pages/Route/Card/RouteSearchbar.vue index 0e5c1643d..48ad09151 100644 --- a/src/pages/Route/Card/RouteSearchbar.vue +++ b/src/pages/Route/Card/RouteSearchbar.vue @@ -9,10 +9,9 @@ const { t } = useI18n(); data-key="RouteList" :label="t('Search route')" :info="t('You can search by route reference')" + url="Routes/filter" /> </template> - -<style scoped lang="scss"></style> <i18n> es: Search route: Buscar rutas diff --git a/src/pages/Route/Cmr/CmrList.vue b/src/pages/Route/Cmr/CmrList.vue index 6dfd3a1e5..ede271960 100644 --- a/src/pages/Route/Cmr/CmrList.vue +++ b/src/pages/Route/Cmr/CmrList.vue @@ -3,7 +3,7 @@ import { onBeforeMount, onMounted, computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import { Notify } from 'quasar'; import { useSession } from 'src/composables/useSession'; -import { toDate } from 'filters/index'; +import { toDateHourMin } from 'filters/index'; import { useStateStore } from 'src/stores/useStateStore'; import axios from 'axios'; @@ -30,56 +30,69 @@ const columns = computed(() => [ isId: true, }, { - align: 'left', + align: 'center', name: 'hasCmrDms', label: t('route.cmr.list.hasCmrDms'), component: 'checkbox', cardVisible: true, }, { + align: 'left', label: t('route.cmr.list.ticketFk'), name: 'ticketFk', }, { + align: 'left', label: t('route.cmr.list.routeFk'), name: 'routeFk', }, { + align: 'left', label: t('route.cmr.list.clientFk'), name: 'clientFk', }, { - align: 'left', + align: 'right', label: t('route.cmr.list.country'), - name: 'country', + name: 'countryFk', cardVisible: true, - }, - { - align: 'center', - label: t('route.cmr.list.shipped'), - name: 'shipped', - cardVisible: true, - component: 'date', - columnFilter: { - alias: 'c', - inWhere: true, - }, - format: ({ date }) => toDate(date), - }, - { - align: 'center', - name: 'warehouseFk', - label: t('globals.warehouse'), - component: 'select', attrs: { - url: 'warehouses', + url: 'countries', fields: ['id', 'name'], optionLabel: 'name', optionValue: 'id', }, + columnFilter: { + inWhere: true, + component: 'select', + }, + format: ({ countryName }) => countryName, }, { align: 'right', + label: t('route.cmr.list.shipped'), + name: 'shipped', + cardVisible: true, + columnFilter: { + component: 'date', + inWhere: true, + }, + format: ({ shipped }) => toDateHourMin(shipped), + }, + { + align: 'right', + name: 'warehouseFk', + label: t('globals.warehouse'), + columnFilter: { + component: 'select', + }, + attrs: { + options: warehouses.value, + }, + format: ({ warehouseName }) => warehouseName, + }, + { + align: 'center', name: 'tableActions', actions: [ { @@ -156,7 +169,7 @@ function downloadPdfs() { </template> <template #column-clientFk="{ row }"> <span class="link" @click.stop> - {{ row.ticketFk }} + {{ row.clientFk }} <CustomerDescriptorProxy :id="row.clientFk" /> </span> </template> diff --git a/src/pages/Route/Roadmap/RoadmapBasicData.vue b/src/pages/Route/Roadmap/RoadmapBasicData.vue index 19b6a1b3d..e1611ed61 100644 --- a/src/pages/Route/Roadmap/RoadmapBasicData.vue +++ b/src/pages/Route/Roadmap/RoadmapBasicData.vue @@ -38,12 +38,12 @@ const onSave = (data, response) => { @on-data-saved="onSave" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.name" :label="t('Roadmap')" clearable /> <VnInputDate v-model="data.etd" :label="t('ETD date')" /> <VnInputTime v-model="data.etd" :label="t('ETD hour')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.tractorPlate" :label="t('Tractor plate')" @@ -55,7 +55,7 @@ const onSave = (data, response) => { clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Carrier')" v-model="data.supplierFk" @@ -84,11 +84,11 @@ const onSave = (data, response) => { clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.driverName" :label="t('Driver name')" clearable /> <VnInput v-model="data.phone" :label="t('Phone')" clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.observations" :label="t('Observations')" diff --git a/src/pages/Route/Roadmap/RoadmapCard.vue b/src/pages/Route/Roadmap/RoadmapCard.vue index 4e8f8dd50..148d16ac9 100644 --- a/src/pages/Route/Roadmap/RoadmapCard.vue +++ b/src/pages/Route/Roadmap/RoadmapCard.vue @@ -10,8 +10,10 @@ import RoadmapFilter from 'pages/Route/Roadmap/RoadmapFilter.vue'; :descriptor="RoadmapDescriptor" :filter-panel="RoadmapFilter" search-data-key="RoadmapList" - search-url="Roadmaps" - searchbar-label="Search roadmap" - searchbar-info="You can search by roadmap id or customer name" + :searchbar-props="{ + url: 'Roadmaps', + label: 'Search roadmap', + info: 'You can search by roadmap id or customer name', + }" /> </template> diff --git a/src/pages/Route/RouteAutonomous.vue b/src/pages/Route/RouteAutonomous.vue index 83bc3b7c5..5ad349942 100644 --- a/src/pages/Route/RouteAutonomous.vue +++ b/src/pages/Route/RouteAutonomous.vue @@ -36,23 +36,20 @@ const tableRef = ref(); const columns = computed(() => [ { align: 'left', - name: 'id', + name: 'routeFk', label: 'Id', chip: { condition: () => true, }, isId: true, + columnFilter: false, }, { align: 'left', name: 'created', label: t('Date'), - component: 'date', - columnFilter: { - alias: 'c', - inWhere: true, - }, - format: ({ date }) => toDate(date), + columnFilter: false, + format: ({ created }) => toDate(created), }, { align: 'left', @@ -66,40 +63,63 @@ const columns = computed(() => [ label: t('Agency agreement'), cardVisible: true, }, + { + align: 'left', + name: 'to', + label: t('To'), + visible: false, + cardVisible: true, + create: true, + component: 'date', + format: ({ date }) => toDate(date), + }, + { + align: 'left', + name: 'from', + label: t('From'), + visible: false, + cardVisible: true, + create: true, + component: 'date', + format: ({ date }) => toDate(date), + }, { align: 'left', name: 'packages', label: t('Packages'), + columnFilter: false, }, { align: 'left', name: 'm3', label: 'm³', cardVisible: true, - columnFilter: { - inWhere: true, - }, + columnFilter: false, }, { align: 'left', name: 'kmTotal', label: t('Km'), cardVisible: true, + columnFilter: false, }, { align: 'left', name: 'price', label: t('Price'), + columnFilter: false, }, { align: 'left', name: 'invoiceInFk', label: t('Received'), + columnFilter: false, }, { align: 'left', name: 'supplierName', label: t('Autonomous'), + columnFilter: false, }, { align: 'right', @@ -194,7 +214,7 @@ onUnmounted(() => (stateStore.rightDrawer = false)); @click="openDmsUploadDialog" > <QTooltip> - {{ t('Create invoiceIn') }} + {{ t('globals.createInvoiceIn') }} </QTooltip> </QBtn> </QCard> @@ -247,7 +267,6 @@ onUnmounted(() => (stateStore.rightDrawer = false)); es: Search autonomous: Buscar autónomos You can search by autonomous reference: Puedes buscar por referencia del autónomo - Create invoiceIn: Crear factura recibida Two autonomous cannot be counted at the same time: Dos autonónomos no pueden ser contabilizados al mismo tiempo Date: Fecha Agency route: Agencia Ruta diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue index 55bcdabb0..e24ed33ed 100644 --- a/src/pages/Route/RouteList.vue +++ b/src/pages/Route/RouteList.vue @@ -11,6 +11,8 @@ import axios from 'axios'; import RouteSearchbar from 'pages/Route/Card/RouteSearchbar.vue'; import RouteListTicketsDialog from 'pages/Route/Card/RouteListTicketsDialog.vue'; import RouteSummary from 'pages/Route/Card/RouteSummary.vue'; +import RightMenu from 'src/components/common/RightMenu.vue'; +import RouteFilter from 'pages/Route/Card/RouteFilter.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; @@ -24,7 +26,6 @@ const selectedRows = ref([]); const tableRef = ref([]); const confirmationDialog = ref(false); const startingDate = ref(null); -const refreshKey = ref(0); const router = useRouter(); const routeFilter = { include: [ @@ -45,9 +46,7 @@ const columns = computed(() => [ condition: () => true, }, isId: true, - columnFilter: { - name: 'search', - }, + columnFilter: false, }, { align: 'left', @@ -57,9 +56,16 @@ const columns = computed(() => [ component: 'select', attrs: { url: 'Workers/activeWithInheritedRole', - fields: ['id', 'nickname'], - optionValue: 'id', - optionLabel: 'nickname', + fields: ['id', 'name'], + useLike: false, + optionFilter: 'firstName', + find: { + value: 'workerFk', + label: 'workerUserName', + }, + }, + columnFilter: { + inWhere: true, }, useLike: false, cardVisible: true, @@ -76,8 +82,10 @@ const columns = computed(() => [ attrs: { url: 'agencyModes', fields: ['id', 'name'], - optionLabel: 'name', - optionValue: 'id', + find: { + value: 'agencyModeFk', + label: 'agencyName', + }, }, }, { @@ -91,20 +99,44 @@ const columns = computed(() => [ url: 'vehicles', fields: ['id', 'numberPlate'], optionLabel: 'numberPlate', - optionValue: 'id', + optionFilterValue: 'numberPlate', + find: { + value: 'vehicleFk', + label: 'vehiclePlateNumber', + }, + }, + columnFilter: { + inWhere: true, }, }, { align: 'left', name: 'created', label: t('Date'), + columnFilter: false, + cardVisible: true, + create: true, + component: 'date', + format: ({ date }) => toDate(date), + }, + { + align: 'left', + name: 'from', + label: t('From'), + visible: false, + cardVisible: true, + create: true, + component: 'date', + format: ({ date }) => toDate(date), + }, + { + align: 'left', + name: 'to', + label: t('To'), + visible: false, cardVisible: true, create: true, component: 'date', - columnFilter: { - alias: 'c', - inWhere: true, - }, format: ({ date }) => toDate(date), }, { @@ -127,18 +159,21 @@ const columns = computed(() => [ name: 'started', label: t('hourStarted'), component: 'time', + columnFilter: false, }, { align: 'left', name: 'finished', label: t('hourFinished'), component: 'time', + columnFilter: false, }, { align: 'left', name: 'isOk', label: t('Served'), component: 'checkbox', + columnFilter: false, }, { align: 'right', @@ -174,8 +209,8 @@ const cloneRoutes = () => { created: startingDate.value, ids: selectedRows.value.map((row) => row?.id), }); - tableRef.value.reload(); startingDate.value = null; + tableRef.value.reload(); }; const showRouteReport = () => { @@ -211,7 +246,7 @@ const openTicketsDialog = (id) => { id, }, }) - .onOk(() => refreshKey.value++); + .onOk(() => tableRef.value.reload()); }; </script> @@ -239,15 +274,22 @@ const openTicketsDialog = (id) => { </QCard> </QDialog> <VnSubToolbar /> + <RightMenu> + <template #right-panel> + <RouteFilter data-key="RouteList" /> + </template> + </RightMenu> <VnTable + class="route-list" ref="tableRef" data-key="RouteList" url="Routes/filter" :columns="columns" - :right-search="true" + :right-search="false" :is-editable="true" :filter="routeFilter" redirect="route" + :row-click="false" :create="{ urlCreate: 'Routes', title: t('Create route'), @@ -256,7 +298,6 @@ const openTicketsDialog = (id) => { }" save-url="Routes/crud" :disable-option="{ card: true }" - :use-model="true" table-height="85vh" v-model:selected="selectedRows" :table="{ @@ -322,6 +363,8 @@ en: hourStarted: Started hour hourFinished: Finished hour es: + From: Desde + To: Hasta Worker: Trabajador Agency: Agencia Vehicle: Vehículo diff --git a/src/pages/Route/RouteMain.vue b/src/pages/Route/RouteMain.vue deleted file mode 100644 index aace646fb..000000000 --- a/src/pages/Route/RouteMain.vue +++ /dev/null @@ -1,19 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; -import { onMounted } from 'vue'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; -const stateStore = useStateStore(); -onMounted(() => (stateStore.leftDrawer = false)); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Route/RouteRoadmap.vue b/src/pages/Route/RouteRoadmap.vue index 050691af4..306387cbe 100644 --- a/src/pages/Route/RouteRoadmap.vue +++ b/src/pages/Route/RouteRoadmap.vue @@ -2,7 +2,7 @@ import { useI18n } from 'vue-i18n'; import { computed, ref } from 'vue'; import { dashIfEmpty } from 'src/filters'; -import { toDate } from 'filters/index'; +import { toDate, toDateHourMin } from 'filters/index'; import { useQuasar } from 'quasar'; import { useSummaryDialog } from 'composables/useSummaryDialog'; import toCurrency from 'filters/toCurrency'; @@ -43,10 +43,9 @@ const columns = computed(() => [ label: t('ETD'), component: 'date', columnFilter: { - alias: 'c', inWhere: true, }, - format: ({ date }) => toDate(date), + format: ({ created }) => toDate(created), cardVisible: true, }, { @@ -200,6 +199,12 @@ function confirmRemove() { }" :disable-option="{ card: true }" > + <template #column-etd="{ row }"> + {{ toDateHourMin(row.etd) }} + </template> + <template #column-supplierFk="{ row }"> + {{ row.supplierFk }} + </template> <template #more-create-dialog="{ data }"> <VnInputDate v-model="data.etd" /> <VnInputTime v-model="data.etd" /> diff --git a/src/pages/Route/RouteTickets.vue b/src/pages/Route/RouteTickets.vue index fc9087032..9356f7590 100644 --- a/src/pages/Route/RouteTickets.vue +++ b/src/pages/Route/RouteTickets.vue @@ -301,6 +301,7 @@ const openSmsDialog = async () => { data-key="RouteTicketList" url="Routes/getTickets" :filter="{ id: route.params.id }" + :limit="0" :order="['priority ASC']" auto-load @on-fetch="(data) => (ticketList = data)" diff --git a/src/pages/Shelving/Card/ShelvingDescriptor.vue b/src/pages/Shelving/Card/ShelvingDescriptor.vue index 52b4896ad..6beca6d88 100644 --- a/src/pages/Shelving/Card/ShelvingDescriptor.vue +++ b/src/pages/Shelving/Card/ShelvingDescriptor.vue @@ -51,7 +51,6 @@ const setData = (entity) => (data.value = useCardDescription(entity.code, entity :subtitle="data.subtitle" data-key="Shelvings" @on-fetch="setData" - :summary="$attrs" > <template #body="{ entity }"> <VnLv :label="t('shelving.summary.code')" :value="entity.code" /> diff --git a/src/pages/Shelving/Card/ShelvingForm.vue b/src/pages/Shelving/Card/ShelvingForm.vue index d9b6ede0d..dd1c4e4a2 100644 --- a/src/pages/Shelving/Card/ShelvingForm.vue +++ b/src/pages/Shelving/Card/ShelvingForm.vue @@ -85,7 +85,7 @@ const onSave = (shelving, newShelving) => { @on-data-saved="onSave" > <template #form="{ data, validate, filter }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.code" :label="t('shelving.basicData.code')" @@ -107,7 +107,7 @@ const onSave = (shelving, newShelving) => { :input-debounce="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.priority" type="number" diff --git a/src/pages/Shelving/ShelvingMain.vue b/src/pages/Shelving/ShelvingMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/Shelving/ShelvingMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Supplier/Card/SupplierAddressesCreate.vue b/src/pages/Supplier/Card/SupplierAddressesCreate.vue index eccf06204..da6549a24 100644 --- a/src/pages/Supplier/Card/SupplierAddressesCreate.vue +++ b/src/pages/Supplier/Card/SupplierAddressesCreate.vue @@ -11,7 +11,6 @@ const { t } = useI18n(); const route = useRoute(); const router = useRouter(); -const postcodesOptions = ref([]); const viewAction = ref(); const updateAddressId = ref(null); const newAddressForm = reactive({ @@ -71,7 +70,7 @@ function handleLocation(data, location) { @on-data-saved="onDataSaved()" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.nickname" :label="t('supplier.addresses.name')" @@ -81,17 +80,16 @@ function handleLocation(data, location) { :label="t('supplier.addresses.street')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.location" @update:model-value="(location) => handleLocation(data, location)" > </VnLocation> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.phone" :label="t('supplier.addresses.phone')" diff --git a/src/pages/Supplier/Card/SupplierAgencyTermCreate.vue b/src/pages/Supplier/Card/SupplierAgencyTermCreate.vue index 5eb64233f..a87ea502b 100644 --- a/src/pages/Supplier/Card/SupplierAgencyTermCreate.vue +++ b/src/pages/Supplier/Card/SupplierAgencyTermCreate.vue @@ -45,7 +45,7 @@ const onDataSaved = () => { @on-data-saved="onDataSaved()" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('supplier.agencyTerms.agencyFk')" v-model="data.agencyFk" @@ -61,7 +61,7 @@ const onDataSaved = () => { type="number" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('supplier.agencyTerms.packagePrice')" v-model.number="data.packagePrice" @@ -78,7 +78,7 @@ const onDataSaved = () => { type="number" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('supplier.agencyTerms.routePrice')" v-model.number="data.routePrice" diff --git a/src/pages/Supplier/Card/SupplierBasicData.vue b/src/pages/Supplier/Card/SupplierBasicData.vue index 10d6f8f68..52964557d 100644 --- a/src/pages/Supplier/Card/SupplierBasicData.vue +++ b/src/pages/Supplier/Card/SupplierBasicData.vue @@ -2,8 +2,6 @@ import { ref } from 'vue'; import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; - -import FetchData from 'components/FetchData.vue'; import FormModel from 'components/FormModel.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnInput from 'src/components/common/VnInput.vue'; @@ -15,12 +13,6 @@ const { t } = useI18n(); const workersOptions = ref([]); </script> <template> - <FetchData - url="Workers/search" - :filter="{ fields: ['id', 'nickname'], order: 'nickname ASC', limit: 30 }" - @on-fetch="(data) => (workersOptions = data)" - auto-load - /> <FormModel :url="`Suppliers/${route.params.id}`" :url-update="`Suppliers/${route.params.id}`" @@ -29,7 +21,7 @@ const workersOptions = ref([]); :clear-store-on-unmount="false" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.nickname" :label="t('supplier.basicData.alias')" @@ -44,6 +36,8 @@ const workersOptions = ref([]); option-label="name" hide-selected map-options + url="Workers/search" + sort-by="nickname ASC" :rules="validate('supplier.workerFk')" > <template #append> @@ -65,7 +59,7 @@ const workersOptions = ref([]); </template> </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox v-model="data.isSerious" :label="t('supplier.basicData.isSerious')" @@ -79,7 +73,7 @@ const workersOptions = ref([]); :label="t('supplier.basicData.isPayMethodChecked')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('supplier.basicData.note')" type="textarea" diff --git a/src/pages/Supplier/Card/SupplierBillingData.vue b/src/pages/Supplier/Card/SupplierBillingData.vue index 62ca91a54..7200bbba6 100644 --- a/src/pages/Supplier/Card/SupplierBillingData.vue +++ b/src/pages/Supplier/Card/SupplierBillingData.vue @@ -36,7 +36,7 @@ const formatPayDems = (data) => { :clear-store-on-unmount="false" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('supplier.billingData.payMethodFk')" v-model="data.payMethodFk" @@ -56,7 +56,7 @@ const formatPayDems = (data) => { :rules="validate('supplier.payDemFk')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QInput :label="t('supplier.billingData.payDay')" type="number" diff --git a/src/pages/Supplier/Card/SupplierCard.vue b/src/pages/Supplier/Card/SupplierCard.vue index adf0315da..594026d18 100644 --- a/src/pages/Supplier/Card/SupplierCard.vue +++ b/src/pages/Supplier/Card/SupplierCard.vue @@ -10,7 +10,10 @@ import SupplierListFilter from '../SupplierListFilter.vue'; :descriptor="SupplierDescriptor" :filter-panel="SupplierListFilter" search-data-key="SupplierList" - search-url="Suppliers/filter" - searchbar-label="Search suppliers" + :searchbar-props="{ + url: 'Suppliers/filter', + searchUrl: 'table', + label: 'Search suppliers', + }" /> </template> diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue index a31a3bc8d..6e60a336c 100644 --- a/src/pages/Supplier/Card/SupplierDescriptor.vue +++ b/src/pages/Supplier/Card/SupplierDescriptor.vue @@ -177,7 +177,7 @@ const getEntryQueryParams = (supplier) => { icon="vn:invoice-in-create" color="primary" > - <QTooltip>{{ t('Create invoiceIn') }}</QTooltip> + <QTooltip>{{ t('globals.createInvoiceIn') }}</QTooltip> </QBtn> </QCardActions> </template> @@ -188,7 +188,6 @@ const getEntryQueryParams = (supplier) => { es: All entries with current supplier: Todas las entradas con proveedor actual Go to client: Ir a cliente - Create invoiceIn: Crear factura recibida Go to module index: Ir al índice del módulo Inactive supplier: Proveedor inactivo Unverified supplier: Proveedor no verificado diff --git a/src/pages/Supplier/Card/SupplierFiscalData.vue b/src/pages/Supplier/Card/SupplierFiscalData.vue index 179c6f5e6..fd9667112 100644 --- a/src/pages/Supplier/Card/SupplierFiscalData.vue +++ b/src/pages/Supplier/Card/SupplierFiscalData.vue @@ -17,7 +17,6 @@ const sageTaxTypesOptions = ref([]); const sageWithholdingsOptions = ref([]); const sageTransactionTypesOptions = ref([]); const supplierActivitiesOptions = ref([]); -const postcodesOptions = ref([]); function handleLocation(data, location) { const { town, code, provinceFk, countryFk } = location ?? {}; @@ -56,7 +55,7 @@ function handleLocation(data, location) { :clear-store-on-unmount="false" > <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.name" :label="t('supplier.fiscalData.name')" @@ -68,7 +67,7 @@ function handleLocation(data, location) { clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.account" :label="t('supplier.fiscalData.account')" @@ -84,7 +83,7 @@ function handleLocation(data, location) { map-options /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('supplier.fiscalData.sageWithholdingFk')" v-model="data.sageWithholdingFk" @@ -104,7 +103,7 @@ function handleLocation(data, location) { map-options /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('supplier.fiscalData.supplierActivityFk')" v-model="data.supplierActivityFk" @@ -120,24 +119,23 @@ function handleLocation(data, location) { clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.street" :label="t('supplier.fiscalData.street')" clearable /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.postCode" @update:model-value="(location) => handleLocation(data, location)" > </VnLocation> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col flex justify-around"> <QCheckbox v-model="data.isTrucker" diff --git a/src/pages/Supplier/Card/SupplierSummary.vue b/src/pages/Supplier/Card/SupplierSummary.vue index 43b8964ff..822586b47 100644 --- a/src/pages/Supplier/Card/SupplierSummary.vue +++ b/src/pages/Supplier/Card/SupplierSummary.vue @@ -152,7 +152,7 @@ function getUrl(section) { /> <VnLv :label="t('supplier.summary.country')" - :value="supplier.country?.country" + :value="supplier.country?.name" dash /> </QCard> diff --git a/src/pages/Supplier/SupplierCreate.vue b/src/pages/Supplier/SupplierCreate.vue index 7d45bac97..9024f4804 100644 --- a/src/pages/Supplier/SupplierCreate.vue +++ b/src/pages/Supplier/SupplierCreate.vue @@ -44,13 +44,11 @@ const redirectToSupplierFiscalData = (_, responseData) => { @on-data-saved="redirectToSupplierFiscalData" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.name" :label="t('supplier.create.supplierName')" - @keyup=" - newSupplierForm.name = newSupplierForm.name.toUpperCase() - " + @keyup="newSupplierForm.name = newSupplierForm.name.toUpperCase()" /> </VnRow> </template> diff --git a/src/pages/Supplier/SupplierList.vue b/src/pages/Supplier/SupplierList.vue index 763fab812..d8404632c 100644 --- a/src/pages/Supplier/SupplierList.vue +++ b/src/pages/Supplier/SupplierList.vue @@ -3,8 +3,6 @@ import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; import VnTable from 'components/VnTable/VnTable.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue'; -import RightMenu from 'components/common/RightMenu.vue'; -import SupplierListFilter from './SupplierListFilter.vue'; const { t } = useI18n(); const tableRef = ref(); @@ -21,94 +19,92 @@ const columns = computed(() => [ label: t('supplier.list.tableVisibleColumns.name'), name: 'socialName', create: true, - component: 'input', - columnField: { - component: null, + columnFilter: { + name: 'search', }, }, { align: 'left', label: t('supplier.list.tableVisibleColumns.nif'), name: 'nif', - component: 'input', - columnField: { - component: null, + columnFilter: { + inWhere: true, }, }, { align: 'left', label: t('supplier.list.tableVisibleColumns.nickname'), name: 'alias', - component: 'input', - columnField: { - component: null, + columnFilter: { + name: 'search', }, }, { align: 'left', label: t('supplier.list.tableVisibleColumns.account'), name: 'account', - component: 'input', - columnField: { - component: null, + columnFilter: { + inWhere: true, }, }, { align: 'left', label: t('supplier.list.tableVisibleColumns.payMethod'), name: 'payMethod', - component: 'select', - attrs: { - url: 'payMethods', - fields: ['id', 'name'], - }, - columnField: { - component: null, + columnFilter: { + inWhere: true, + name: 'payMethodFk', + component: 'select', + attrs: { + url: 'payMethods', + fields: ['id', 'name'], + find: { + value: 'payMethodFk', + label: 'name', + }, + }, }, + visible: false, }, { align: 'left', label: t('supplier.list.tableVisibleColumns.payDay'), - name: 'payDat', - component: 'input', - columnField: { - component: null, + name: 'payDay', + columnFilter: { + inWhere: true, }, + visible: false, }, ]); </script> <template> <VnSearchbar data-key="SuppliersList" :limit="20" :label="t('Search suppliers')" /> - <RightMenu> - <template #right-panel> - <SupplierListFilter data-key="SuppliersList" /> - </template> - </RightMenu> <VnTable ref="tableRef" data-key="SuppliersList" url="Suppliers/filter" - save-url="Suppliers/crud" redirect="supplier" :create="{ urlCreate: 'Suppliers/newSupplier', title: t('Create Supplier'), onDataSaved: ({ id }) => tableRef.redirect(id), formInitialData: {}, + mapper: (data) => { + data.name = data.socialName; + delete data.socialName; + return data; + }, }" order="id ASC" :columns="columns" auto-load - :right-search="false" - :use-model="true" /> </template> <i18n> en: Search suppliers: Search suppliers - es: Search suppliers: Buscar proveedores </i18n> diff --git a/src/pages/Supplier/SupplierMain.vue b/src/pages/Supplier/SupplierMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/Supplier/SupplierMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue index c8a8e85c9..2d937346a 100644 --- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue +++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue @@ -311,7 +311,7 @@ onMounted(() => onFormModelInit()); auto-load /> <QForm> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('basicData.client')" v-model="clientId" @@ -343,7 +343,7 @@ onMounted(() => onFormModelInit()); :required="true" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('basicData.address')" v-model="addressId" @@ -447,7 +447,7 @@ onMounted(() => onFormModelInit()); </template> </VnSelect> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate :label="t('basicData.shipped')" v-model="formData.shipped" diff --git a/src/pages/Ticket/Card/ExpeditionNewTicket.vue b/src/pages/Ticket/Card/ExpeditionNewTicket.vue index da775a368..55ca700bc 100644 --- a/src/pages/Ticket/Card/ExpeditionNewTicket.vue +++ b/src/pages/Ticket/Card/ExpeditionNewTicket.vue @@ -63,10 +63,10 @@ const createTicket = async () => { :save-fn="createTicket" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate :label="t('expedition.landed')" v-model="data.landed" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-if="withRoute" :label="t('expedition.routeId')" diff --git a/src/pages/Ticket/Card/TicketBoxing.vue b/src/pages/Ticket/Card/TicketBoxing.vue index 05bde8977..bff95c0e2 100644 --- a/src/pages/Ticket/Card/TicketBoxing.vue +++ b/src/pages/Ticket/Card/TicketBoxing.vue @@ -105,14 +105,14 @@ async function getVideoList(expeditionId, timed) { label markers snap - color="orange" + color="primary" /> </QItemSection> </QItem> <QItem v-if="lastExpedition && videoList.length"> <QItemSection> <QSelect - color="orange" + color="primary" v-model="slide" :options="videoList" :label="t('ticket.boxing.selectVideo')" diff --git a/src/pages/Ticket/Card/TicketCard.vue b/src/pages/Ticket/Card/TicketCard.vue index 689a717e6..cf15cb7fa 100644 --- a/src/pages/Ticket/Card/TicketCard.vue +++ b/src/pages/Ticket/Card/TicketCard.vue @@ -11,20 +11,19 @@ const { t } = useI18n(); const route = useRoute(); const routeName = computed(() => route.name); -const searchBarDataKeys = { - TicketSummary: 'TicketSummary', - TicketSale: 'TicketSale', - TicketPurchaseRequest: 'TicketPurchaseRequest', -}; +const customRouteRedirectName = computed(() => routeName.value); </script> <template> <VnCard data-key="Ticket" + base-url="Tickets" :filter-panel="TicketFilter" :descriptor="TicketDescriptor" - :search-data-key="searchBarDataKeys[routeName]" - :search-custom-route-redirect="routeName" - :searchbar-label="t('card.search')" - :searchbar-info="t('card.searchInfo')" + search-data-key="TicketList" + :searchbar-props="{ + customRouteRedirectName, + label: t('card.search'), + info: t('card.searchInfo'), + }" /> </template> diff --git a/src/pages/Ticket/Card/TicketCreateRequest.vue b/src/pages/Ticket/Card/TicketCreateRequest.vue index 6b436621f..ffe009516 100644 --- a/src/pages/Ticket/Card/TicketCreateRequest.vue +++ b/src/pages/Ticket/Card/TicketCreateRequest.vue @@ -31,7 +31,7 @@ const attendersOptions = ref([]); @on-data-saved="() => emit('onRequestCreated')" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.description" :label="t('purchaseRequest.description')" @@ -45,7 +45,7 @@ const attendersOptions = ref([]); option-value="id" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.quantity" :label="t('purchaseRequest.quantity')" diff --git a/src/pages/Ticket/Card/TicketCreateServiceType.vue b/src/pages/Ticket/Card/TicketCreateServiceType.vue index d392ec206..067d7dee8 100644 --- a/src/pages/Ticket/Card/TicketCreateServiceType.vue +++ b/src/pages/Ticket/Card/TicketCreateServiceType.vue @@ -31,7 +31,7 @@ onMounted(async () => { @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput ref="nameInputRef" :label="t('service.description')" diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue index 399663571..87ca8dd3f 100644 --- a/src/pages/Ticket/Card/TicketCreateTracking.vue +++ b/src/pages/Ticket/Card/TicketCreateTracking.vue @@ -44,7 +44,7 @@ const onStateFkChange = (formData) => (formData.userFk = user.value.id); @on-data-saved="() => emit('onRequestCreated')" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect v-model="data.stateFk" :label="t('tracking.state')" diff --git a/src/pages/Ticket/Card/TicketDmsImportForm.vue b/src/pages/Ticket/Card/TicketDmsImportForm.vue index 869e166ca..4b6b9c6cd 100644 --- a/src/pages/Ticket/Card/TicketDmsImportForm.vue +++ b/src/pages/Ticket/Card/TicketDmsImportForm.vue @@ -54,7 +54,7 @@ const importDms = async () => { :save-fn="importDms" > <template #form-inputs> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('Document')" :options="dmsOptions" diff --git a/src/pages/Ticket/Card/TicketEditMana.vue b/src/pages/Ticket/Card/TicketEditMana.vue index 721057515..428e5e8c2 100644 --- a/src/pages/Ticket/Card/TicketEditMana.vue +++ b/src/pages/Ticket/Card/TicketEditMana.vue @@ -34,7 +34,7 @@ const cancel = () => { <template> <QPopupProxy ref="QPopupProxyRef"> <div class="container"> - <QSpinner v-if="!mana" color="orange" size="md" /> + <QSpinner v-if="!mana" color="primary" size="md" /> <div v-else> <div class="header">Mana: {{ toCurrency(mana) }}</div> <div class="q-pa-md"> diff --git a/src/pages/Ticket/Card/TicketExpedition.vue b/src/pages/Ticket/Card/TicketExpedition.vue index bddfa2bfd..a7eb9e27e 100644 --- a/src/pages/Ticket/Card/TicketExpedition.vue +++ b/src/pages/Ticket/Card/TicketExpedition.vue @@ -65,7 +65,7 @@ const ticketData = computed(() => ticketStore.data); const refetchExpeditions = async () => { await expeditionsArrayData.applyFilter({ - params: { filter: JSON.stringify(expeditionsFilter.value) }, + filter: expeditionsFilter.value, }); }; @@ -81,7 +81,7 @@ const applyColumnFilter = async (col) => { try { const paramKey = col.columnFilter?.filterParamKey || col.field; params[paramKey] = col.columnFilter.filterValue; - await expeditionsArrayData.addFilter({ params }); + await expeditionsArrayData.addFilter({ filter: expeditionsFilter.value, params }); } catch (err) { console.error('Error applying column filter', err); } diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue index cbc94b388..5978dbf09 100644 --- a/src/pages/Ticket/Card/TicketSale.vue +++ b/src/pages/Ticket/Card/TicketSale.vue @@ -11,7 +11,6 @@ import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; import TicketEditManaProxy from './TicketEditMana.vue'; import VnImg from 'src/components/ui/VnImg.vue'; -import RightMenu from 'src/components/common/RightMenu.vue'; import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import TicketSaleMoreActions from './TicketSaleMoreActions.vue'; import TicketTransfer from './TicketTransfer.vue'; diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue index 295e8bca5..177384663 100644 --- a/src/pages/Ticket/Card/TicketSummary.vue +++ b/src/pages/Ticket/Card/TicketSummary.vue @@ -181,7 +181,7 @@ async function changeState(value) { <span :class="{ link: ticket.refFk }"> {{ dashIfEmpty(ticket.refFk) }} <InvoiceOutDescriptorProxy - :id="ticket.id" + :id="ticket.invoiceOut.id" v-if="ticket.refFk" /> </span> @@ -391,7 +391,7 @@ async function changeState(value) { <QTd>{{ props.row.quantity }}</QTd> <QTd class="description-cell"> <div class="row full-width justify-between"> - {{ props.row.item.name }} + {{ props.row.concept }} <div v-if="props.row.item.subName" class="subName"> {{ props.row.item.subName.toUpperCase() }} </div> diff --git a/src/pages/Ticket/TicketAdvance.vue b/src/pages/Ticket/TicketAdvance.vue index bb9a8c8a8..bf4000fdf 100644 --- a/src/pages/Ticket/TicketAdvance.vue +++ b/src/pages/Ticket/TicketAdvance.vue @@ -626,7 +626,7 @@ onMounted(async () => { </template> <template #body-cell-ticketId="{ row }"> <QTd> - <QBtn flat color="primary"> + <QBtn flat class="link"> {{ row.id }} <TicketDescriptorProxy :id="row.id" /> </QBtn> @@ -658,7 +658,7 @@ onMounted(async () => { </template> <template #body-cell-futureId="{ row }"> <QTd class="vertical-separator"> - <QBtn flat color="primary" dense> + <QBtn flat class="link" dense> {{ row.futureId }} <TicketDescriptorProxy :id="row.futureId" /> </QBtn> diff --git a/src/pages/Ticket/TicketCreate.vue b/src/pages/Ticket/TicketCreate.vue index 79a68c8b5..034a299fc 100644 --- a/src/pages/Ticket/TicketCreate.vue +++ b/src/pages/Ticket/TicketCreate.vue @@ -158,7 +158,7 @@ const redirectToTicketList = (_, { id }) => { </VnSelect> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('ticket.create.address')" @@ -185,7 +185,7 @@ const redirectToTicketList = (_, { id }) => { </VnSelect> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnInputDate placeholder="dd-mm-aaa" @@ -196,7 +196,7 @@ const redirectToTicketList = (_, { id }) => { /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('ticket.create.warehouse')" @@ -209,7 +209,7 @@ const redirectToTicketList = (_, { id }) => { /> </div> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('ticket.create.agency')" diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue index 3570cfc03..3b9833ce2 100644 --- a/src/pages/Ticket/TicketFilter.vue +++ b/src/pages/Ticket/TicketFilter.vue @@ -15,11 +15,11 @@ const props = defineProps({ }, }); -const workers = ref(); -const provinces = ref(); -const states = ref(); -const agencies = ref(); -const warehouses = ref(); +const workers = ref([]); +const provinces = ref([]); +const states = ref([]); +const agencies = ref([]); +const warehouses = ref([]); </script> <template> @@ -33,7 +33,7 @@ const warehouses = ref(); @on-fetch="(data) => (workers = data)" auto-load /> - <VnFilterPanel :data-key="props.dataKey" :search-button="true"> + <VnFilterPanel :data-key="props.dataKey" :search-button="true" search-url="table"> <template #tags="{ tag, formatFn }"> <div class="q-gutter-x-xs"> <strong>{{ t(`params.${tag.label}`) }}: </strong> diff --git a/src/pages/Ticket/TicketFuture.vue b/src/pages/Ticket/TicketFuture.vue index 4db32de75..2fec6dc18 100644 --- a/src/pages/Ticket/TicketFuture.vue +++ b/src/pages/Ticket/TicketFuture.vue @@ -442,7 +442,7 @@ onMounted(async () => { </template> <template #body-cell-ticketId="{ row }"> <QTd> - <QBtn flat color="primary"> + <QBtn flat class="link"> {{ row.id }} <TicketDescriptorProxy :id="row.id" /> </QBtn> @@ -489,7 +489,7 @@ onMounted(async () => { </template> <template #body-cell-futureId="{ row }"> <QTd class="vertical-separator"> - <QBtn flat color="primary" dense> + <QBtn flat class="link" dense> {{ row.futureId }} <TicketDescriptorProxy :id="row.futureId" /> </QBtn> diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue index 6090bdbef..cbd102317 100644 --- a/src/pages/Ticket/TicketList.vue +++ b/src/pages/Ticket/TicketList.vue @@ -1,26 +1,27 @@ <script setup> -import { onMounted, onUnmounted } from 'vue'; -import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; +import axios from 'axios'; +import { computed, ref, onMounted } from 'vue'; import { useStateStore } from 'stores/useStateStore'; +import { useI18n } from 'vue-i18n'; import { toDate, toCurrency } from 'src/filters/index'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; import TicketSummary from './Card/TicketSummary.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; -import TicketFilter from './TicketFilter.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import CardList from 'src/components/ui/CardList.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; +import VnTable from 'src/components/VnTable/VnTable.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnInputDate from 'src/components/common/VnInputDate.vue'; +import VnRow from 'src/components/ui/VnRow.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; +import TicketFilter from './TicketFilter.vue'; -const router = useRouter(); const { t } = useI18n(); -const stateStore = useStateStore(); const { viewSummary } = useSummaryDialog(); - -onMounted(() => (stateStore.rightDrawer = true)); -onUnmounted(() => (stateStore.rightDrawer = false)); - +const tableRef = ref(); +const clientsOptions = ref([]); +const addressesOptions = ref([]); +const agenciesOptions = ref([]); +const selectedClient = ref(); +const stateStore = useStateStore(); const from = Date.vnNew(); const to = Date.vnNew(); to.setDate(to.getDate() + 1); @@ -30,89 +31,304 @@ const userParams = { to: to.toISOString(), }; -function navigate(id) { - router.push({ path: `/ticket/${id}` }); -} +const columns = computed(() => [ + { + align: 'left', + name: 'stateFk', + label: t('ticketList.state'), + columnFilter: { + name: 'stateFk', + component: 'select', + attrs: { + url: 'States', + fields: ['id', 'name'], + }, + }, + }, + { + align: 'left', + name: 'id', + label: t('ticketList.id'), + chip: { + condition: () => true, + }, + isId: true, + }, + { + align: 'left', + name: 'nickname', + label: t('ticketList.nickname'), + isTitle: true, + }, + + { + align: 'left', + name: 'shipped', + cardVisible: true, + label: t('ticketList.shipped'), + columnFilter: { + component: 'date', + alias: 't', + inWhere: true, + }, + format: ({ shipped }) => toDate(shipped), + }, + { + align: 'left', + name: 'zoneFk', + label: t('ticketList.zone'), + columnFilter: { + component: 'select', + attrs: { + url: 'Zones', + fields: ['id', 'name'], + }, + alias: 't', + inWhere: true, + }, + format: (row, dashIfEmpty) => dashIfEmpty(row.zoneName), + }, + { + align: 'left', + label: t('ticketList.salesPerson'), + name: 'salesPersonFk', + component: 'select', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesPerson' }, + optionFilter: 'firstName', + useLike: false, + }, + columnField: { + component: null, + }, + format: (row, dashIfEmpty) => dashIfEmpty(row.salesPerson), + }, + { + align: 'left', + name: 'totalWithVat', + label: t('ticketList.totalWithVat'), + cardVisible: true, + columnFilter: { + component: 'number', + inWhere: true, + }, + format: (row) => toCurrency(row.totalWithVat), + }, + { + align: 'right', + name: 'tableActions', + actions: [ + { + title: t('ticketList.summary'), + icon: 'preview', + action: (row) => viewSummary(row.id, TicketSummary), + }, + ], + }, +]); + +const onClientSelected = async (formData) => { + await fetchClient(formData); + await fetchAddresses(formData); +}; + +const fetchAvailableAgencies = async (formData) => { + if (!formData.warehouseId || !formData.addressId || !formData.landed) return; + let params = { + warehouseFk: formData.warehouseId, + addressFk: formData.addressId, + landed: formData.landed, + }; + + const { data } = await axios.get('Agencies/getAgenciesWithWarehouse', { params }); + + agenciesOptions.value = data; + + const defaultAgency = agenciesOptions.value.find( + (agency) => + agency.agencyModeFk === selectedClient.value.defaultAddress.agencyModeFk + ); + + if (defaultAgency) formData.agencyModeId = defaultAgency.agencyModeFk; +}; + +const fetchClient = async (formData) => { + try { + const filter = { + include: { + relation: 'defaultAddress', + scope: { + fields: ['id', 'agencyModeFk'], + }, + }, + where: { id: formData.clientId }, + }; + const params = { filter: JSON.stringify(filter) }; + const { data } = await axios.get('Clients', { params }); + const [client] = data; + selectedClient.value = client; + } catch (err) { + console.error('Error fetching client'); + } +}; + +const fetchAddresses = async (formData) => { + try { + if (!formData.clientId) return; + + const filter = { + fields: ['nickname', 'street', 'city', 'id'], + where: { isActive: true }, + order: 'nickname ASC', + }; + const params = { filter: JSON.stringify(filter) }; + const { data } = await axios.get(`Clients/${formData.clientId}/addresses`, { + params, + }); + addressesOptions.value = data; + + const { defaultAddress } = selectedClient.value; + formData.addressId = defaultAddress.id; + } catch (err) { + console.error(`Error fetching addresses`, err); + return err.response; + } +}; +const getColor = (row) => { + return row?.classColor ? `bg-${row.classColor}` : 'bg-orange'; +}; + +onMounted(() => (stateStore.rightDrawer = true)); </script> <template> <VnSearchbar - data-key="TicketList" + data-key="Tickets" :label="t('Search ticket')" :info="t('You can search by ticket id or alias')" /> <RightMenu> <template #right-panel> - <TicketFilter data-key="TicketList" /> + <TicketFilter data-key="Tickets" /> </template> </RightMenu> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - data-key="TicketList" - url="Tickets/filter" - :user-params="userParams" - order="id DESC" - auto-load - > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :key="row.id" - :id="row.id" - :title="`${row.nickname}`" - @click="navigate(row.id)" - > - <template #list-items> - <VnLv - :label="t('ticket.list.nickname')" - :value="row.nickname" - /> - <VnLv :label="t('ticket.list.state')"> - <template #value> - <QBadge - text-color="black" - :color="row.classColor ?? 'orange'" - class="q-ma-none" - dense - > - {{ row.state }} - </QBadge> - </template> - </VnLv> - <VnLv - :label="t('ticket.list.shipped')" - :value="toDate(row.shipped)" - /> - <VnLv :label="t('Zone')" :value="row.zoneName" /> - <VnLv - :label="t('ticket.list.salesPerson')" - :value="row.salesPerson" - /> - <VnLv - :label="t('ticket.list.total')" - :value="toCurrency(row.totalWithVat)" - /> - </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, TicketSummary)" - color="primary" - /> - </template> - </CardList> - </template> - </VnPaginate> - </div> - <QPageSticky :offset="[20, 20]"> - <QBtn :to="{ name: 'TicketCreate' }" fab icon="add" color="primary"> - <QTooltip> - {{ t('New ticket') }} - </QTooltip> - </QBtn> - </QPageSticky> - </QPage> + <VnTable + ref="tableRef" + data-key="Tickets" + url="Tickets/filter" + :create="{ + urlCreate: 'Tickets/new', + title: t('ticketList.createTicket'), + onDataSaved: ({ id }) => tableRef.redirect(id), + formInitialData: {}, + }" + default-mode="table" + order="id DESC" + :columns="columns" + :user-params="userParams" + :right-search="false" + redirect="ticket" + auto-load + > + <template #more-create-dialog="{ data }"> + <VnRow> + <VnSelect + url="Clients" + :label="t('ticketList.client')" + v-model="data.clientId" + :options="clientsOptions" + option-value="id" + option-label="name" + hide-selected + @update:model-value="(client) => onClientSelected(data)" + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel> + {{ scope.opt.name }} + </QItemLabel> + <QItemLabel caption> + {{ `#${scope.opt.id}` }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + </VnRow> + <VnRow> + <VnSelect + url="Addresses" + :label="t('ticket.create.address')" + v-model="data.addressId" + :options="addressesOptions" + option-value="id" + option-label="nickname" + hide-selected + :disable="!data.clientId" + @update:model-value="() => fetchAvailableAgencies(data)" + > + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel> + {{ scope.opt.nickname }} + </QItemLabel> + <QItemLabel caption> + {{ `${scope.opt.street}, ${scope.opt.city}` }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + </VnRow> + <VnRow> + <div class="col"> + <VnInputDate + placeholder="dd-mm-aaa" + :label="t('ticket.create.landed')" + v-model="data.landed" + @update:model-value="() => fetchAvailableAgencies(data)" + /> + </div> + </VnRow> + <VnRow> + <div class="col"> + <VnSelect + url="Warehouses" + :sort-by="['name']" + :label="t('ticket.create.warehouse')" + v-model="data.warehouseId" + :options="warehousesOptions" + option-value="id" + option-label="name" + hide-selected + @update:model-value="() => fetchAvailableAgencies(data)" + /> + </div> + </VnRow> + <VnRow> + <div class="col"> + <VnSelect + :label="t('ticket.create.agency')" + v-model="data.agencyModeId" + :options="agenciesOptions" + option-value="agencyModeFk" + option-label="agencyMode" + hide-selected + :disable="!data.clientId || !data.landed || !data.warehouseId" + /> + </div> + </VnRow> + </template> + <template #column-stateFk="{ row }"> + <QChip :class="getColor(row)" dense square> + {{ row.state }} + </QChip> + </template> + </VnTable> </template> <i18n> diff --git a/src/pages/Ticket/TicketWeekly.vue b/src/pages/Ticket/TicketWeekly.vue index 5dbc99d22..d68d18c24 100644 --- a/src/pages/Ticket/TicketWeekly.vue +++ b/src/pages/Ticket/TicketWeekly.vue @@ -1,40 +1,28 @@ <script setup> -import { onMounted, ref, computed, reactive, onUnmounted } from 'vue'; +import { onMounted, ref, computed, onUnmounted } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; - -import FetchData from 'components/FetchData.vue'; -import TableVisibleColumns from 'src/components/common/TableVisibleColumns.vue'; -import VnInput from 'src/components/common/VnInput.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; +import VnSelectCache from 'src/components/common/VnSelectCache.vue'; import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue'; import TicketDescriptorProxy from 'src/pages/Ticket/Card/TicketDescriptorProxy.vue'; import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue'; -import VnPaginate from 'components/ui/VnPaginate.vue'; -import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue'; import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; - import { useStateStore } from 'stores/useStateStore'; -import { dashIfEmpty } from 'src/filters'; import { useVnConfirm } from 'composables/useVnConfirm'; import { useArrayData } from 'composables/useArrayData'; import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; +import VnTable from 'src/components/VnTable/VnTable.vue'; -const router = useRouter(); const stateStore = useStateStore(); const { t } = useI18n(); -const { openConfirmationModal } = useVnConfirm(); const { notify } = useNotify(); - -const paginateRef = ref(null); -const agencyModesOptions = ref([]); -const visibleColumns = ref([]); +const { openConfirmationModal } = useVnConfirm(); const allColumnNames = ref([]); const arrayData = useArrayData('WeeklyTickets'); const { store } = arrayData; - +const tableRef = ref(); const weekdays = [ { id: 0, name: t('weekdays.mon') }, { id: 1, name: t('weekdays.tue') }, @@ -45,113 +33,132 @@ const weekdays = [ { id: 6, name: t('weekdays.sun') }, ]; -const exprBuilder = (param, value) => { - switch (param) { - case 'clientName': - return { 'c.name': value }; - case 'nickName': - return { 'u.name': value }; - } -}; - -const params = reactive({}); - -const applyColumnFilter = async (col) => { - try { - const paramKey = col.columnFilter?.filterParamKey || col.field; - params[paramKey] = col.columnFilter.filterValue; - await paginateRef.value.addFilter(null, params); - } catch (err) { - console.error('Error applying column filter', err); - } -}; - -const getInputEvents = (col) => ({ 'keyup.enter': () => applyColumnFilter(col) }); - const columns = computed(() => [ { + align: 'left', + name: 'ticketFk', label: t('weeklyTickets.id'), - name: 'id', - field: 'ticketFk', - align: 'left', - sortable: true, - columnFilter: null, + chip: { + condition: () => true, + }, + isId: true, + cardVisible: true, }, { + align: 'left', + name: 'clientFk', label: t('weeklyTickets.client'), - name: 'client', - field: 'clientName', - align: 'left', - sortable: true, - columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - attrs: { - dense: true, - }, + isTitle: true, + cardVisible: true, + component: 'select', + attrs: { + url: 'Clients', + optionLabel: 'name', + optionValue: 'id', + isWhere: true, }, - format: (val) => dashIfEmpty(val), + columnField: { + component: null, + }, + format: (row) => row.clientName, }, { + align: 'left', + name: 'weekDay', label: t('weeklyTickets.shipment'), - name: 'shipment', - field: 'weekDay', - align: 'left', - sortable: true, - columnFilter: null, - }, - { - label: t('weeklyTickets.agency'), - name: 'agency', - field: 'agencyModeFk', - align: 'left', - sortable: true, - columnFilter: null, - }, - { - label: t('weeklyTickets.warehouse'), - name: 'warehouse', - field: 'warehouseName', - align: 'left', - sortable: true, - columnFilter: null, - }, - { - label: t('weeklyTickets.salesperson'), - field: 'salesperson', - name: 'salesperson', - align: 'left', - sortable: true, + cardVisible: true, columnFilter: { - component: VnInput, - type: 'text', - filterValue: null, - event: getInputEvents, - filterParamKey: 'nickName', + component: 'select', attrs: { - dense: true, + options: weekdays, + optionLabel: weekdays.name, + optionValue: weekdays.id, }, + inWhere: true, }, }, { - label: '', - name: 'actions', align: 'left', - columnFilter: null, + label: t('weeklyTickets.agency'), + name: 'agencyModeFk', + cardVisible: true, + columnFilter: { + component: 'select', + alias: 'tw', + attrs: { + url: 'AgencyModes', + fields: ['id', 'name'], + }, + inWhere: true, + }, + }, + { + align: 'left', + name: 'warehouseFk', + label: t('weeklyTickets.warehouse'), + cardVisible: true, + columnFilter: { + component: 'select', + attrs: { + url: 'Warehouses', + fields: ['id', 'name'], + }, + inWhere: true, + }, + columnField: { + component: null, + }, + format: (row, dashIfEmpty) => dashIfEmpty(row.warehouseName), + }, + { + align: 'left', + name: 'id', + label: t('weeklyTickets.salesperson'), + columnFilter: { + component: 'select', + alias: 'u', + attrs: { + url: 'Workers/activeWithInheritedRole', + fields: ['id', 'name'], + where: { role: 'salesperson' }, + }, + inWhere: true, + }, + columnField: { + component: null, + }, + cardVisible: true, + format: (row) => row.userName, + }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('ticketWeekly.delete'), + icon: 'delete', + action: (row) => + openConfirmationModal( + t('You are going to delete this weekly ticket'), + t( + 'This ticket will be removed from weekly tickets! Continue anyway?' + ), + () => deleteWeekly(row.ticketFk) + ), + isPrimary: true, + }, + ], }, ]); -const redirectToTicketSummary = (ticketFk) => - router.push({ name: 'TicketSummary', params: { id: ticketFk } }); - const deleteWeekly = async (ticketFk) => { try { await axios.delete(`TicketWeeklies/${ticketFk}`); notify(t('globals.dataSaved'), 'positive'); const ticketIndex = store.data.findIndex((e) => e.ticketFk == ticketFk); store.data.splice(ticketIndex, 1); + location.reload(); } catch (err) { console.error('Error deleting weekly', err); } @@ -176,147 +183,59 @@ onUnmounted(() => (stateStore.rightDrawer = false)); </script> <template> - <FetchData - url="AgencyModes/isActive" - :filter="{ fields: ['id', 'name'], order: 'name' }" - auto-load - @on-fetch="(data) => (agencyModesOptions = data)" - /> <VnSearchbar data-key="WeeklyTickets" :label="t('weeklyTickets.search')" :info="t('weeklyTickets.searchInfo')" /> - <VnSubToolbar> - <template #st-data> - <TableVisibleColumns - :all-columns="allColumnNames" - table-code="itemsIndex" - labels-traductions-path="weeklyTickets" - @on-config-saved="visibleColumns = [...$event, 'actions']" + <VnTable + ref="tableRef" + data-key="WeeklyTickets" + url="TicketWeeklies/filter" + :columns="columns" + default-mode="table" + :use-model="true" + :disable-option="{ card: true }" + auto-load + > + <template #column-ticketFk="{ row }"> + <span class="link" @click.stop> + {{ row.ticketFk }} + <TicketDescriptorProxy :id="row.ticketFk" /> + </span> + </template> + <template #column-weekDay="{ row }"> + <VnSelect + :options="weekdays" + hide-selected + option-label="name" + option-value="id" + v-model="row.weekDay" + @update:model-value="onUpdate(row.ticketFk, 'weekDay', $event)" /> </template> - </VnSubToolbar> - <QPage class="column items-center q-pa-md"> - <VnPaginate - ref="paginateRef" - data-key="WeeklyTickets" - url="TicketWeeklies/filter" - :order="['weekDay', 'ticketFk']" - :limit="20" - :expr-builder="exprBuilder" - :user-params="params" - :offset="50" - auto-load - > - <template #body="{ rows }"> - <QTable - :rows="rows" - :columns="columns" - row-key="id" - :pagination="{ rowsPerPage: 0 }" - class="full-width q-mt-md" - :visible-columns="visibleColumns" - :no-data-label="t('globals.noResults')" - @row-click="(_, row) => redirectToTicketSummary(row.ticketFk)" - > - <template #top-row="{ cols }"> - <QTr> - <QTd - v-for="(col, index) in cols" - :key="index" - style="max-width: 100px" - > - <component - :is="col.columnFilter.component" - v-if="col.columnFilter" - v-model="col.columnFilter.filterValue" - v-bind="col.columnFilter.attrs" - v-on="col.columnFilter.event(col)" - dense - /> - </QTd> - </QTr> - </template> - <template #body-cell-id="{ row }"> - <QTd @click.stop> - <QBtn flat color="primary"> - {{ row.ticketFk }} - <TicketDescriptorProxy :id="row.ticketFk" /> - </QBtn> - </QTd> - </template> - <template #body-cell-salesperson="{ row }"> - <QTd @click.stop> - <QBtn flat color="primary"> - {{ row.userName }} - <WorkerDescriptorProxy :id="row.workerFk" /> - </QBtn> - </QTd> - </template> - <template #body-cell-client="{ row }"> - <QTd @click.stop> - <QBtn flat color="primary" dense> - {{ row.clientName }} - <CustomerDescriptorProxy :id="row.clientFk" /> - </QBtn> - </QTd> - </template> - <template #body-cell-shipment="{ row }"> - <QTd @click.stop> - <VnSelect - :options="weekdays" - hide-selected - option-label="name" - option-value="id" - v-model="row.weekDay" - @update:model-value=" - onUpdate(row.ticketFk, 'weekDay', $event) - " - /> - </QTd> - </template> - <template #body-cell-agency="{ row }"> - <QTd @click.stop> - <VnSelect - :options="agencyModesOptions" - hide-selected - option-label="name" - option-value="id" - v-model="row.agencyModeFk" - @update:model-value=" - onUpdate(row.ticketFk, 'agencyModeFk', $event) - " - /> - </QTd> - </template> - <template #body-cell-actions="{ row }"> - <QTd> - <QIcon - @click.stop=" - openConfirmationModal( - t('You are going to delete this weekly ticket'), - t( - 'This ticket will be removed from weekly tickets! Continue anyway?' - ), - () => deleteWeekly(row.ticketFk) - ) - " - class="q-ml-sm cursor-pointer" - color="primary" - name="delete" - size="sm" - > - <QTooltip> - {{ t('globals.delete') }} - </QTooltip> - </QIcon> - </QTd> - </template> - </QTable> - </template> - </VnPaginate> - </QPage> + <template #column-agencyModeFk="{ row }"> + <VnSelectCache + url="AgencyModes/isActive" + :row="row" + :find="['agencyModeFk', 'agencyModeName']" + v-model="row.agencyModeFk" + @update:model-value="onUpdate(row.ticketFk, 'agencyModeFk', $event)" + /> + </template> + <template #column-clientFk="{ row }"> + <span class="link" @click.stop> + {{ row.clientName }} + <CustomerDescriptorProxy :id="row.clientFk" /> + </span> + </template> + <template #column-id="{ row }"> + <span class="link" @click.stop> + {{ row.userName }} + <WorkerDescriptorProxy :id="row.workerFk" /> + </span> + </template> + </VnTable> </template> <i18n> diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml index d5530926f..10a8e1fa4 100644 --- a/src/pages/Ticket/locale/en.yml +++ b/src/pages/Ticket/locale/en.yml @@ -225,3 +225,14 @@ package: added: Added addPackage: Add package removePackage: Remove package +ticketList: + id: Id + nickname: Nickname + state: State + shipped: Shipped + zone: Zone + salesPerson: Sales person + totalWithVat: Total with VAT + summary: Summary + client: Customer + createTicket: Create ticket diff --git a/src/pages/Ticket/locale/es.yml b/src/pages/Ticket/locale/es.yml index 132c61928..a80692bfe 100644 --- a/src/pages/Ticket/locale/es.yml +++ b/src/pages/Ticket/locale/es.yml @@ -228,3 +228,14 @@ ticketSaleTracking: Search ticket: Buscar tickets You can search by ticket id or alias: Puedes buscar por id o alias del ticket Select lines to see the options: Selecciona líneas para ver las opciones +ticketList: + id: Id + nickname: Alias + state: Estado + shipped: F. Envío + zone: Zona + salesPerson: Comercial + totalWithVat: Total con IVA + summary: Resumen + client: Cliente + createTicket: Crear ticket diff --git a/src/pages/Travel/Card/TravelBasicData.vue b/src/pages/Travel/Card/TravelBasicData.vue index 1eb9bbc0f..8a369a0dd 100644 --- a/src/pages/Travel/Card/TravelBasicData.vue +++ b/src/pages/Travel/Card/TravelBasicData.vue @@ -28,7 +28,7 @@ const agenciesOptions = ref([]); auto-load > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.ref" :label="t('travel.basicData.reference')" /> <VnSelect :label="t('travel.basicData.agency')" @@ -40,7 +40,7 @@ const agenciesOptions = ref([]); hide-selected /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate v-model="data.shipped" :label="t('travel.basicData.shipped')" @@ -50,7 +50,7 @@ const agenciesOptions = ref([]); :label="t('travel.basicData.landed')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('travel.basicData.warehouseOut')" v-model="data.warehouseOutFk" @@ -70,7 +70,7 @@ const agenciesOptions = ref([]); hide-selected /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox :label="t('travel.basicData.delivered')" v-model="data.isDelivered" diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue index a3c1430e9..44bd9d430 100644 --- a/src/pages/Travel/Card/TravelCard.vue +++ b/src/pages/Travel/Card/TravelCard.vue @@ -35,10 +35,12 @@ const filter = { data-key="Travel" base-url="Travels" search-data-key="TravelList" - searchbar-label="Search travel" - searchbar-info="You can search by travel id or name" - search-url="Travels" :filter="filter" :descriptor="TravelDescriptor" + :searchbar-props="{ + url: 'Travels', + label: 'Search travel', + info: 'You can search by travel id or name', + }" /> </template> diff --git a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue index 1bb80ff01..bd2561211 100644 --- a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue +++ b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue @@ -38,7 +38,7 @@ const cloneTravelWithEntries = async () => { notify('globals.dataSaved', 'positive'); router.push({ name: 'TravelBasicData', params: { id: data.id } }); } catch (err) { - console.err('Error cloning travel with entries'); + console.error('Error cloning travel with entries'); } }; diff --git a/src/pages/Travel/Card/TravelThermographsForm.vue b/src/pages/Travel/Card/TravelThermographsForm.vue index 33b56e745..7f40873b1 100644 --- a/src/pages/Travel/Card/TravelThermographsForm.vue +++ b/src/pages/Travel/Card/TravelThermographsForm.vue @@ -235,7 +235,7 @@ const onThermographCreated = async (data) => { </div> </Teleport> <QCard class="q-pa-lg"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelectDialog :label="t('travel.thermographs.thermograph')" v-model="thermographForm.thermographId" @@ -256,7 +256,7 @@ const onThermographCreated = async (data) => { :label="t('travel.thermographs.state')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="thermographForm.reference" :label="t('travel.thermographs.reference')" @@ -269,7 +269,7 @@ const onThermographCreated = async (data) => { option-label="name" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('travel.thermographs.company')" v-model="thermographForm.companyId" @@ -293,7 +293,7 @@ const onThermographCreated = async (data) => { fill-input /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QFile ref="inputFileRef" :label="t('travel.thermographs.file')" diff --git a/src/pages/Travel/TravelCreate.vue b/src/pages/Travel/TravelCreate.vue index 09bf58765..6fb3274e4 100644 --- a/src/pages/Travel/TravelCreate.vue +++ b/src/pages/Travel/TravelCreate.vue @@ -57,7 +57,7 @@ const redirectToTravelBasicData = (_, { id }) => { @on-data-saved="redirectToTravelBasicData" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.ref" :label="t('globals.reference')" /> <VnSelect :label="t('globals.agency')" @@ -68,11 +68,11 @@ const redirectToTravelBasicData = (_, { id }) => { hide-selected /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputDate v-model="data.shipped" :label="t('globals.shipped')" /> <VnInputDate :label="t('globals.landed')" v-model="data.landed" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('globals.wareHouseOut')" v-model="data.warehouseOutFk" diff --git a/src/pages/Travel/TravelList.vue b/src/pages/Travel/TravelList.vue index dbb8949a7..8989e485c 100644 --- a/src/pages/Travel/TravelList.vue +++ b/src/pages/Travel/TravelList.vue @@ -9,7 +9,7 @@ import { useSummaryDialog } from 'src/composables/useSummaryDialog'; import { computed } from 'vue'; import TravelSummary from './Card/TravelSummary.vue'; import VnSearchbar from 'components/ui/VnSearchbar.vue'; -import { dashIfEmpty, toDate } from 'src/filters'; +import { toDate } from 'src/filters'; const { viewSummary } = useSummaryDialog(); const router = useRouter(); const { t } = useI18n(); diff --git a/src/pages/Travel/TravelMain.vue b/src/pages/Travel/TravelMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/Travel/TravelMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Wagon/WagonCounter.vue b/src/pages/Wagon/WagonCounter.vue index 70bbc9803..505cbba28 100644 --- a/src/pages/Wagon/WagonCounter.vue +++ b/src/pages/Wagon/WagonCounter.vue @@ -64,7 +64,12 @@ function confirm() { <QList class="row q-mx-auto q-mt-xl"> <QItem v-for="(props, name) in counters" :key="name" class="col-6"> <QItemSection> - <VnImg :id="props.id" width="130px" @click="handleEvent(name, 'add')" /> + <VnImg + :id="props.id" + width="130px" + @click="handleEvent(name, 'add')" + :zoom="false" + /> <p class="title">{{ props.title }}</p> </QItemSection> <QItemSection class="q-ma-none"> diff --git a/src/pages/Wagon/WagonMain.vue b/src/pages/Wagon/WagonMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/Wagon/WagonMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Worker/Card/WorkerBasicData.vue b/src/pages/Worker/Card/WorkerBasicData.vue index 62ca9dad9..d131fea3e 100644 --- a/src/pages/Worker/Card/WorkerBasicData.vue +++ b/src/pages/Worker/Card/WorkerBasicData.vue @@ -12,9 +12,12 @@ import VnSelect from 'src/components/common/VnSelect.vue'; const route = useRoute(); const { t } = useI18n(); -const workersOptions = ref([]); -const countriesOptions = ref([]); -const educationLevelsOptions = ref([]); +const educationLevels = ref([]); +const countries = ref([]); +const maritalStatus = [ + { code: 'M', name: t('Married') }, + { code: 'S', name: t('Single') }, +]; const workerFilter = { include: [ @@ -29,44 +32,21 @@ const workerFilter = { { relation: 'department', scope: { include: { relation: 'department' } } }, ], }; -const workersFilter = { - fields: ['id', 'nickname'], - order: 'nickname ASC', - limit: 30, -}; -const countriesFilter = { - fields: ['id', 'name', 'code'], - order: 'name ASC', - limit: 30, -}; -const educationLevelsFilter = { fields: ['id', 'name'], order: 'name ASC', limit: 30 }; - -const maritalStatus = [ - { code: 'M', name: t('Married') }, - { code: 'S', name: t('Single') }, -]; </script> <template> <FetchData - :filter="workersFilter" - @on-fetch="(data) => (workersOptions = data)" - auto-load - url="Workers/search" - /> - <FetchData - :filter="countriesFilter" - @on-fetch="(data) => (countriesOptions = data)" - auto-load - url="Countries" - /> - <FetchData - :filter="educationLevelsFilter" - @on-fetch="(data) => (educationLevelsOptions = data)" + :filter="{ fields: ['id', 'name'], order: 'name ASC' }" + @on-fetch="(data) => (educationLevels = data)" auto-load url="EducationLevels" /> - + <FetchData + url="Countries" + :filter="{ fields: ['id', 'name'], order: 'name ASC' }" + @on-fetch="(data) => (countries = data)" + auto-load + /> <FormModel :filter="workerFilter" :url="`Workers/${route.params.id}`" @@ -90,7 +70,7 @@ const maritalStatus = [ <VnRow> <VnSelect :label="t('Boss')" - :options="workersOptions" + url="Workers/search" hide-selected option-label="nickname" option-value="id" @@ -121,7 +101,7 @@ const maritalStatus = [ <VnRow> <VnSelect :label="t('Origin country')" - :options="countriesOptions" + :options="countries" hide-selected option-label="name" option-value="id" @@ -129,7 +109,7 @@ const maritalStatus = [ /> <VnSelect :label="t('Education level')" - :options="educationLevelsOptions" + :options="educationLevels" hide-selected option-label="name" option-value="id" @@ -139,23 +119,19 @@ const maritalStatus = [ <VnRow> <VnInput v-model="data.SSN" :label="t('SSN')" clearable /> - <VnInput - v-model="data.locker" - type="number" - :label="t('Locker')" - clearable - /> - </VnRow> - <VnRow> <VnInputDate :label="t('fiDueDate')" v-model="data.fiDueDate" /> - - <VnInput v-model="data.sex" :label="t('sex')" clearable /> </VnRow> <VnRow> + <VnSelect + :label="t('sex')" + :options="['M', 'F']" + hide-selected + v-model="data.sex" + /> <VnInputDate :label="t('seniority')" v-model="data.seniority" /> - <VnInput v-model="data.fi" :label="t('fi')" /> </VnRow> <VnRow> + <VnInput v-model="data.fi" :label="t('fi')" /> <VnInputDate :label="t('birth')" v-model="data.birth" /> </VnRow> <VnRow> diff --git a/src/pages/Worker/Card/WorkerCalendar.vue b/src/pages/Worker/Card/WorkerCalendar.vue index ea6e62683..e9cb793f4 100644 --- a/src/pages/Worker/Card/WorkerCalendar.vue +++ b/src/pages/Worker/Card/WorkerCalendar.vue @@ -171,18 +171,16 @@ watch([year, businessFk], () => refreshData()); ref="WorkerFreelanceRef" auto-load /> - <QDrawer v-model="stateStore.rightDrawer" side="right" :width="256" show-if-above> - <QScrollArea class="fit text-grey-8"> - <WorkerCalendarFilter - ref="workerCalendarFilterRef" - v-model:business-fk="businessFk" - v-model:year="year" - v-model:absence-type="absenceType" - :contract-holidays="contractHolidays" - :year-holidays="yearHolidays" - /> - </QScrollArea> - </QDrawer> + <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> + <WorkerCalendarFilter + ref="workerCalendarFilterRef" + v-model:business-fk="businessFk" + v-model:year="year" + v-model:absence-type="absenceType" + :contract-holidays="contractHolidays" + :year-holidays="yearHolidays" + /> + </Teleport> <QPage class="column items-center"> <QCard v-if="workerIsFreelance"> <QCardSection class="text-center"> diff --git a/src/pages/Worker/Card/WorkerCard.vue b/src/pages/Worker/Card/WorkerCard.vue index fb9ab9666..0abcdcafd 100644 --- a/src/pages/Worker/Card/WorkerCard.vue +++ b/src/pages/Worker/Card/WorkerCard.vue @@ -10,8 +10,10 @@ import WorkerFilter from '../WorkerFilter.vue'; :descriptor="WorkerDescriptor" :filter-panel="WorkerFilter" search-data-key="WorkerList" - search-url="Workers/filter" - searchbar-label="Search worker" - searchbar-info="You can search by worker id or name" + :searchbar-props="{ + url: 'Workers/filter', + label: 'Search worker', + info: 'You can search by worker id or name', + }" /> </template> diff --git a/src/pages/Worker/Card/WorkerChangePasswordForm.vue b/src/pages/Worker/Card/WorkerChangePasswordForm.vue index ef75ba55a..20132f21e 100644 --- a/src/pages/Worker/Card/WorkerChangePasswordForm.vue +++ b/src/pages/Worker/Card/WorkerChangePasswordForm.vue @@ -61,7 +61,7 @@ onMounted(async () => await getPassRequirements()); <template> <FormPopup :title="t('Reset password')" @on-submit="setPassword()"> <template #form-inputs> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('New password')" v-model="formData.newPassword" @@ -78,7 +78,7 @@ onMounted(async () => await getPassRequirements()); " /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Repeat password')" v-model="formData.repeatPassword" diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue index 951c8511e..8fbb23ef8 100644 --- a/src/pages/Worker/Card/WorkerDescriptor.vue +++ b/src/pages/Worker/Card/WorkerDescriptor.vue @@ -111,7 +111,6 @@ const refetch = async () => await cardDescriptorRef.value.getData(); :filter="filter" :title="data.title" :subtitle="data.subtitle" - :summary="$attrs" @on-fetch=" (data) => { worker = data; @@ -145,7 +144,12 @@ const refetch = async () => await cardDescriptorRef.value.getData(); </QItem> </template> <template #before> - <VnImg :id="entityId" collection="user" size="160x160" class="photo"> + <VnImg + :id="parseInt(entityId)" + collection="user" + resolution="520x520" + class="photo" + > <template #error> <div class="absolute-full picture text-center q-pa-md flex flex-center" @@ -182,6 +186,32 @@ const refetch = async () => await cardDescriptorRef.value.getData(); </template> </VnLv> </template> + <template #actions="{ entity }"> + <QCardActions class="flex justify-center"> + <QBtn + :to="{ + name: 'CustomerCard', + params: { id: entity.id }, + }" + size="md" + icon="vn:Person" + color="primary" + > + <QTooltip>{{ t('Go to client') }}</QTooltip> + </QBtn> + <QBtn + :to="{ + name: 'AccountCard', + params: { id: entity.user.id }, + }" + size="md" + icon="face" + color="primary" + > + <QTooltip>{{ t('Go to user') }}</QTooltip> + </QBtn> + </QCardActions> + </template> </CardDescriptor> </template> diff --git a/src/pages/Worker/Card/WorkerFormation.vue b/src/pages/Worker/Card/WorkerFormation.vue index 829326898..71c5cba5d 100644 --- a/src/pages/Worker/Card/WorkerFormation.vue +++ b/src/pages/Worker/Card/WorkerFormation.vue @@ -108,7 +108,7 @@ const columns = computed(() => [ :filter="courseFilter" :create="{ urlCreate: 'trainingCourses', - title: 'Create trainingCourse', + title: t('Create training course'), onDataSaved: () => tableRef.reload(), formInitialData: { workerFk: entityId, @@ -122,3 +122,7 @@ const columns = computed(() => [ :use-model="true" /> </template> +<i18n> +es: + Create training course: Crear curso de formación +</i18n> diff --git a/src/pages/Worker/Card/WorkerPBX.vue b/src/pages/Worker/Card/WorkerPBX.vue index 3bba5b33e..547156532 100644 --- a/src/pages/Worker/Card/WorkerPBX.vue +++ b/src/pages/Worker/Card/WorkerPBX.vue @@ -56,7 +56,7 @@ const updateModelValue = (data) => { @on-fetch="onFetch" > <template #form="{}"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('worker.summary.sipExtension')" v-model="extension" diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue index 513edcf45..4e0abc20c 100644 --- a/src/pages/Worker/Card/WorkerPda.vue +++ b/src/pages/Worker/Card/WorkerPda.vue @@ -126,7 +126,7 @@ function reloadData() { @on-data-saved="reloadData()" > <template #form-inputs="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('worker.pda.newPDA')" v-model="data.deviceProductionFk" diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue index d8bee4714..5c6261b94 100644 --- a/src/pages/Worker/Card/WorkerSummary.vue +++ b/src/pages/Worker/Card/WorkerSummary.vue @@ -10,6 +10,8 @@ import CardSummary from 'components/ui/CardSummary.vue'; import VnUserLink from 'src/components/ui/VnUserLink.vue'; import VnTitle from 'src/components/common/VnTitle.vue'; import RoleDescriptorProxy from 'src/pages/Account/Role/Card/RoleDescriptorProxy.vue'; +import VnRow from 'src/components/ui/VnRow.vue'; +import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue'; const route = useRoute(); const { t } = useI18n(); @@ -83,10 +85,14 @@ const filter = { :text="t('worker.summary.basicData')" /> <VnLv :label="t('worker.card.name')" :value="worker.user?.nickname" /> - <VnLv - :label="t('worker.list.department')" - :value="worker.department?.department?.name" - /> + <VnLv :label="t('worker.list.department')"> + <template #value> + <span class="link" v-text="worker.department?.department?.name" /> + <DepartmentDescriptorProxy + :id="worker.department?.department?.id" + /> + </template> + </VnLv> <VnLv :label="t('worker.list.email')" :value="worker.user.email" copy /> <VnLv :label="t('worker.summary.boss')" link> <template #value> @@ -133,30 +139,24 @@ const filter = { /> <VnLv :label="t('worker.summary.fi')" :value="worker.fi" /> <VnLv :label="t('worker.summary.birth')" :value="toDate(worker.birth)" /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.isFreelance')" - v-model="worker.isFreelance" - :disable="true" - /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.isSsDiscounted')" - v-model="worker.isSsDiscounted" - :disable="true" - /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.hasMachineryAuthorized')" - v-model="worker.hasMachineryAuthorized" - :disable="true" - /> - <QCheckbox - class="padding-none" - :label="t('worker.summary.isDisable')" - v-model="worker.isDisable" - :disable="true" - /> + <VnRow class="q-mt-sm" wrap> + <VnLv + :label="t('worker.summary.isFreelance')" + :value="worker.isFreelance" + /> + <VnLv + :label="t('worker.summary.isSsDiscounted')" + :value="worker.isSsDiscounted" + /> + <VnLv + :label="t('worker.summary.hasMachineryAuthorized')" + :value="worker.hasMachineryAuthorized" + /> + <VnLv + :label="t('worker.summary.isDisable')" + :value="worker.isDisable" + /> + </VnRow> </QCard> <QCard class="vn-one"> <VnTitle :text="t('worker.summary.userData')" /> diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue index f466c4f9a..87ff44e63 100644 --- a/src/pages/Worker/Card/WorkerTimeControl.vue +++ b/src/pages/Worker/Card/WorkerTimeControl.vue @@ -372,15 +372,15 @@ const showReasonForm = () => { const updateWorkerTimeControlMail = async (state, reason) => { try { const params = { - workerId: Number(route.params.id), year: selectedDate.value.getFullYear(), week: selectedWeekNumber.value, state, }; + const workerId = Number(route.params.id); if (reason) params.reason = reason; - await axios.post('WorkerTimeControls/updateWorkerTimeControlMail', params); + await axios.post(`WorkerTimeControls/${workerId}/updateMailState`, params); await getMailStates(selectedDate.value); await fetchWeekData(); notify(t('globals.dataSaved'), 'positive'); @@ -410,7 +410,7 @@ const resendEmail = async () => { workerId: Number(route.params.id), state: 'SENDED', }; - await axios.post('WorkerTimeControls/weekly-hour-hecord-email', params); + await axios.post('WorkerTimeControls/weekly-hour-record-email', params); await getMailStates(selectedDate.value); notify(t('Email sended'), 'positive'); } catch (err) { @@ -489,7 +489,7 @@ onMounted(async () => { </QBtnGroup> </div> </Teleport> - <QDrawer v-model="stateStore.rightDrawer" side="right" :width="260" class="q-pa-md"> + <Teleport to="#right-panel" v-if="stateStore.isHeaderMounted()"> <div class="q-pa-md q-mb-md" style="border: 2px solid #222"> <QCardSection horizontal> <span class="text-weight-bold text-subtitle1 text-center full-width"> @@ -515,7 +515,7 @@ onMounted(async () => { @click-date="onInputChange" @on-moved="getMailStates" /> - </QDrawer> + </Teleport> <QPage class="column items-center"> <QTable :columns="columns" :rows="['']" hide-bottom class="full-width"> <template #header="props"> diff --git a/src/pages/Worker/Card/WorkerTimeControlCalendar.vue b/src/pages/Worker/Card/WorkerTimeControlCalendar.vue index 20d02ca78..2717a71f4 100644 --- a/src/pages/Worker/Card/WorkerTimeControlCalendar.vue +++ b/src/pages/Worker/Card/WorkerTimeControlCalendar.vue @@ -4,7 +4,6 @@ import { useI18n } from 'vue-i18n'; import { QCalendarMonth } from '@quasar/quasar-ui-qcalendar/src/index.js'; import QCalendarMonthWrapper from 'src/components/ui/QCalendarMonthWrapper.vue'; - const $props = defineProps({ modelValue: { type: String, @@ -139,7 +138,9 @@ const paintWorkWeeks = async () => { show-work-weeks :weekdays="[1, 2, 3, 4, 5, 6, 0]" :selected-dates="selectedDates" + :min-weekday-label="1" :locale="locale" + animated mini-mode enable-outside-days class="q-py-sm" diff --git a/src/pages/Worker/Card/WorkerTimeForm.vue b/src/pages/Worker/Card/WorkerTimeForm.vue index 0a58a04ca..3250e3180 100644 --- a/src/pages/Worker/Card/WorkerTimeForm.vue +++ b/src/pages/Worker/Card/WorkerTimeForm.vue @@ -5,7 +5,7 @@ import { useRoute } from 'vue-router'; import VnSelect from 'src/components/common/VnSelect.vue'; import FormModelPopup from 'components/FormModelPopup.vue'; -import VnInputTime from 'components/common/VnInputTime.vue'; +import VnInputTime from 'src/components/common/VnInputTime.vue'; const $props = defineProps({ entryId: { @@ -37,8 +37,8 @@ const entryDirections = [ const closeButton = ref(null); -const onDataSaved = () => { - emit('onDataSaved'); +const onDataSaved = (dataSaved) => { + emit('onDataSaved', dataSaved); closeForm(); }; @@ -73,7 +73,7 @@ onBeforeMount(() => { :default-actions="false" :title="title" :url-create="urlCreate" - @on-data-saved="onDataSaved()" + @on-data-saved="onDataSaved" > <template #form-inputs="{ data }"> <VnInputTime @@ -91,7 +91,6 @@ onBeforeMount(() => { option-value="code" option-label="description" hide-selected - :required="true" /> </template> </FormModelPopup> diff --git a/src/pages/Worker/WorkerCreate.vue b/src/pages/Worker/WorkerCreate.vue index 5e81a3070..a1ded2bfd 100644 --- a/src/pages/Worker/WorkerCreate.vue +++ b/src/pages/Worker/WorkerCreate.vue @@ -21,7 +21,6 @@ const companiesOptions = ref([]); const workersOptions = ref([]); const payMethodsOptions = ref([]); const bankEntitiesOptions = ref([]); -const postcodesOptions = ref([]); const formData = ref({ isFreelance: false }); const defaultPayMethod = ref(0); @@ -173,7 +172,6 @@ onBeforeMount(async () => { <VnLocation :rules="validate('Worker.postcode')" :roles-allowed-to-create="['deliveryAssistant']" - :options="postcodesOptions" v-model="data.location" @update:model-value="(location) => handleLocation(data, location)" :disable="formData.isFreelance" diff --git a/src/pages/Worker/WorkerFilter.vue b/src/pages/Worker/WorkerFilter.vue index 0853791ef..765241341 100644 --- a/src/pages/Worker/WorkerFilter.vue +++ b/src/pages/Worker/WorkerFilter.vue @@ -5,6 +5,7 @@ import { useI18n } from 'vue-i18n'; import FetchData from 'components/FetchData.vue'; import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue'; import VnInput from 'src/components/common/VnInput.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; const { t } = useI18n(); const props = defineProps({ @@ -26,7 +27,7 @@ const departments = ref(); <span>{{ formatFn(tag.value) }}</span> </div> </template> - <template #body="{ params, searchFn }"> + <template #body="{ params }"> <QItem> <QItemSection> <VnInput :label="t('FI')" v-model="params.fi" is-outlined @@ -67,20 +68,17 @@ const departments = ref(); <QSkeleton type="QInput" class="full-width" /> </QItemSection> <QItemSection v-if="departments"> - <QSelect + <VnSelect :label="t('Department')" v-model="params.departmentFk" - @update:model-value="searchFn()" :options="departments" option-value="id" option-label="name" emit-value map-options - use-input dense outlined rounded - :input-debounce="0" /> </QItemSection> </QItem> @@ -107,6 +105,7 @@ en: userName: User extension: Extension departmentFk: Department + id: ID es: params: search: Contiene @@ -116,6 +115,7 @@ es: userName: Usuario extension: Extensión departmentFk: Departamento + id: ID FI: NIF First Name: Nombre Last Name: Apellidos diff --git a/src/pages/Worker/WorkerList.vue b/src/pages/Worker/WorkerList.vue index 8057e3e7c..7b3237f70 100644 --- a/src/pages/Worker/WorkerList.vue +++ b/src/pages/Worker/WorkerList.vue @@ -1,86 +1,298 @@ <script setup> +import { computed, ref } from 'vue'; import { useI18n } from 'vue-i18n'; -import { useRouter } from 'vue-router'; -import VnPaginate from 'src/components/ui/VnPaginate.vue'; -import WorkerSummary from './Card/WorkerSummary.vue'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; -import WorkerFilter from './WorkerFilter.vue'; -import VnLv from 'src/components/ui/VnLv.vue'; -import CardList from 'src/components/ui/CardList.vue'; import { useSummaryDialog } from 'src/composables/useSummaryDialog'; +import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; +import VnTable from 'src/components/VnTable/VnTable.vue'; +import WorkerSummary from './Card/WorkerSummary.vue'; +import VnRow from 'src/components/ui/VnRow.vue'; +import VnInput from 'src/components/common/VnInput.vue'; +import VnRadio from 'src/components/common/VnRadio.vue'; +import VnSelect from 'src/components/common/VnSelect.vue'; +import VnInputDate from 'src/components/common/VnInputDate.vue'; +import VnLocation from 'src/components/common/VnLocation.vue'; +import VnSelectDialog from 'src/components/common/VnSelectDialog.vue'; +import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue'; +import FetchData from 'src/components/FetchData.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; +import WorkerFilter from './WorkerFilter.vue'; -const router = useRouter(); const { t } = useI18n(); +const tableRef = ref(); const { viewSummary } = useSummaryDialog(); +const companiesOptions = ref([]); +const workersOptions = ref([]); +const payMethodsOptions = ref([]); +const bankEntitiesOptions = ref([]); +const postcodesOptions = ref([]); -function navigate(id) { - router.push({ path: `/worker/${id}` }); +const columns = computed(() => [ + { + align: 'left', + name: 'id', + label: t('id'), + field: 'id', + isId: true, + }, + { + align: 'left', + name: 'nickname', + label: t('tableColumns.name'), + isTitle: true, + columnFilter: { + name: 'firstName', + }, + }, + { + align: 'left', + name: 'departmentFk', + label: t('tableColumns.department'), + cardVisible: true, + columnFilter: { + component: 'select', + name: 'departmentFk', + attrs: { + url: 'Departments', + }, + }, + format: (row, dashIfEmpty) => dashIfEmpty(row.department), + }, + { + align: 'left', + name: 'email', + label: t('tableColumns.email'), + cardVisible: true, + columnFilter: { + alias: 'mu', + inWhere: true, + }, + hidden: true, + }, + { + align: 'right', + label: '', + name: 'tableActions', + actions: [ + { + title: t('InvoiceOutSummary'), + icon: 'preview', + action: (row) => viewSummary(row.id, WorkerSummary), + }, + ], + }, +]); + +function handleLocation(data, location) { + const { town, code, provinceFk, countryFk } = location ?? {}; + data.postcode = code; + data.city = town; + data.provinceFk = provinceFk; + data.countryFk = countryFk; } -const redirectToCreateView = () => { - router.push({ name: 'WorkerCreate' }); -}; +function uppercaseStreetModel(data) { + return { + get: () => (data.street ? data.street.toUpperCase() : ''), + set: (value) => { + data.street = value.toUpperCase(); + }, + }; +} </script> <template> <VnSearchbar - data-key="WorkerList" + data-key="Worker" :label="t('Search worker')" :info="t('You can search by worker id or name')" /> + <FetchData + url="Companies" + @on-fetch="(data) => (companiesOptions = data)" + auto-load + /> + <FetchData + url="Workers/search" + @on-fetch="(data) => (workersOptions = data)" + auto-load + /> + <FetchData + url="Paymethods" + @on-fetch="(data) => (payMethodsOptions = data)" + auto-load + /> + <FetchData + url="BankEntities" + @on-fetch="(data) => (bankEntitiesOptions = data)" + auto-load + /> <RightMenu> <template #right-panel> - <WorkerFilter data-key="WorkerList" /> + <WorkerFilter data-key="Worker" /> </template> </RightMenu> - <QPage class="column items-center q-pa-md"> - <div class="vn-card-list"> - <VnPaginate - data-key="WorkerList" - url="Workers/filter" - order="id DESC" - auto-load - > - <template #body="{ rows }"> - <CardList - v-for="row of rows" - :key="row.id" - :id="row.id" - :title="row.nickname" - @click="navigate(row.id)" + <VnTable + ref="tableRef" + data-key="Worker" + url="Workers/filter" + :create="{ + urlCreate: 'Workers/new', + title: t('Create worker'), + onDataSaved: ({ id }) => tableRef.redirect(id), + formInitialData: { + isFreelance: false, + }, + }" + :columns="columns" + default-mode="table" + redirect="worker" + :right-search="false" + auto-load + > + <template #more-create-dialog="{ data }"> + <div class="q-pa-lg full-width" style="max-width: 1200px"> + <VnRadio + v-model="data.isFreelance" + :val="false" + :label="`${t('Internal')}`" + @update:model-value="data.payMethodFk = defaultPayMethod" + /> + <VnRadio + v-model="data.isFreelance" + :val="true" + :label="`${t('External')}`" + @update:model-value="delete data.payMethodFk" + /> + <VnRow> + <VnInput v-model="data.firstName" :label="t('worker.create.name')" /> + <VnInput + v-model="data.lastNames" + :label="t('worker.create.lastName')" + /> + <VnInput v-model="data.code" :label="t('worker.create.code')" /> + </VnRow> + <VnRow> + <VnInput v-model="data.name" :label="t('worker.create.webUser')" /> + <VnInput + v-model="data.email" + :label="t('worker.create.personalEmail')" + /> + </VnRow> + <VnRow> + <VnSelect + :label="t('worker.create.company')" + v-model="data.companyFk" + :options="companiesOptions" + option-value="id" + option-label="code" + hide-selected + /> + <VnSelect + :label="t('worker.create.boss')" + v-model="data.bossFk" + :options="workersOptions" + option-value="id" + option-label="name" + hide-selected > - <template #list-items> - <VnLv :label="t('worker.list.name')" :value="row.userName" /> - <VnLv :label="t('worker.list.email')" :value="row.email" /> - <VnLv - :label="t('worker.list.department')" - :value="row.department" + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection> + <QItemLabel>{{ scope.opt.name }}</QItemLabel> + <QItemLabel caption + >{{ scope.opt.nickname }}, + {{ scope.opt.code }} + </QItemLabel> + </QItemSection> + </QItem> + </template> + </VnSelect> + </VnRow> + <VnRow> + <VnInput v-model="data.fi" :label="t('worker.create.fi')" /> + <VnInputDate + v-model="data.birth" + :label="t('worker.create.birth')" + :disable="data.isFreelance" + /> + <VnInput + v-model="data.phone" + :label="t('worker.create.phone')" + :disable="data.isFreelance" + /> + </VnRow> + <VnRow> + <VnLocation + :roles-allowed-to-create="['deliveryAssistant']" + :options="postcodesOptions" + v-model="data.location" + @update:model-value="(location) => handleLocation(data, location)" + :disable="data.isFreelance" + > + </VnLocation> + </VnRow> + <VnRow> + <VnInput + :label="t('worker.create.street')" + :model-value="uppercaseStreetModel(data).get()" + @update:model-value="uppercaseStreetModel(data).set" + :disable="data.isFreelance" + /> + </VnRow> + <VnRow> + <VnSelect + :label="t('worker.create.payMethods')" + v-model="data.payMethodFk" + :options="payMethodsOptions" + option-value="id" + option-label="name" + map-options + hide-selected + :disable="data.isFreelance" + @update:model-value="(val) => !val && delete data.payMethodFk" + /> + <VnInput + v-model="data.iban" + :label="t('worker.create.iban')" + :disable="data.isFreelance" + > + <template #append> + <QIcon name="info" class="cursor-info"> + <QTooltip>{{ t('components.iban_tooltip') }}</QTooltip> + </QIcon> + </template> + </VnInput> + </VnRow> + <VnRow> + <VnSelectDialog + :label="t('worker.create.bankEntity')" + v-model="data.bankEntityFk" + :options="bankEntitiesOptions" + option-label="name" + option-value="id" + hide-selected + :roles-allowed-to-create="['salesAssistant', 'hr']" + :disable="data.isFreelance" + > + <template #form> + <CreateBankEntityForm + @on-data-saved="(data) => bankEntitiesOptions.push(data)" /> </template> - <template #actions> - <QBtn - :label="t('components.smartCard.openCard')" - @click.stop="navigate(row.id)" - outline - /> - <QBtn - :label="t('components.smartCard.openSummary')" - @click.stop="viewSummary(row.id, WorkerSummary)" - color="primary" - style="margin-top: 15px" - /> + <template #option="scope"> + <QItem v-bind="scope.itemProps"> + <QItemSection v-if="scope.opt"> + <QItemLabel + >{{ scope.opt.bic }} + {{ scope.opt.name }}</QItemLabel + > + </QItemSection> + </QItem> </template> - </CardList> - </template> - </VnPaginate> - </div> - <QPageSticky :offset="[20, 20]"> - <QBtn fab icon="add" color="primary" @click="redirectToCreateView()" /> - <QTooltip> - {{ t('worker.list.newWorker') }} - </QTooltip> - </QPageSticky> - </QPage> + </VnSelectDialog> + </VnRow> + </div> + </template> + </VnTable> </template> <i18n> diff --git a/src/pages/Worker/WorkerMain.vue b/src/pages/Worker/WorkerMain.vue deleted file mode 100644 index 66ce78f23..000000000 --- a/src/pages/Worker/WorkerMain.vue +++ /dev/null @@ -1,17 +0,0 @@ -<script setup> -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; - -const stateStore = useStateStore(); -</script> - -<template> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> -</template> diff --git a/src/pages/Worker/locale/en.yml b/src/pages/Worker/locale/en.yml index f947b30e7..96df37919 100644 --- a/src/pages/Worker/locale/en.yml +++ b/src/pages/Worker/locale/en.yml @@ -1 +1,6 @@ passwordRequirements: 'The password must have at least { length } length characters, {nAlpha} alphabetic characters, {nUpper} capital letters, {nDigits} digits and {nPunct} symbols (Ex: $%&.)\n' +tableColumns: + id: ID + name: Name + department: Department + email: Email diff --git a/src/pages/Worker/locale/es.yml b/src/pages/Worker/locale/es.yml index d2478535a..41812345f 100644 --- a/src/pages/Worker/locale/es.yml +++ b/src/pages/Worker/locale/es.yml @@ -4,3 +4,8 @@ Locker: Taquilla Internal: Interno External: Externo passwordRequirements: 'La contraseña debe tener al menos { length } caracteres de longitud, {nAlpha} caracteres alfabéticos, {nUpper} letras mayúsculas, {nDigits} dígitos y {nPunct} símbolos (Ej: $%&.)' +tableColumns: + id: ID + name: Nombre + department: Departamento + email: Email diff --git a/src/pages/Zone/Card/ZoneBasicData.vue b/src/pages/Zone/Card/ZoneBasicData.vue index 9f2195766..a4874e5fc 100644 --- a/src/pages/Zone/Card/ZoneBasicData.vue +++ b/src/pages/Zone/Card/ZoneBasicData.vue @@ -31,11 +31,11 @@ const agencyOptions = ref([]); <FormModel :url="`Zones/${route.params.id}`" auto-load model="zone"> <template #form="{ data, validate }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput :label="t('Name')" clearable v-model="data.name" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect option-label="name" option-value="id" @@ -66,7 +66,7 @@ const agencyOptions = ref([]); /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.travelingDays" :label="t('Traveling days')" @@ -77,7 +77,7 @@ const agencyOptions = ref([]); <VnInputTime v-model="data.hour" :label="t('Closing')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.price" :label="t('Price')" @@ -94,7 +94,7 @@ const agencyOptions = ref([]); /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.inflation" :label="t('Inflation')" clearable /> <QCheckbox v-model="data.isVolumetric" diff --git a/src/pages/Zone/Card/ZoneCard.vue b/src/pages/Zone/Card/ZoneCard.vue index f92ee1e4e..b81ee9039 100644 --- a/src/pages/Zone/Card/ZoneCard.vue +++ b/src/pages/Zone/Card/ZoneCard.vue @@ -2,19 +2,14 @@ import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import { computed } from 'vue'; - import VnCard from 'components/common/VnCard.vue'; import ZoneDescriptor from './ZoneDescriptor.vue'; +import ZoneSearchbar from './ZoneSearchbar.vue'; const { t } = useI18n(); const route = useRoute(); const routeName = computed(() => route.name); -const customRouteRedirectName = computed(() => { - if (routeName.value === 'ZoneLocations') return null; - return routeName.value; -}); -const searchbarMakeFetch = computed(() => routeName.value !== 'ZoneEvents'); const searchBarDataKeys = { ZoneWarehouses: 'ZoneWarehouses', ZoneSummary: 'ZoneSummary', @@ -28,10 +23,15 @@ const searchBarDataKeys = { data-key="Zone" :descriptor="ZoneDescriptor" :search-data-key="searchBarDataKeys[routeName]" - :search-custom-route-redirect="customRouteRedirectName" - :search-redirect="!!customRouteRedirectName" - :search-make-fetch="searchbarMakeFetch" - :searchbar-label="t('list.searchZone')" - :searchbar-info="t('list.searchInfo')" - /> + :filter-panel="ZoneFilterPanel" + :searchbar-props="{ + url: 'Zones', + label: t('list.searchZone'), + info: t('list.searchInfo'), + }" + > + <template #searchbar> + <ZoneSearchbar /> + </template> + </VnCard> </template> diff --git a/src/pages/Zone/Card/ZoneCreateWarehouse.vue b/src/pages/Zone/Card/ZoneCreateWarehouse.vue index 0f35ee679..86c4dcc72 100644 --- a/src/pages/Zone/Card/ZoneCreateWarehouse.vue +++ b/src/pages/Zone/Card/ZoneCreateWarehouse.vue @@ -29,7 +29,7 @@ const warehousesOptions = ref([]); @on-submit="emit('onSubmitCreateWarehouse', ZoneWarehouseFormData)" > <template #form-inputs> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col"> <VnSelect :label="t('warehouses.warehouse')" diff --git a/src/pages/Zone/Card/ZoneDescriptor.vue b/src/pages/Zone/Card/ZoneDescriptor.vue index 602fefde3..04fb22ba5 100644 --- a/src/pages/Zone/Card/ZoneDescriptor.vue +++ b/src/pages/Zone/Card/ZoneDescriptor.vue @@ -52,7 +52,6 @@ const setData = (entity) => { :filter="filter" @on-fetch="setData" data-key="zoneData" - :summary="$attrs" > <template #menu="{ entity }"> <ZoneDescriptorMenuItems :zone="entity" /> diff --git a/src/pages/Zone/Card/ZoneEventInclusionForm.vue b/src/pages/Zone/Card/ZoneEventInclusionForm.vue index 808f14a53..66e41607f 100644 --- a/src/pages/Zone/Card/ZoneEventInclusionForm.vue +++ b/src/pages/Zone/Card/ZoneEventInclusionForm.vue @@ -149,7 +149,7 @@ onMounted(() => { class="q-mb-sm" /> </div> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <div class="col flex justify-center"> <VnInputDate v-if="inclusionType === 'day'" @@ -173,7 +173,7 @@ onMounted(() => { v-model="eventInclusionFormData.ended" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInputTime v-model="eventInclusionFormData.hour" :label="t('eventsInclusionForm.closing')" @@ -185,7 +185,7 @@ onMounted(() => { min="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="eventInclusionFormData.price" :label="t('eventsInclusionForm.price')" @@ -199,7 +199,7 @@ onMounted(() => { min="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="eventInclusionFormData.m3Max" :label="t('eventsInclusionForm.m3Max')" diff --git a/src/pages/Zone/ZoneMain.vue b/src/pages/Zone/Card/ZoneSearchbar.vue similarity index 71% rename from src/pages/Zone/ZoneMain.vue rename to src/pages/Zone/Card/ZoneSearchbar.vue index 68ff9a5d1..607057d0b 100644 --- a/src/pages/Zone/ZoneMain.vue +++ b/src/pages/Zone/Card/ZoneSearchbar.vue @@ -1,11 +1,8 @@ <script setup> import { useI18n } from 'vue-i18n'; -import { useStateStore } from 'stores/useStateStore'; -import LeftMenu from 'src/components/LeftMenu.vue'; -import VnSearchbar from 'src/components/ui/VnSearchbar.vue'; +import VnSearchbar from 'components/ui/VnSearchbar.vue'; const { t } = useI18n(); -const stateStore = useStateStore(); const exprBuilder = (param, value) => { switch (param) { @@ -49,12 +46,4 @@ const exprBuilder = (param, value) => { :info="t('list.searchInfo')" custom-route-redirect-name="ZoneSummary" /> - <QDrawer v-model="stateStore.leftDrawer" show-if-above :width="256"> - <QScrollArea class="fit text-grey-8"> - <LeftMenu /> - </QScrollArea> - </QDrawer> - <QPageContainer> - <RouterView></RouterView> - </QPageContainer> </template> diff --git a/src/pages/Zone/ZoneCreate.vue b/src/pages/Zone/ZoneCreate.vue index e25ccae3a..7d7fa24a3 100644 --- a/src/pages/Zone/ZoneCreate.vue +++ b/src/pages/Zone/ZoneCreate.vue @@ -51,14 +51,14 @@ const redirectToZoneLocations = (_, { id }) => { @on-data-saved="redirectToZoneLocations" > <template #form="{ data }"> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.name" :label="t('create.name')" :required="true" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnSelect :label="t('create.warehouse')" :options="warehousesOptions" @@ -77,7 +77,7 @@ const redirectToZoneLocations = (_, { id }) => { :required="true" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.travelingDays" :label="t('create.travelingDays')" @@ -87,7 +87,7 @@ const redirectToZoneLocations = (_, { id }) => { <VnInputTime v-model="data.hour" :label="t('create.closingHour')" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <VnInput v-model="data.price" :label="t('create.price')" @@ -101,7 +101,7 @@ const redirectToZoneLocations = (_, { id }) => { min="0" /> </VnRow> - <VnRow class="row q-gutter-md q-mb-md"> + <VnRow> <QCheckbox :label="t('create.volumetric')" v-model="data.isVolumetric" diff --git a/src/pages/Zone/ZoneDeliveryDays.vue b/src/pages/Zone/ZoneDeliveryDays.vue index ddde3f6b3..d95c64d8b 100644 --- a/src/pages/Zone/ZoneDeliveryDays.vue +++ b/src/pages/Zone/ZoneDeliveryDays.vue @@ -3,6 +3,7 @@ import { ref } from 'vue'; import ZoneDeliveryPanel from './ZoneDeliveryPanel.vue'; import ZoneCalendarGrid from './ZoneCalendarGrid.vue'; import RightMenu from 'src/components/common/RightMenu.vue'; +import ZoneSearchbar from './Card/ZoneSearchbar.vue'; const firstDay = ref(null); const lastDay = ref(null); @@ -10,6 +11,7 @@ const events = ref([]); </script> <template> + <ZoneSearchbar /> <RightMenu> <template #right-panel> <ZoneDeliveryPanel /> diff --git a/src/pages/Zone/ZoneList.vue b/src/pages/Zone/ZoneList.vue index 0932a0b57..0272292f6 100644 --- a/src/pages/Zone/ZoneList.vue +++ b/src/pages/Zone/ZoneList.vue @@ -15,6 +15,7 @@ import { useStateStore } from 'stores/useStateStore'; import axios from 'axios'; import RightMenu from 'src/components/common/RightMenu.vue'; import ZoneFilterPanel from './ZoneFilterPanel.vue'; +import ZoneSearchbar from './Card/ZoneSearchbar.vue'; const stateStore = useStateStore(); const { t } = useI18n(); @@ -87,6 +88,7 @@ onMounted(() => (stateStore.rightDrawer = true)); </script> <template> + <ZoneSearchbar /> <RightMenu> <template #right-panel> <ZoneFilterPanel data-key="ZoneList" :expr-builder="exprBuilder" /> diff --git a/src/pages/Zone/ZoneUpcoming.vue b/src/pages/Zone/ZoneUpcoming.vue index be7b12534..ecf82bf4f 100644 --- a/src/pages/Zone/ZoneUpcoming.vue +++ b/src/pages/Zone/ZoneUpcoming.vue @@ -7,6 +7,7 @@ import FetchData from 'components/FetchData.vue'; import { toDateFormat } from 'src/filters/date.js'; import { useWeekdayStore } from 'src/stores/useWeekdayStore'; +import ZoneSearchbar from './Card/ZoneSearchbar.vue'; const { t } = useI18n(); const weekdayStore = useWeekdayStore(); @@ -52,6 +53,7 @@ onMounted(() => weekdayStore.initStore()); @on-fetch="(data) => (details = data)" auto-load /> + <ZoneSearchbar /> <VnSubToolbar /> <QPage class="column items-center q-pa-md"> <QCard class="full-width q-pa-md"> diff --git a/src/router/index.js b/src/router/index.js index faa3ab5d4..686da2dde 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -46,7 +46,7 @@ export { Router }; export default route(function (/* { store, ssrContext } */) { Router.beforeEach(async (to, from, next) => { const { isLoggedIn } = session; - const outLayout = ['Login', 'TwoFactor', 'VerifyEmail']; + const outLayout = Router.options.routes[0].children.map((r) => r.name); if (!isLoggedIn() && !outLayout.includes(to.name)) { return next({ name: 'Login', query: { redirect: to.fullPath } }); } diff --git a/src/router/modules/Supplier.js b/src/router/modules/Supplier.js index da45aad2f..b711066b2 100644 --- a/src/router/modules/Supplier.js +++ b/src/router/modules/Supplier.js @@ -29,7 +29,7 @@ export default { { path: '', name: 'SupplierMain', - component: () => import('src/pages/Supplier/SupplierMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'SupplierList' }, children: [ { diff --git a/src/router/modules/account.js b/src/router/modules/account.js index 6f3f8c25b..cfec2b95d 100644 --- a/src/router/modules/account.js +++ b/src/router/modules/account.js @@ -34,7 +34,7 @@ export default { { path: '', name: 'AccountMain', - component: () => import('src/pages/Account/AccountMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'AccountList' }, children: [ { @@ -65,13 +65,13 @@ export default { component: () => import('src/pages/Account/AccountAliasList.vue'), }, { - path: 'connections', - name: 'AccountConnections', + path: 'acls', + name: 'AccountAcls', meta: { - title: 'connections', + title: 'acls', icon: 'check', }, - component: () => import('src/pages/Account/AccountConnections.vue'), + component: () => import('src/pages/Account/AccountAcls.vue'), }, { path: 'accounts', @@ -104,13 +104,13 @@ export default { component: () => import('src/pages/Account/AccountSamba.vue'), }, { - path: 'acls', - name: 'AccountAcls', + path: 'connections', + name: 'AccountConnections', meta: { - title: 'acls', - icon: 'check', + title: 'connections', + icon: 'share', }, - component: () => import('src/pages/Account/AccountAcls.vue'), + component: () => import('src/pages/Account/AccountConnections.vue'), }, { path: 'acl-form', diff --git a/src/router/modules/claim.js b/src/router/modules/claim.js index 65c714418..cced9e24d 100644 --- a/src/router/modules/claim.js +++ b/src/router/modules/claim.js @@ -26,7 +26,7 @@ export default { { name: 'ClaimMain', path: '', - component: () => import('src/pages/Claim/ClaimMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'ClaimList' }, children: [ { diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js index 9e3b39479..684b83b0f 100644 --- a/src/router/modules/customer.js +++ b/src/router/modules/customer.js @@ -38,7 +38,7 @@ export default { { path: '', name: 'CustomerMain', - component: () => import('src/pages/Customer/CustomerMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'CustomerList' }, children: [ { @@ -187,87 +187,32 @@ export default { }, { path: 'notes', - name: 'CustomerNotesCard', - redirect: { name: 'CustomerNotes' }, - children: [ - { - path: '', - name: 'CustomerNotes', - meta: { - title: 'notes', - icon: 'vn:notes', - }, - component: () => - import('src/pages/Customer/Card/CustomerNotes.vue'), - }, - { - path: 'create', - name: 'CustomerNoteCreate', - meta: { - title: 'note-create', - }, - component: () => - import( - 'src/pages/Customer/components/CustomerNoteCreate.vue' - ), - }, - ], + name: 'CustomerNotes', + meta: { + title: 'notes', + icon: 'vn:notes', + }, + component: () => import('src/pages/Customer/Card/CustomerNotes.vue'), }, { path: 'credits', - name: 'CreditsCard', - redirect: { name: 'CustomerCredits' }, - children: [ - { - path: '', - name: 'CustomerCredits', - meta: { - title: 'credits', - icon: 'vn:credit', - }, - component: () => - import('src/pages/Customer/Card/CustomerCredits.vue'), - }, - { - path: 'create', - name: 'CustomerCreditCreate', - meta: { - title: 'credit-create', - }, - component: () => - import( - 'src/pages/Customer/components/CustomerCreditCreate.vue' - ), - }, - ], + name: 'CustomerCredits', + meta: { + title: 'credits', + icon: 'vn:credit', + }, + component: () => + import('src/pages/Customer/Card/CustomerCredits.vue'), }, { path: 'greuges', - name: 'GreugesCard', - redirect: { name: 'CustomerGreuges' }, - children: [ - { - path: '', - name: 'CustomerGreuges', - meta: { - title: 'greuges', - icon: 'vn:greuge', - }, - component: () => - import('src/pages/Customer/Card/CustomerGreuges.vue'), - }, - { - path: 'create', - name: 'CustomerGreugeCreate', - meta: { - title: 'greuge-create', - }, - component: () => - import( - 'src/pages/Customer/components/CustomerGreugeCreate.vue' - ), - }, - ], + name: 'CustomerGreuges', + meta: { + title: 'greuges', + icon: 'vn:greuge', + }, + component: () => + import('src/pages/Customer/Card/CustomerGreuges.vue'), }, { path: 'balance', @@ -281,31 +226,13 @@ export default { }, { path: 'recoveries', - name: 'RecoveriesCard', - redirect: { name: 'CustomerRecoveries' }, - children: [ - { - path: '', - name: 'CustomerRecoveries', - meta: { - title: 'recoveries', - icon: 'vn:recovery', - }, - component: () => - import('src/pages/Customer/Card/CustomerRecoveries.vue'), - }, - { - path: 'create', - name: 'CustomerRecoverieCreate', - meta: { - title: 'recoverie-create', - }, - component: () => - import( - 'src/pages/Customer/components/CustomerRecoverieCreate.vue' - ), - }, - ], + name: 'CustomerRecoveries', + meta: { + title: 'recoveries', + icon: 'vn:recovery', + }, + component: () => + import('src/pages/Customer/Card/CustomerRecoveries.vue'), }, { path: 'web-access', diff --git a/src/router/modules/entry.js b/src/router/modules/entry.js index 4f5f05231..0d38ed626 100644 --- a/src/router/modules/entry.js +++ b/src/router/modules/entry.js @@ -18,7 +18,7 @@ export default { { path: '', name: 'EntryMain', - component: () => import('src/pages/Entry/EntryMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'EntryList' }, children: [ { diff --git a/src/router/modules/invoiceIn.js b/src/router/modules/invoiceIn.js index 75d0612aa..cd8f7de9c 100644 --- a/src/router/modules/invoiceIn.js +++ b/src/router/modules/invoiceIn.js @@ -25,7 +25,7 @@ export default { { path: '', name: 'InvoiceInMain', - component: () => import('src/pages/InvoiceIn/InvoiceInMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'InvoiceInList' }, children: [ { diff --git a/src/router/modules/invoiceOut.js b/src/router/modules/invoiceOut.js index aac84573c..5e83b0859 100644 --- a/src/router/modules/invoiceOut.js +++ b/src/router/modules/invoiceOut.js @@ -18,7 +18,7 @@ export default { { path: '', name: 'InvoiceOutMain', - component: () => import('src/pages/InvoiceOut/InvoiceOutMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'InvoiceOutList' }, children: [ { diff --git a/src/router/modules/item.js b/src/router/modules/item.js index 06fe680eb..4bd5df4e2 100644 --- a/src/router/modules/item.js +++ b/src/router/modules/item.js @@ -35,7 +35,7 @@ export default { { path: '', name: 'ItemMain', - component: () => import('src/pages/Item/ItemMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'ItemList' }, children: [ { diff --git a/src/router/modules/monitor.js b/src/router/modules/monitor.js index 6c388a474..f0db8d3f3 100644 --- a/src/router/modules/monitor.js +++ b/src/router/modules/monitor.js @@ -18,7 +18,7 @@ export default { { path: '', name: 'MonitorMain', - component: () => import('src/pages/Monitor/MonitorMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'MonitorList' }, children: [ { diff --git a/src/router/modules/order.js b/src/router/modules/order.js index aa1ca774d..9ccdb820b 100644 --- a/src/router/modules/order.js +++ b/src/router/modules/order.js @@ -18,7 +18,7 @@ export default { { path: '', name: 'OrderMain', - component: () => import('src/pages/Order/OrderMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'OrderList' }, children: [ { @@ -63,7 +63,7 @@ export default { title: 'basicData', icon: 'vn:settings', }, - component: () => import('src/pages/Order/Card/OrderForm.vue'), + component: () => import('src/pages/Order/Card/OrderBasicData.vue'), }, { name: 'OrderCatalog', @@ -72,7 +72,7 @@ export default { title: 'catalog', icon: 'vn:basket', }, - component: () => import('src/pages/Order/OrderCatalog.vue'), + component: () => import('src/pages/Order/Card/OrderCatalog.vue'), }, { name: 'OrderVolume', @@ -81,7 +81,7 @@ export default { title: 'volume', icon: 'vn:volume', }, - component: () => import('src/pages/Order/OrderVolume.vue'), + component: () => import('src/pages/Order/Card/OrderVolume.vue'), }, { name: 'OrderLines', @@ -90,7 +90,7 @@ export default { title: 'lines', icon: 'vn:lines', }, - component: () => import('src/pages/Order/OrderLines.vue'), + component: () => import('src/pages/Order/Card/OrderLines.vue'), }, ], }, diff --git a/src/router/modules/route.js b/src/router/modules/route.js index f6f92b7d9..3c5c860cf 100644 --- a/src/router/modules/route.js +++ b/src/router/modules/route.js @@ -18,7 +18,10 @@ export default { { path: '/route', name: 'RouteMain', - component: () => import('src/pages/Route/RouteMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), + props: { + leftDrawer: false, + }, redirect: { name: 'RouteList' }, children: [ { diff --git a/src/router/modules/shelving.js b/src/router/modules/shelving.js index d20ce40f4..70145dfb4 100644 --- a/src/router/modules/shelving.js +++ b/src/router/modules/shelving.js @@ -18,7 +18,7 @@ export default { { path: '', name: 'ShelvingMain', - component: () => import('src/pages/Shelving/ShelvingMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'ShelvingList' }, children: [ { diff --git a/src/router/modules/ticket.js b/src/router/modules/ticket.js index c507553d6..4074f089f 100644 --- a/src/router/modules/ticket.js +++ b/src/router/modules/ticket.js @@ -35,7 +35,7 @@ export default { { name: 'TicketMain', path: '', - component: () => import('src/pages/Ticket/TicketMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'TicketList' }, children: [ { diff --git a/src/router/modules/travel.js b/src/router/modules/travel.js index e1a08e9de..627692be8 100644 --- a/src/router/modules/travel.js +++ b/src/router/modules/travel.js @@ -18,7 +18,7 @@ export default { { path: '', name: 'TravelMain', - component: () => import('src/pages/Travel/TravelMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'TravelList' }, children: [ { diff --git a/src/router/modules/wagon.js b/src/router/modules/wagon.js index 6f9a4c819..d3d14a888 100644 --- a/src/router/modules/wagon.js +++ b/src/router/modules/wagon.js @@ -18,7 +18,7 @@ export default { { path: '/wagon', name: 'WagonMain', - component: () => import('src/pages/Wagon/WagonMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'WagonList' }, children: [ { @@ -62,7 +62,7 @@ export default { { path: '/wagon/type', name: 'WagonTypeMain', - component: () => import('src/pages/Wagon/WagonMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'WagonTypeList' }, children: [ { diff --git a/src/router/modules/worker.js b/src/router/modules/worker.js index 3fc71c2a3..f80df5e06 100644 --- a/src/router/modules/worker.js +++ b/src/router/modules/worker.js @@ -31,7 +31,7 @@ export default { { path: '', name: 'WorkerMain', - component: () => import('src/pages/Worker/WorkerMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'WorkerList' }, children: [ { @@ -104,6 +104,25 @@ export default { }, ], }, + { + name: 'WorkerTimeControl', + path: 'time-control', + meta: { + title: 'timeControl', + icon: 'access_time', + }, + component: () => + import('src/pages/Worker/Card/WorkerTimeControl.vue'), + }, + { + name: 'WorkerCalendar', + path: 'calendar', + meta: { + title: 'calendar', + icon: 'calendar_today', + }, + component: () => import('src/pages/Worker/Card/WorkerCalendar.vue'), + }, { name: 'WorkerPda', path: 'pda', @@ -150,25 +169,6 @@ export default { }, component: () => import('src/pages/Worker/Card/WorkerLog.vue'), }, - { - name: 'WorkerCalendar', - path: 'calendar', - meta: { - title: 'calendar', - icon: 'calendar_today', - }, - component: () => import('src/pages/Worker/Card/WorkerCalendar.vue'), - }, - { - name: 'WorkerTimeControl', - path: 'time-control', - meta: { - title: 'timeControl', - icon: 'access_time', - }, - component: () => - import('src/pages/Worker/Card/WorkerTimeControl.vue'), - }, { name: 'WorkerLocker', path: 'locker', diff --git a/src/router/modules/zone.js b/src/router/modules/zone.js index fd6fa959b..889b47464 100644 --- a/src/router/modules/zone.js +++ b/src/router/modules/zone.js @@ -29,7 +29,7 @@ export default { { path: '/zone', name: 'ZoneMain', - component: () => import('src/pages/Zone/ZoneMain.vue'), + component: () => import('src/components/common/VnSectionMain.vue'), redirect: { name: 'ZoneList' }, children: [ { diff --git a/src/router/routes.js b/src/router/routes.js index 805eefb8c..cced308b5 100644 --- a/src/router/routes.js +++ b/src/router/routes.js @@ -46,6 +46,18 @@ const routes = [ meta: { title: 'verifyEmail' }, component: () => import('../pages/Login/VerifyEmail.vue'), }, + { + path: '/recoverPassword', + name: 'RecoverPassword', + meta: { title: 'recoverPassword' }, + component: () => import('../pages/Login/RecoverPassword.vue'), + }, + { + path: '/resetPassword', + name: 'ResetPassword', + meta: { title: 'resetPassword' }, + component: () => import('../pages/Login/ResetPassword.vue'), + }, ], }, { diff --git a/test/cypress/integration/entry/myEntry.spec.js b/test/cypress/integration/entry/myEntry.spec.js index 8edd3a11c..dca74dec2 100644 --- a/test/cypress/integration/entry/myEntry.spec.js +++ b/test/cypress/integration/entry/myEntry.spec.js @@ -7,7 +7,6 @@ describe('EntryMy when is supplier', () => { cy.stub(win, 'open'); }, }); - cy.waitForElement('.q-page', 6000); }); it('should open buyLabel when is supplier', () => { diff --git a/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js b/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js index efe5550c3..a64f98c10 100644 --- a/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInCorrective.spec.js @@ -1,7 +1,7 @@ /// <reference types="cypress" /> describe('InvoiceInCorrective', () => { - const createRectificative = '.q-menu > .q-list > :nth-child(4) > .q-item__section'; + const createRectificative = '.q-menu > .q-list > :nth-child(6) > .q-item__section'; const rectificativeSection = '.q-drawer-container .q-list > a:nth-child(6)'; const saveDialog = '.q-card > .q-card__actions > .q-btn--standard '; @@ -9,12 +9,16 @@ describe('InvoiceInCorrective', () => { cy.viewport(1280, 720); cy.login('developer'); cy.visit(`/#/invoice-in/1/summary`); - cy.waitForElement('.q-page'); + cy.intercept('POST', '/api/InvoiceIns/corrective').as('corrective'); cy.openActionsDescriptor(); cy.get(createRectificative).click(); cy.get(saveDialog).click(); + cy.wait('@corrective').then((interception) => { + const correctingId = interception.response.body; + cy.url().should('include', `/invoice-in/${correctingId}/summary`); + }); cy.get(rectificativeSection).click(); cy.get('tbody > tr:visible').should('have.length', 1); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js index c87fd4315..f6dac4c73 100644 --- a/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInIntrastat.spec.js @@ -1,8 +1,9 @@ /// <reference types="cypress" /> describe('InvoiceInIntrastat', () => { - const inputBtns = 'label button'; + const firstRow = 'tbody > :nth-child(1)'; const thirdRow = 'tbody > :nth-child(3)'; - const firstLineCode = 'tbody > :nth-child(1) > :nth-child(2)'; + const firstRowCode = `${firstRow} > :nth-child(2)`; + const firstRowAmount = `${firstRow} > :nth-child(3)`; beforeEach(() => { cy.login('developer'); @@ -10,26 +11,30 @@ describe('InvoiceInIntrastat', () => { }); it('should edit the first line', () => { - cy.selectOption(firstLineCode, 'Plantas vivas: Esqueje/injerto, Vid'); - - cy.get(inputBtns).eq(1).click(); - + cy.selectOption(firstRowCode, 'Plantas vivas: Esqueje/injerto, Vid'); + cy.get(firstRowAmount).clear(); cy.saveCard(); - cy.visit(`/#/invoice-in/1/intrastat`); - - cy.getValue(firstLineCode).should('equal', 'Plantas vivas: Esqueje/injerto, Vid'); + cy.get(`${firstRowCode} span`).should( + 'have.text', + '6021010:Plantas vivas: Esqueje/injerto, Vid' + ); }); it('should add a new row', () => { - const rowData = [false, 'Plantas vivas: Esqueje/injerto, Vid', 30, 10, 5, 'FR']; - cy.addRow(); - cy.fillRow(thirdRow, rowData); + cy.fillRow(thirdRow, [ + false, + 'Plantas vivas: Esqueje/injerto, Vid', + 30, + 10, + 5, + 'FR', + ]); cy.saveCard(); cy.get('.q-notification__message').should('have.text', 'Data saved'); }); it('should remove the first line', () => { - cy.removeRow(2); + cy.removeRow(1); }); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js index b2fa10d52..fa0d1c5e4 100644 --- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js @@ -1,23 +1,23 @@ /// <reference types="cypress" /> describe('InvoiceInList', () => { - const firstCard = '.q-card:nth-child(1)'; - const firstChipId = - ':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content'; - const firstDetailBtn = '.q-card:nth-child(1) .q-btn:nth-child(2)'; + const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)'; + const firstId = `${firstRow} > td:nth-child(1) span`; + const firstDetailBtn = `${firstRow} .q-btn:nth-child(1)`; const summaryHeaders = '.summaryBody .header-link'; beforeEach(() => { cy.viewport(1920, 1080); cy.login('developer'); cy.visit(`/#/invoice-in/list`); + cy.get('#searchbar input').type('{enter}'); }); it('should redirect on clicking a invoice', () => { - cy.get(firstChipId) + cy.get(firstId) .invoke('text') .then((content) => { const id = content.replace(/\D/g, ''); - cy.get(firstCard).click(); + cy.get(firstRow).click(); cy.url().should('include', `/invoice-in/${id}/summary`); }); }); diff --git a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js index 63e99eac1..018ae7a53 100644 --- a/test/cypress/integration/invoiceIn/invoiceInVat.spec.js +++ b/test/cypress/integration/invoiceIn/invoiceInVat.spec.js @@ -4,8 +4,7 @@ describe('InvoiceInVat', () => { const firstLineVat = 'tbody > :nth-child(1) > :nth-child(4)'; const dialogInputs = '.q-dialog label input'; const dialogBtns = '.q-dialog button'; - const acrossInput = - ':nth-child(1) > .q-td.q-table--col-auto-width > .q-field > .q-field__inner > .q-field__control > :nth-child(2) > .default-icon'; + const acrossInput = 'tbody tr:nth-child(1) td:nth-child(2) .default-icon'; const randomInt = Math.floor(Math.random() * 100); beforeEach(() => { @@ -16,9 +15,7 @@ describe('InvoiceInVat', () => { it('should edit the sage iva', () => { cy.selectOption(firstLineVat, 'H.P. IVA 21% CEE'); cy.saveCard(); - cy.visit(`/#/invoice-in/1/vat`); - - cy.getValue(firstLineVat).should('equal', '8'); + cy.get(`${firstLineVat} span`).should('have.text', '8:H.P. IVA 21% CEE'); }); it('should add a new row', () => { diff --git a/test/cypress/integration/login.spec.js b/test/cypress/integration/outLogin/login.spec.js similarity index 100% rename from test/cypress/integration/login.spec.js rename to test/cypress/integration/outLogin/login.spec.js diff --git a/test/cypress/integration/logout.spec.js b/test/cypress/integration/outLogin/logout.spec.js similarity index 84% rename from test/cypress/integration/logout.spec.js rename to test/cypress/integration/outLogin/logout.spec.js index b35a8415a..423189908 100644 --- a/test/cypress/integration/logout.spec.js +++ b/test/cypress/integration/outLogin/logout.spec.js @@ -7,10 +7,8 @@ describe('Logout', () => { }); describe('by user', () => { it('should logout', () => { - cy.get( - '#user > .q-btn__content > .q-avatar > .q-avatar__content > .q-img > .q-img__container > .q-img__image' - ).click(); - cy.get('.block').click(); + cy.get('#user').click(); + cy.get('#logout').click(); }); }); describe('not user', () => { diff --git a/test/cypress/integration/outLogin/recoverPassword.spec.js b/test/cypress/integration/outLogin/recoverPassword.spec.js new file mode 100755 index 000000000..eec81b661 --- /dev/null +++ b/test/cypress/integration/outLogin/recoverPassword.spec.js @@ -0,0 +1,54 @@ +/// <reference types="cypress" /> +describe('Recover Password', () => { + const username = 'trainee'; + beforeEach(() => { + cy.visit('/#/login'); + cy.get('#switchLanguage').click(); + cy.get('.q-menu > :nth-child(1) > .q-item').click(); + }); + + it('should go to recover password section and send notification', () => { + cy.get('input[aria-label="Username"]').type(username); + cy.get(`a[href="#/recoverPassword?user=${username}"]`).click(); + + cy.waitForElement('input[aria-label="User or recovery email"]'); + cy.get('input[aria-label="User or recovery email"]').should( + 'have.value', + username + ); + + cy.get('button[type="submit"]').click(); + cy.get('.q-notification__message').should('have.text', 'Notification sent'); + }); + + it('should change password to user', () => { + // Get token from mail + cy.request( + `http://localhost:3000/api/Mails?filter=%7B%22where%22%3A%20%7B%22receiver%22%3A%20%22${username}%40mydomain.com%22%7D%2C%20%22order%22%3A%20%5B%22id%20DESC%22%5D%7D&access_token=DEFAULT_TOKEN` + ).then((response) => { + const regex = /access_token=([a-zA-Z0-9]+)/; + const [match] = response.body[0].body.match(regex); + + const resetUrl = '/#/resetPassword?' + match; + cy.visit(resetUrl); + }); + + // Change password + const newPassword = 'test.1234'; + cy.waitForElement('input[aria-label="Password"]'); + cy.waitForElement('input[aria-label="Repeat password"]'); + cy.get('input[aria-label="Password"]').type(newPassword); + cy.get('input[aria-label="Repeat password"]').type(newPassword); + + cy.get('button[type="submit"]').click(); + cy.get('.q-notification__message').should('have.text', 'Password changed'); + + // Try to login successfully + cy.get('input[aria-label="Username"]').type(username); + cy.get('input[aria-label="Password"]').type(newPassword); + cy.get('button[type="submit"]').click(); + cy.url().should('contain', '/dashboard'); + + // ❗The password cannot be returned because "nightmare" does not meet the requirements + }); +}); diff --git a/test/cypress/integration/outLogin/twoFactor.spec.js b/test/cypress/integration/outLogin/twoFactor.spec.js new file mode 100755 index 000000000..4d8561f0f --- /dev/null +++ b/test/cypress/integration/outLogin/twoFactor.spec.js @@ -0,0 +1,56 @@ +/// <reference types="cypress" /> +describe('Two Factor', () => { + const username = 'sysadmin'; + const userId = 66; + beforeEach(() => { + cy.visit('/#/login'); + cy.get('#switchLanguage').click(); + cy.get('.q-menu > :nth-child(1) > .q-item').click(); + }); + + it('should enable two factor to sysadmin', () => { + cy.request( + 'PATCH', + `http://localhost:3000/api/VnUsers/${userId}/update-user?access_token=DEFAULT_TOKEN`, + { twoFactor: 'email' } + ); + }); + + it('should fail when login with incorrect two factor', () => { + cy.get('input[aria-label="Username"]').type(username); + cy.get('input[aria-label="Password"]').type('nightmare'); + cy.get('button[type="submit"]').click(); + cy.get('.q-notification__message').should( + 'have.text', + 'Two-factor verification required' + ); + + cy.get('input[type="text"]').type('123456'); + cy.get('button[type="submit"]').click(); + cy.url().should('contain', '/twoFactor'); + }); + + it('should login with correct two factor', () => { + cy.get('input[aria-label="Username"]').type(username); + cy.get('input[aria-label="Password"]').type('nightmare'); + cy.get('button[type="submit"]').click(); + cy.get('.q-notification__message').should( + 'have.text', + 'Two-factor verification required' + ); + + // Get code from mail + cy.request( + `http://localhost:3000/api/Mails?filter=%7B%22where%22%3A%20%7B%22receiver%22%3A%20%22${username}%40mydomain.com%22%7D%2C%20%22order%22%3A%20%5B%22id%20DESC%22%5D%7D&access_token=DEFAULT_TOKEN` + ).then((response) => { + const tempDiv = document.createElement('div'); + tempDiv.innerHTML = response.body[0].body; + const codeElement = tempDiv.querySelector('.code'); + const code = codeElement ? codeElement.textContent.trim() : null; + + cy.get('input[type="text"]').type(code); + cy.get('button[type="submit"]').click(); + cy.url().should('contain', '/dashboard'); + }); + }); +}); diff --git a/test/cypress/integration/route/roadMap/roadmapList.spec.js b/test/cypress/integration/route/roadMap/roadmapList.spec.js new file mode 100644 index 000000000..ba602fdf6 --- /dev/null +++ b/test/cypress/integration/route/roadMap/roadmapList.spec.js @@ -0,0 +1,13 @@ +describe('RoadMap', () => { + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/route/roadmap`); + }); + it('Route list create roadmap and redirect', () => { + cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click(); + cy.get('input[name="name"]').eq(1).type('roadMapTestOne{enter}'); + cy.get('.q-notification__message').should('have.text', 'Data created'); + cy.url().should('include', '/summary'); + }); +}); diff --git a/test/cypress/integration/route/routeList.spec.js b/test/cypress/integration/route/routeList.spec.js index d30595d52..afc0fc395 100644 --- a/test/cypress/integration/route/routeList.spec.js +++ b/test/cypress/integration/route/routeList.spec.js @@ -4,12 +4,28 @@ describe('Route', () => { cy.login('developer'); cy.visit(`/#/route/list`); }); + const getVnSelect = + '> :nth-child(1) > .column > .q-field > .q-field__inner > .q-field__control > .q-field__control-container'; + const getRowColumn = (row, column) => `:nth-child(${row}) > :nth-child(${column})`; it('Route list create route', () => { - cy.visit(`/#/route/list`); cy.get('.q-page-sticky > div > .q-btn > .q-btn__content > .q-icon').click(); cy.get('input[name="description"]').eq(1).type('routeTestOne{enter}'); cy.get('.q-notification__message').should('have.text', 'Data created'); cy.url().should('include', '/summary'); }); + + it('Route list search and edit', () => { + cy.get('input[name="description"]').type('routeTestOne{enter}'); + cy.get('.q-table tr') + .its('length') + .then((rowCount) => { + expect(rowCount).to.be.greaterThan(0); + }); + cy.get(getRowColumn(1, 3) + getVnSelect).type('{downArrow}{enter}'); + cy.get(getRowColumn(1, 4) + getVnSelect).type('{downArrow}{enter}'); + cy.get(getRowColumn(1, 5) + getVnSelect).type('{downArrow}{enter}'); + cy.get('button[title="Save"]').click(); + cy.get('.q-notification__message').should('have.text', 'Data saved'); + }); }); diff --git a/test/cypress/integration/vnComponent/vnLocation.spec.js b/test/cypress/integration/vnComponent/vnLocation.spec.js index 6719d8391..30c1d6df2 100644 --- a/test/cypress/integration/vnComponent/vnLocation.spec.js +++ b/test/cypress/integration/vnComponent/vnLocation.spec.js @@ -1,8 +1,9 @@ -const locationOptions = '[role="listbox"] > div.q-virtual-scroll__content > .q-item'; describe('VnLocation', () => { + const locationOptions = '[role="listbox"] > div.q-virtual-scroll__content > .q-item'; const dialogInputs = '.q-dialog label input'; + const createLocationButton = '.q-form > .q-card > .vn-row:nth-child(6) .--add-icon'; + const inputLocation = '.q-form input[aria-label="Location"]'; describe('Worker Create', () => { - const inputLocation = '.q-form input[aria-label="Location"]'; beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); @@ -32,25 +33,50 @@ describe('VnLocation', () => { cy.login('developer'); cy.visit('/#/supplier/567/fiscal-data', { timeout: 7000 }); cy.waitForElement('.q-form'); + cy.get(createLocationButton).click(); }); - it('Create postCode', function () { - cy.get('.q-form > .q-card > .vn-row:nth-child(6) .--add-icon').click(); + it('Create postCode', () => { + const postCode = '1234475'; + const province = 'Valencia'; cy.get('.q-card > h1').should('have.text', 'New postcode'); - cy.get(dialogInputs).eq(0).clear('12'); - cy.get(dialogInputs).eq(0).type('1234453'); + cy.get(dialogInputs).eq(0).clear(); + cy.get(dialogInputs).eq(0).type(postCode); cy.selectOption( - '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(4) > .q-select > .q-field__inner > .q-field__control ', - 'Valencia' - ); - cy.selectOption( - '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(5) > .q-select > .q-field__inner > .q-field__control ', - 'Province one' - ); - cy.selectOption( - '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(6) > .q-select > .q-field__inner > .q-field__control ', - 'España' + '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(4) > .q-select > .q-field__inner > .q-field__control ', + province ); cy.get('.q-mt-lg > .q-btn--standard').click(); + cy.get('.q-dialog__inner > .column > #formModel > .q-card').should( + 'not.exist' + ); + checkVnLocation(postCode, province); }); + it('Create city', () => { + const postCode = '9011'; + const province = 'Saskatchew'; + cy.get(dialogInputs).eq(0).type(postCode); + // city create button + cy.get( + '.q-dialog__inner > .column > #formModel > .q-card > :nth-child(4) > .q-select > .q-field__inner > .q-field__control > :nth-child(2) > .q-icon' + ).click(); + cy.selectOption('#q-portal--dialog--2 .q-select', 'one'); + cy.get('#q-portal--dialog--2 .q-input').type(province); + cy.get('#q-portal--dialog--2 .q-btn--standard').click(); + cy.get('#q-portal--dialog--1 .q-btn--standard').click(); + checkVnLocation(postCode, province); + }); + + function checkVnLocation(postCode, province) { + cy.get('.q-dialog__inner > .column > #formModel > .q-card').should( + 'not.exist' + ); + cy.get('.q-form > .q-card > .vn-row:nth-child(6)') + .find('input') + .invoke('val') + .then((text) => { + expect(text).to.contain(postCode); + expect(text).to.contain(province); + }); + } }); }); diff --git a/test/cypress/integration/worker/workerCreate.spec.js b/test/cypress/integration/worker/workerCreate.spec.js index 26ce899c8..c1832ad67 100644 --- a/test/cypress/integration/worker/workerCreate.spec.js +++ b/test/cypress/integration/worker/workerCreate.spec.js @@ -1,5 +1,5 @@ describe('WorkerCreate', () => { - const externalRadio = '.q-toolbar .q-radio:nth-child(2)'; + const externalRadio = '.q-radio:nth-child(2)'; const notification = '.q-notification__message'; const developerBossId = 120; @@ -9,12 +9,13 @@ describe('WorkerCreate', () => { Name: { val: 'Manolo' }, 'Last name': { val: 'Hurtado' }, 'Personal email': { val: 'manolo@mydomain.com' }, + Company: { val: 'VNL', type: 'select' }, Street: { val: 'S/ DEFAULTWORKERSTREET' }, Location: { val: 1, type: 'select' }, Phone: { val: '123456789' }, 'Worker code': { val: 'DWW' }, Boss: { val: developerBossId, type: 'select' }, - Birth: { val: '2022-12-11T23:00:00.000Z', type: 'date', day: 11 }, + Birth: { val: '11-12-2022', type: 'date' }, }; const external = { Fi: { val: 'Z4531219V' }, @@ -29,16 +30,14 @@ describe('WorkerCreate', () => { beforeEach(() => { cy.viewport(1280, 720); cy.login('hr'); - cy.visit('/#/worker/create'); + cy.visit('/#/worker/list'); + cy.get('.q-page-sticky > div > .q-btn').click(); }); it('should throw an error if a pay method has not been selected', () => { cy.fillInForm(internal); - cy.saveCard(); - cy.get(notification).should( - 'contains.text', - 'That payment method requires an IBAN' - ); + cy.get('.q-mt-lg > .q-btn--standard').click(); + cy.get(notification).should('contains.text', 'Payment method is required'); }); it('should create an internal', () => { @@ -46,14 +45,14 @@ describe('WorkerCreate', () => { ...internal, 'Pay method': { val: 'PayMethod one', type: 'select' }, }); - cy.saveCard(); + cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(notification).should('contains.text', 'Data created'); }); it('should create an external', () => { cy.get(externalRadio).click(); cy.fillInForm(external); - cy.saveCard(); + cy.get('.q-mt-lg > .q-btn--standard').click(); cy.get(notification).should('contains.text', 'Data created'); }); }); diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js index 9808fd157..8a8bea443 100644 --- a/test/cypress/integration/worker/workerList.spec.js +++ b/test/cypress/integration/worker/workerList.spec.js @@ -1,25 +1,19 @@ describe('WorkerList', () => { - const workerFieldNames = - '.card-list-body > .list-items > :nth-child(1) > .value > span'; + const inputName = '.q-drawer .q-form input[aria-label="First Name"]'; + const searchBtn = '.q-drawer button:nth-child(3)'; + const descriptorTitle = '.descriptor .title span'; beforeEach(() => { cy.viewport(1280, 720); cy.login('developer'); cy.visit('/#/worker/list'); }); - it('should load workers', () => { - cy.get(workerFieldNames).eq(2).should('have.text', 'jessicajones'); - cy.get(workerFieldNames).eq(3).should('have.text', 'brucebanner'); - cy.get(workerFieldNames).eq(4).should('have.text', 'charlesxavier'); - }); - it('should open the worker summary', () => { - cy.openListSummary(2); - cy.get('.summaryHeader div').should('have.text', '1110 - Jessica Jones'); - cy.get('.summary .header-link') - .eq(0) - .invoke('text') - .should('include', 'Basic data'); - cy.get('.summary .header-link').eq(2).should('have.text', 'User data '); + cy.get(inputName).type('jessica{enter}'); + cy.get(searchBtn).click(); + cy.intercept('GET', /\/api\/Workers\/\d+/).as('worker'); + cy.wait('@worker').then(() => + cy.get(descriptorTitle).should('include.text', 'Jessica') + ); }); }); diff --git a/test/cypress/integration/worker/workerLocker.spec.js b/test/cypress/integration/worker/workerLocker.spec.js index ef2f88300..9a4066f54 100644 --- a/test/cypress/integration/worker/workerLocker.spec.js +++ b/test/cypress/integration/worker/workerLocker.spec.js @@ -2,7 +2,7 @@ describe('WorkerLocker', () => { const workerId = 1109; const lockerCode = '2F'; const input = '.q-card input'; - const firstOpt = '[role="listbox"] .q-item:nth-child(1)'; + const thirdOpt = '[role="listbox"] .q-item:nth-child(1)'; beforeEach(() => { cy.viewport(1280, 720); cy.login('productionBoss'); @@ -11,8 +11,8 @@ describe('WorkerLocker', () => { it('should allocates a locker', () => { cy.get(input).click(); - cy.get(input).type(lockerCode); - cy.get(firstOpt).click(); + cy.waitForElement('[role="listbox"]'); + cy.get(thirdOpt).click(); cy.saveCard(); cy.get(input).invoke('val').should('eq', lockerCode); }); diff --git a/test/cypress/integration/zone/zoneDeliveryDays.spec.js b/test/cypress/integration/zone/zoneDeliveryDays.spec.js new file mode 100644 index 000000000..1e1fc8ff5 --- /dev/null +++ b/test/cypress/integration/zone/zoneDeliveryDays.spec.js @@ -0,0 +1,15 @@ +describe('ZoneDeliveryDays', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit(`/#/zone/delivery-days`); + }); + + it('should query for the day', () => { + cy.get('.q-form > .q-btn > .q-btn__content').click(); + cy.get('.q-notification__message').should( + 'have.text', + 'No service for the specified zone' + ); + }); +}); diff --git a/test/cypress/integration/zone/zoneList.spec.js b/test/cypress/integration/zone/zoneList.spec.js new file mode 100644 index 000000000..f35da7e5f --- /dev/null +++ b/test/cypress/integration/zone/zoneList.spec.js @@ -0,0 +1,15 @@ +describe('ZoneList', () => { + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/zone/list`); + }); + + it('should open the details', () => { + cy.get(':nth-child(1) > .text-right > .material-symbols-outlined').click(); + }); + it('should redirect to summary', () => { + cy.waitForElement('.q-page'); + cy.get('tbody > :nth-child(1)').click(); + }); +}); diff --git a/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js b/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js new file mode 100644 index 000000000..28e2222d4 --- /dev/null +++ b/test/cypress/integration/zone/zoneUpcomingDeliveries.spec.js @@ -0,0 +1,9 @@ +describe('ZoneUpcomingDeliveries', () => { + beforeEach(() => { + cy.login('developer'); + cy.viewport(1920, 1080); + cy.visit(`/#/zone/upcoming-deliveries`); + }); + + it('should show the page', () => {}); +}); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 38a23f71c..3cf909af5 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -87,7 +87,6 @@ Cypress.Commands.add('selectOption', (selector, option) => { }); Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => { - const days = '.q-date__calendar-days .q-date__calendar-item--in'; cy.waitForElement('.q-form > .q-card'); cy.get(`${form} input`).each(([el]) => { cy.wrap(el) @@ -96,17 +95,15 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => { const field = obj[ariaLabel]; if (!field) return; - const { type, val, day } = field; + const { type, val } = field; switch (type) { case 'select': cy.wrap(el).type(val); cy.get('.q-menu .q-item').contains(val).click(); + cy.get('body').click(); break; case 'date': - cy.wrap(el).click(); - cy.get(days) - .eq(day ? day - 1 : 0) - .click(); + cy.wrap(el).type(val.split('-').join('')); break; default: cy.wrap(el).type(val); @@ -191,11 +188,14 @@ Cypress.Commands.add('validateRow', (rowSelector, expectedValues) => { }); Cypress.Commands.add('removeRow', (rowIndex) => { + const trEls = 'tbody > tr:visible'; let rowsBefore; - cy.get('tbody > tr:visible') + cy.get('tbody > tr') .its('length') .then((length) => { - cy.get('.q-checkbox').eq(rowIndex).click(); + cy.get(`${trEls} .q-checkbox`) + .eq(rowIndex - 1) + .click(); cy.removeCard(); cy.get('.q-dialog button').eq(2).click(); rowsBefore = length; @@ -204,7 +204,7 @@ Cypress.Commands.add('removeRow', (rowIndex) => { // Check the existence of tbody before performing the second assertion. cy.get('tbody').then(($tbody) => { if ($tbody.length > 0) - cy.get('tbody > tr:visible').should('have.length', rowsBefore - 1); + cy.get('tbody > tr').should('have.length', rowsBefore - 1); }); }); }); diff --git a/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js b/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js index 13293f596..466a544b4 100644 --- a/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js +++ b/test/vitest/__tests__/pages/Customer/CustomerPayments.spec.js @@ -35,18 +35,4 @@ describe('CustomerPayments', () => { ); }); }); - - describe('stateColor()', () => { - it('should return "positive" when isConfirmed property is truthy', async () => { - const result = await vm.stateColor({ isConfirmed: true }); - - expect(result).toEqual('positive'); - }); - - it('should return "primary" when isConfirmed property is falsy', async () => { - const result = await vm.stateColor({ isConfirmed: false }); - - expect(result).toEqual('primary'); - }); - }); }); diff --git a/test/vitest/__tests__/pages/Login/Login.spec.js b/test/vitest/__tests__/pages/Login/Login.spec.js index 9b9968736..e90a8ee53 100644 --- a/test/vitest/__tests__/pages/Login/Login.spec.js +++ b/test/vitest/__tests__/pages/Login/Login.spec.js @@ -25,27 +25,25 @@ describe('Login', () => { vi.spyOn(axios, 'post').mockResolvedValueOnce({ data: { token: 'token' } }); vi.spyOn(axios, 'get').mockImplementation((url) => { if (url === 'VnUsers/acls') return Promise.resolve({ data: [] }); - return Promise.resolve({data: { roles: [], user: expectedUser , multimediaToken: {id:'multimediaToken' }}}); + return Promise.resolve({ + data: { + roles: [], + user: expectedUser, + multimediaToken: { id: 'multimediaToken' }, + }, + }); }); - vi.spyOn(vm.quasar, 'notify'); expect(vm.session.getToken()).toEqual(''); await vm.onSubmit(); expect(vm.session.getToken()).toEqual('token'); - expect(vm.quasar.notify).toHaveBeenCalledWith( - expect.objectContaining({ type: 'positive' }) - ); await vm.session.destroy(); }); it('should not set the token into session if any error occurred', async () => { vi.spyOn(axios, 'post').mockReturnValue({ data: null }); - vi.spyOn(vm.quasar, 'notify'); - await vm.onSubmit(); - - expect(vm.quasar.notify).not.toHaveBeenCalled(); }); }); diff --git a/test/vitest/helper.js b/test/vitest/helper.js index d6721d817..e201535ec 100644 --- a/test/vitest/helper.js +++ b/test/vitest/helper.js @@ -38,6 +38,7 @@ vi.mock('vue-router', () => ({ meta: { moduleName: 'mockName' }, path: 'mockSection/list', }), + onBeforeRouteLeave: () => {}, })); vi.mock('axios');