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');