diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index 263e5eb89..000000000
--- a/.eslintignore
+++ /dev/null
@@ -1,6 +0,0 @@
-/dist
-/src-capacitor
-/src-cordova
-/.quasar
-/node_modules
-.eslintrc.js
diff --git a/.eslintrc.js b/.eslintrc.js
deleted file mode 100644
index 5c33d2118..000000000
--- a/.eslintrc.js
+++ /dev/null
@@ -1,75 +0,0 @@
-export default {
-    // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
-    // This option interrupts the configuration hierarchy at this file
-    // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
-    root: true,
-
-    parserOptions: {
-        ecmaVersion: '2021', // Allows for the parsing of modern ECMAScript features
-    },
-
-    env: {
-        node: true,
-        browser: true,
-        'vue/setup-compiler-macros': true,
-    },
-
-    // Rules order is important, please avoid shuffling them
-    extends: [
-        // Base ESLint recommended rules
-        'eslint:recommended',
-
-        // Uncomment any of the lines below to choose desired strictness,
-        // but leave only one uncommented!
-        // See https://eslint.vuejs.org/rules/#available-rules
-        // 'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
-        'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
-        // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
-
-        // https://github.com/prettier/eslint-config-prettier#installation
-        // usage with Prettier, provided by 'eslint-config-prettier'.
-        'prettier',
-    ],
-
-    plugins: [
-        // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
-        // required to lint *.vue files
-        'vue',
-
-        // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
-        // Prettier has not been included as plugin to avoid performance impact
-        // add it as an extension for your IDE
-    ],
-
-    globals: {
-        ga: 'readonly', // Google Analytics
-        cordova: 'readonly',
-        __statics: 'readonly',
-        __QUASAR_SSR__: 'readonly',
-        __QUASAR_SSR_SERVER__: 'readonly',
-        __QUASAR_SSR_CLIENT__: 'readonly',
-        __QUASAR_SSR_PWA__: 'readonly',
-        process: 'readonly',
-        Capacitor: 'readonly',
-        chrome: 'readonly',
-    },
-
-    // add your custom rules here
-    rules: {
-        'prefer-promise-reject-errors': 'off',
-        'no-unused-vars': 'warn',
-        'vue/no-multiple-template-root': 'off',
-        // allow debugger during development only
-        'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
-    },
-    overrides: [
-        {
-            files: ['test/cypress/**/*.*'],
-            extends: [
-                // Add Cypress-specific lint rules, globals and Cypress plugin
-                // See https://github.com/cypress-io/eslint-plugin-cypress#rules
-                'plugin:cypress/recommended',
-            ],
-        },
-    ],
-};
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 000000000..ba1902263
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+    "extends": ["plugin:cypress/recommended"]
+}
diff --git a/Jenkinsfile b/Jenkinsfile
index 05ef34791..a9db9d369 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -125,8 +125,10 @@ pipeline {
                             sh "docker-compose ${env.COMPOSE_PARAMS} pull db"
                             sh "docker-compose ${env.COMPOSE_PARAMS} up -d"
 
+                            def modules = sh(script: 'node test/cypress/docker/find/find.js', returnStdout: true).trim()
+                            echo "E2E MODULES: ${modules}"
                             image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {
-                                sh 'sh test/cypress/cypressParallel.sh 1'
+                                sh "sh test/cypress/docker/cypressParallel.sh 1 '${modules}'"
                             }
                         }
                     }
@@ -183,3 +185,4 @@ pipeline {
         }
     }
 }
+
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 000000000..70f738bbe
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,87 @@
+import cypress from 'eslint-plugin-cypress';
+import eslint from 'eslint-plugin-import';
+import globals from 'globals';
+import js from '@eslint/js';
+import vue from 'eslint-plugin-vue';
+export default {
+    plugins: { vue, eslint, cypress },
+    languageOptions: {
+        globals: {
+            ...globals.node,
+            ...globals.browser,
+            ...vue.configs['vue3-strongly-recommended'].globals,
+            ...cypress.environments.globals.globals,
+            ga: 'readonly',
+            cordova: 'readonly',
+            __statics: 'readonly',
+            __QUASAR_SSR__: 'readonly',
+            __QUASAR_SSR_SERVER__: 'readonly',
+            __QUASAR_SSR_CLIENT__: 'readonly',
+            __QUASAR_SSR_PWA__: 'readonly',
+            process: 'readonly',
+            Capacitor: 'readonly',
+            chrome: 'readonly',
+        },
+
+        ecmaVersion: 2020,
+        sourceType: 'module',
+
+        parserOptions: {
+            parser: '@babel/eslint-parser',
+        },
+    },
+    rules: {
+        ...vue.rules['flat/strongly-recommended'],
+        ...js.configs.recommended.rules,
+        semi: 'off',
+        'generator-star-spacing': 'warn',
+        'arrow-parens': 'warn',
+        'no-var': 'error',
+        'prefer-const': 'error',
+        'prefer-template': 'warn',
+        'prefer-destructuring': 'off',
+        'prefer-spread': 'warn',
+        'prefer-rest-params': 'warn',
+        'prefer-object-spread': 'warn',
+        'prefer-arrow-callback': 'warn',
+        'prefer-numeric-literals': 'warn',
+        'prefer-exponentiation-operator': 'warn',
+        'prefer-regex-literals': 'warn',
+        'one-var': [
+            'error',
+            {
+                let: 'never',
+                const: 'never',
+            },
+        ],
+        'no-void': 'off',
+        'prefer-promise-reject-errors': 'error',
+        'multiline-ternary': 'warn',
+        'no-restricted-imports': 'warn',
+        'no-import-assign': 'warn',
+        'no-duplicate-imports': 'warn',
+        'no-useless-rename': 'warn',
+        'eslint/no-named-as-default': 'warn',
+        'eslint/no-named-as-default-member': 'warn',
+        'no-unsafe-optional-chaining': 'warn',
+        'no-undef': 'error',
+        'no-unused-vars': 'error',
+        'no-console': 'error',
+        'no-debugger': 'error',
+        'no-useless-escape': 'error',
+        'no-prototype-builtins': 'error',
+        'no-async-promise-executor': 'error',
+        'no-irregular-whitespace': 'error',
+        'no-constant-condition': 'error',
+        'no-unsafe-finally': 'error',
+        'no-extend-native': 'error',
+    },
+    ignores: [
+        '/dist',
+        '/src-capacitor',
+        '/src-cordova',
+        '/.quasar',
+        '/node_modules',
+        '.eslintrc.js',
+    ],
+};
diff --git a/package.json b/package.json
index 017412ef2..ccff022cf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "salix-front",
-    "version": "25.14.0",
+    "version": "25.16.0",
     "description": "Salix frontend",
     "productName": "Salix",
     "author": "Verdnatura",
@@ -9,7 +9,8 @@
     "type": "module",
     "scripts": {
         "resetDatabase": "cd ../salix && gulp docker",
-        "lint": "eslint --ext .js,.vue ./",
+        "lint": "eslint \"**/*.{vue,js}\" ",
+        "lint:fix": "eslint \"**/*.{vue,js}\" --fix ",
         "format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
         "test:e2e": "cypress open",
         "test:e2e:ci": "npm run resetDatabase && cd ../salix-front && cypress run",
@@ -31,38 +32,47 @@
         "axios": "^1.4.0",
         "chromium": "^3.0.3",
         "croppie": "^2.6.5",
+        "es-module-lexer": "^1.6.0",
+        "fast-glob": "^3.3.3",
         "moment": "^2.30.1",
         "pinia": "^2.1.3",
         "quasar": "^2.17.7",
         "validator": "^13.9.0",
         "vue": "^3.5.13",
-        "vue-i18n": "^9.3.0",
+        "vue-i18n": "^9.4.0",
+        "@eslint/eslintrc": "^3.2.0",
+        "@eslint/js": "^9.20.0",
         "vue-router": "^4.2.5"
     },
     "devDependencies": {
         "@commitlint/cli": "^19.2.1",
         "@commitlint/config-conventional": "^19.1.0",
-        "@intlify/unplugin-vue-i18n": "^0.8.2",
+        "@eslint/eslintrc": "^3.2.0",
+        "@eslint/js": "^9.20.0",
+        "@intlify/unplugin-vue-i18n": "^4.0.0",
         "@pinia/testing": "^0.1.2",
         "@quasar/app-vite": "^2.0.8",
         "@quasar/quasar-app-extension-qcalendar": "^4.0.2",
         "@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
+        "@vue/compiler-sfc": "^3.5.13",
         "@vue/test-utils": "^2.4.4",
         "autoprefixer": "^10.4.14",
         "cypress": "^14.1.0",
         "cypress-mochawesome-reporter": "^3.8.2",
         "eslint": "^9.18.0",
         "eslint-config-prettier": "^10.0.1",
+        "eslint-import-resolver-alias": "^1.1.2",
         "eslint-plugin-cypress": "^4.1.0",
+        "eslint-plugin-import": "^2.31.0",
         "eslint-plugin-vue": "^9.32.0",
+        "globals": "^16.0.0",
         "husky": "^8.0.0",
         "junit-merge": "^2.0.0",
         "mocha": "^11.1.0",
         "postcss": "^8.4.23",
         "prettier": "^3.4.2",
         "sass": "^1.83.4",
-        "vitepress": "^1.6.3",
-        "vitest": "^0.34.0",
+        "vitest": "^3.0.3",
         "xunit-viewer": "^10.6.1"
     },
     "engines": {
@@ -76,4 +86,4 @@
         "vite": "^6.0.11",
         "vitest": "^0.31.1"
     }
-}
\ No newline at end of file
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 51fc75469..35b1a9ea8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5,39 +5,51 @@ settings:
   excludeLinksFromLockfile: false
 
 dependencies:
+  '@eslint/eslintrc':
+    specifier: ^3.2.0
+    version: 3.3.1
+  '@eslint/js':
+    specifier: ^9.20.0
+    version: 9.24.0
   '@quasar/cli':
     specifier: ^2.4.1
-    version: 2.4.1
+    version: 2.5.0
   '@quasar/extras':
     specifier: ^1.16.16
     version: 1.16.17
   axios:
     specifier: ^1.4.0
-    version: 1.7.9
+    version: 1.8.4
   chromium:
     specifier: ^3.0.3
     version: 3.0.3
   croppie:
     specifier: ^2.6.5
     version: 2.6.5
+  es-module-lexer:
+    specifier: ^1.6.0
+    version: 1.6.0
+  fast-glob:
+    specifier: ^3.3.3
+    version: 3.3.3
   moment:
     specifier: ^2.30.1
     version: 2.30.1
   pinia:
     specifier: ^2.1.3
-    version: 2.3.1(typescript@5.7.3)(vue@3.5.13)
+    version: 2.3.1(typescript@5.8.3)(vue@3.5.13)
   quasar:
     specifier: ^2.17.7
-    version: 2.17.7
+    version: 2.18.1
   validator:
     specifier: ^13.9.0
-    version: 13.12.0
+    version: 13.15.0
   vue:
     specifier: ^3.5.13
-    version: 3.5.13(typescript@5.7.3)
+    version: 3.5.13(typescript@5.8.3)
   vue-i18n:
-    specifier: ^9.3.0
-    version: 9.14.2(vue@3.5.13)
+    specifier: ^9.4.0
+    version: 9.14.4(vue@3.5.13)
   vue-router:
     specifier: ^4.2.5
     version: 4.5.0(vue@3.5.13)
@@ -45,49 +57,61 @@ dependencies:
 devDependencies:
   '@commitlint/cli':
     specifier: ^19.2.1
-    version: 19.7.1(@types/node@22.13.5)(typescript@5.7.3)
+    version: 19.8.0(@types/node@22.14.0)(typescript@5.8.3)
   '@commitlint/config-conventional':
     specifier: ^19.1.0
-    version: 19.7.1
+    version: 19.8.0
   '@intlify/unplugin-vue-i18n':
-    specifier: ^0.8.2
-    version: 0.8.2(vue-i18n@9.14.2)
+    specifier: ^4.0.0
+    version: 4.0.0(vue-i18n@9.14.4)
   '@pinia/testing':
     specifier: ^0.1.2
     version: 0.1.7(pinia@2.3.1)(vue@3.5.13)
   '@quasar/app-vite':
     specifier: ^2.0.8
-    version: 2.1.0(@types/node@22.13.5)(eslint@9.20.1)(pinia@2.3.1)(quasar@2.17.7)(sass@1.85.0)(typescript@5.7.3)(vue-router@4.5.0)(vue@3.5.13)
+    version: 2.2.0(@types/node@22.14.0)(eslint@9.24.0)(pinia@2.3.1)(quasar@2.18.1)(sass@1.86.3)(typescript@5.8.3)(vue-router@4.5.0)(vue@3.5.13)
   '@quasar/quasar-app-extension-qcalendar':
     specifier: ^4.0.2
     version: 4.1.2
   '@quasar/quasar-app-extension-testing-unit-vitest':
     specifier: ^0.4.0
-    version: 0.4.0(@vue/test-utils@2.4.6)(quasar@2.17.7)(typescript@5.7.3)(vite@6.2.0)(vitest@0.34.6)(vue@3.5.13)
+    version: 0.4.0(@vue/test-utils@2.4.6)(quasar@2.18.1)(typescript@5.8.3)(vite@6.2.5)(vitest@3.1.1)(vue@3.5.13)
+  '@vue/compiler-sfc':
+    specifier: ^3.5.13
+    version: 3.5.13
   '@vue/test-utils':
     specifier: ^2.4.4
     version: 2.4.6
   autoprefixer:
     specifier: ^10.4.14
-    version: 10.4.20(postcss@8.5.3)
+    version: 10.4.21(postcss@8.5.3)
   cypress:
     specifier: ^14.1.0
-    version: 14.1.0
+    version: 14.2.1
   cypress-mochawesome-reporter:
     specifier: ^3.8.2
-    version: 3.8.2(cypress@14.1.0)(mocha@11.1.0)
+    version: 3.8.2(cypress@14.2.1)(mocha@11.1.0)
   eslint:
     specifier: ^9.18.0
-    version: 9.20.1
+    version: 9.24.0
   eslint-config-prettier:
     specifier: ^10.0.1
-    version: 10.0.1(eslint@9.20.1)
+    version: 10.1.1(eslint@9.24.0)
+  eslint-import-resolver-alias:
+    specifier: ^1.1.2
+    version: 1.1.2(eslint-plugin-import@2.31.0)
   eslint-plugin-cypress:
     specifier: ^4.1.0
-    version: 4.1.0(eslint@9.20.1)
+    version: 4.2.0(eslint@9.24.0)
+  eslint-plugin-import:
+    specifier: ^2.31.0
+    version: 2.31.0(eslint@9.24.0)
   eslint-plugin-vue:
     specifier: ^9.32.0
-    version: 9.32.0(eslint@9.20.1)
+    version: 9.33.0(eslint@9.24.0)
+  globals:
+    specifier: ^16.0.0
+    version: 16.0.0
   husky:
     specifier: ^8.0.0
     version: 8.0.3
@@ -102,182 +126,19 @@ devDependencies:
     version: 8.5.3
   prettier:
     specifier: ^3.4.2
-    version: 3.5.1
+    version: 3.5.3
   sass:
     specifier: ^1.83.4
-    version: 1.85.0
-  vitepress:
-    specifier: ^1.6.3
-    version: 1.6.3(@algolia/client-search@5.20.3)(@types/node@22.13.5)(axios@1.7.9)(postcss@8.5.3)(react-dom@19.0.0)(react@19.0.0)(sass@1.85.0)(search-insights@2.17.3)(typescript@5.7.3)
+    version: 1.86.3
   vitest:
-    specifier: ^0.34.0
-    version: 0.34.6(sass@1.85.0)
+    specifier: ^3.0.3
+    version: 3.1.1(@types/node@22.14.0)(sass@1.86.3)
   xunit-viewer:
     specifier: ^10.6.1
-    version: 10.6.1(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0)
+    version: 10.6.1(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0)
 
 packages:
 
-  /@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3):
-    resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==}
-    dependencies:
-      '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3)
-      '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)
-    transitivePeerDependencies:
-      - '@algolia/client-search'
-      - algoliasearch
-      - search-insights
-    dev: true
-
-  /@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3):
-    resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==}
-    peerDependencies:
-      search-insights: '>= 1 < 3'
-    dependencies:
-      '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)
-      search-insights: 2.17.3
-    transitivePeerDependencies:
-      - '@algolia/client-search'
-      - algoliasearch
-    dev: true
-
-  /@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3):
-    resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==}
-    peerDependencies:
-      '@algolia/client-search': '>= 4.9.1 < 6'
-      algoliasearch: '>= 4.9.1 < 6'
-    dependencies:
-      '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)
-      '@algolia/client-search': 5.20.3
-      algoliasearch: 5.20.3
-    dev: true
-
-  /@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3):
-    resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==}
-    peerDependencies:
-      '@algolia/client-search': '>= 4.9.1 < 6'
-      algoliasearch: '>= 4.9.1 < 6'
-    dependencies:
-      '@algolia/client-search': 5.20.3
-      algoliasearch: 5.20.3
-    dev: true
-
-  /@algolia/client-abtesting@5.20.3:
-    resolution: {integrity: sha512-wPOzHYSsW+H97JkBLmnlOdJSpbb9mIiuNPycUCV5DgzSkJFaI/OFxXfZXAh1gqxK+hf0miKue1C9bltjWljrNA==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/client-analytics@5.20.3:
-    resolution: {integrity: sha512-XE3iduH9lA7iTQacDGofBQyIyIgaX8qbTRRdj1bOCmfzc9b98CoiMwhNwdTifmmMewmN0EhVF3hP8KjKWwX7Yw==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/client-common@5.20.3:
-    resolution: {integrity: sha512-IYRd/A/R3BXeaQVT2805lZEdWo54v39Lqa7ABOxIYnUvX2vvOMW1AyzCuT0U7Q+uPdD4UW48zksUKRixShcWxA==}
-    engines: {node: '>= 14.0.0'}
-    dev: true
-
-  /@algolia/client-insights@5.20.3:
-    resolution: {integrity: sha512-QGc/bmDUBgzB71rDL6kihI2e1Mx6G6PxYO5Ks84iL3tDcIel1aFuxtRF14P8saGgdIe1B6I6QkpkeIddZ6vWQw==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/client-personalization@5.20.3:
-    resolution: {integrity: sha512-zuM31VNPDJ1LBIwKbYGz/7+CSm+M8EhlljDamTg8AnDilnCpKjBebWZR5Tftv/FdWSro4tnYGOIz1AURQgZ+tQ==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/client-query-suggestions@5.20.3:
-    resolution: {integrity: sha512-Nn872PuOI8qzi1bxMMhJ0t2AzVBqN01jbymBQOkypvZHrrjZPso3iTpuuLLo9gi3yc/08vaaWTAwJfPhxPwJUw==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/client-search@5.20.3:
-    resolution: {integrity: sha512-9+Fm1ahV8/2goSIPIqZnVitV5yHW5E5xTdKy33xnqGd45A9yVv5tTkudWzEXsbfBB47j9Xb3uYPZjAvV5RHbKA==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/ingestion@1.20.3:
-    resolution: {integrity: sha512-5GHNTiZ3saLjTNyr6WkP5hzDg2eFFAYWomvPcm9eHWskjzXt8R0IOiW9kkTS6I6hXBwN5H9Zna5mZDSqqJdg+g==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/monitoring@1.20.3:
-    resolution: {integrity: sha512-KUWQbTPoRjP37ivXSQ1+lWMfaifCCMzTnEcEnXwAmherS5Tp7us6BAqQDMGOD4E7xyaS2I8pto6WlOzxH+CxmA==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/recommend@5.20.3:
-    resolution: {integrity: sha512-oo/gG77xTTTclkrdFem0Kmx5+iSRFiwuRRdxZETDjwzCI7svutdbwBgV/Vy4D4QpYaX4nhY/P43k84uEowCE4Q==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
-  /@algolia/requester-browser-xhr@5.20.3:
-    resolution: {integrity: sha512-BkkW7otbiI/Er1AiEPZs1h7lxbtSO9p09jFhv3/iT8/0Yz0CY79VJ9iq+Wv1+dq/l0OxnMpBy8mozrieGA3mXQ==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-    dev: true
-
-  /@algolia/requester-fetch@5.20.3:
-    resolution: {integrity: sha512-eAVlXz7UNzTsA1EDr+p0nlIH7WFxo7k3NMxYe8p38DH8YVWLgm2MgOVFUMNg9HCi6ZNOi/A2w/id2ZZ4sKgUOw==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-    dev: true
-
-  /@algolia/requester-node-http@5.20.3:
-    resolution: {integrity: sha512-FqR3pQPfHfQyX1wgcdK6iyqu86yP76MZd4Pzj1y/YLMj9rRmRCY0E0AffKr//nrOFEwv6uY8BQY4fd9/6b0ZCg==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-common': 5.20.3
-    dev: true
-
   /@babel/code-frame@7.26.2:
     resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==}
     engines: {node: '>=6.9.0'}
@@ -295,65 +156,65 @@ packages:
     resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/parser@7.26.9:
-    resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==}
+  /@babel/parser@7.27.0:
+    resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==}
     engines: {node: '>=6.0.0'}
     hasBin: true
     dependencies:
-      '@babel/types': 7.26.9
+      '@babel/types': 7.27.0
 
-  /@babel/runtime@7.26.9:
-    resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==}
+  /@babel/runtime@7.27.0:
+    resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
     engines: {node: '>=6.9.0'}
     dependencies:
       regenerator-runtime: 0.14.1
     dev: true
 
-  /@babel/types@7.26.9:
-    resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
+  /@babel/types@7.27.0:
+    resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-string-parser': 7.25.9
       '@babel/helper-validator-identifier': 7.25.9
 
-  /@bufbuild/protobuf@2.2.3:
-    resolution: {integrity: sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg==}
+  /@bufbuild/protobuf@2.2.5:
+    resolution: {integrity: sha512-/g5EzJifw5GF8aren8wZ/G5oMuPoGeS6MQD3ca8ddcvdXR5UELUfdTZITCGNhNXynY/AYl3Z4plmxdj/tRl/hQ==}
     dev: true
 
   /@codemirror/autocomplete@6.18.6:
     resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==}
     dependencies:
-      '@codemirror/language': 6.10.8
+      '@codemirror/language': 6.11.0
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
       '@lezer/common': 1.2.3
     dev: true
 
-  /@codemirror/commands@6.8.0:
-    resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==}
+  /@codemirror/commands@6.8.1:
+    resolution: {integrity: sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==}
     dependencies:
-      '@codemirror/language': 6.10.8
+      '@codemirror/language': 6.11.0
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
       '@lezer/common': 1.2.3
     dev: true
 
-  /@codemirror/language@6.10.8:
-    resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==}
+  /@codemirror/language@6.11.0:
+    resolution: {integrity: sha512-A7+f++LodNNc1wGgoRDTt78cOwWm9KVezApgjOMp1W4hM0898nsqBXwF+sbePE7ZRcjN7Sa1Z5m2oN27XkmEjQ==}
     dependencies:
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
       '@lezer/common': 1.2.3
       '@lezer/highlight': 1.2.1
       '@lezer/lr': 1.4.2
       style-mod: 4.1.2
     dev: true
 
-  /@codemirror/lint@6.8.4:
-    resolution: {integrity: sha512-u4q7PnZlJUojeRe8FJa/njJcMctISGgPQ4PnWsd9268R4ZTtU+tfFYmwkBvgcrK2+QQ8tYFVALVb5fVJykKc5A==}
+  /@codemirror/lint@6.8.5:
+    resolution: {integrity: sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==}
     dependencies:
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
       crelt: 1.0.6
     dev: true
 
@@ -361,7 +222,7 @@ packages:
     resolution: {integrity: sha512-RMdPdmsrUf53pb2VwflKGHEe1XVM07hI7vV2ntgw1dmqhimpatSJKva4VA9h4TLUDOD4EIF02201oZurpnEFsg==}
     dependencies:
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
       crelt: 1.0.6
     dev: true
 
@@ -374,14 +235,14 @@ packages:
   /@codemirror/theme-one-dark@6.1.2:
     resolution: {integrity: sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==}
     dependencies:
-      '@codemirror/language': 6.10.8
+      '@codemirror/language': 6.11.0
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
       '@lezer/highlight': 1.2.1
     dev: true
 
-  /@codemirror/view@6.36.3:
-    resolution: {integrity: sha512-N2bilM47QWC8Hnx0rMdDxO2x2ImJ1FvZWXubwKgjeoOrWwEiFrtpA7SFHcuZ+o2Ze2VzbkgbzWVj4+V18LVkeg==}
+  /@codemirror/view@6.36.5:
+    resolution: {integrity: sha512-cd+FZEUlu3GQCYnguYm3EkhJ8KJVisqqUsCOKedBoAt/d9c76JUUap6U0UrpElln5k6VyrEOYliMuDAKIeDQLg==}
     dependencies:
       '@codemirror/state': 6.5.2
       style-mod: 4.1.2
@@ -395,16 +256,16 @@ packages:
     dev: true
     optional: true
 
-  /@commitlint/cli@19.7.1(@types/node@22.13.5)(typescript@5.7.3):
-    resolution: {integrity: sha512-iObGjR1tE/PfDtDTEfd+tnRkB3/HJzpQqRTyofS2MPPkDn1mp3DBC8SoPDayokfAy+xKhF8+bwRCJO25Nea0YQ==}
+  /@commitlint/cli@19.8.0(@types/node@22.14.0)(typescript@5.8.3):
+    resolution: {integrity: sha512-t/fCrLVu+Ru01h0DtlgHZXbHV2Y8gKocTR5elDOqIRUzQd0/6hpt2VIWOj9b3NDo7y4/gfxeR2zRtXq/qO6iUg==}
     engines: {node: '>=v18'}
     hasBin: true
     dependencies:
-      '@commitlint/format': 19.5.0
-      '@commitlint/lint': 19.7.1
-      '@commitlint/load': 19.6.1(@types/node@22.13.5)(typescript@5.7.3)
-      '@commitlint/read': 19.5.0
-      '@commitlint/types': 19.5.0
+      '@commitlint/format': 19.8.0
+      '@commitlint/lint': 19.8.0
+      '@commitlint/load': 19.8.0(@types/node@22.14.0)(typescript@5.8.3)
+      '@commitlint/read': 19.8.0
+      '@commitlint/types': 19.8.0
       tinyexec: 0.3.2
       yargs: 17.7.2
     transitivePeerDependencies:
@@ -412,27 +273,27 @@ packages:
       - typescript
     dev: true
 
-  /@commitlint/config-conventional@19.7.1:
-    resolution: {integrity: sha512-fsEIF8zgiI/FIWSnykdQNj/0JE4av08MudLTyYHm4FlLWemKoQvPNUYU2M/3tktWcCEyq7aOkDDgtjrmgWFbvg==}
+  /@commitlint/config-conventional@19.8.0:
+    resolution: {integrity: sha512-9I2kKJwcAPwMoAj38hwqFXG0CzS2Kj+SAByPUQ0SlHTfb7VUhYVmo7G2w2tBrqmOf7PFd6MpZ/a1GQJo8na8kw==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/types': 19.5.0
+      '@commitlint/types': 19.8.0
       conventional-changelog-conventionalcommits: 7.0.2
     dev: true
 
-  /@commitlint/config-validator@19.5.0:
-    resolution: {integrity: sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==}
+  /@commitlint/config-validator@19.8.0:
+    resolution: {integrity: sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/types': 19.5.0
+      '@commitlint/types': 19.8.0
       ajv: 8.17.1
     dev: true
 
-  /@commitlint/ensure@19.5.0:
-    resolution: {integrity: sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==}
+  /@commitlint/ensure@19.8.0:
+    resolution: {integrity: sha512-kNiNU4/bhEQ/wutI1tp1pVW1mQ0QbAjfPRo5v8SaxoVV+ARhkB8Wjg3BSseNYECPzWWfg/WDqQGIfV1RaBFQZg==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/types': 19.5.0
+      '@commitlint/types': 19.8.0
       lodash.camelcase: 4.3.0
       lodash.kebabcase: 4.1.1
       lodash.snakecase: 4.1.1
@@ -440,48 +301,48 @@ packages:
       lodash.upperfirst: 4.3.1
     dev: true
 
-  /@commitlint/execute-rule@19.5.0:
-    resolution: {integrity: sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==}
+  /@commitlint/execute-rule@19.8.0:
+    resolution: {integrity: sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A==}
     engines: {node: '>=v18'}
     dev: true
 
-  /@commitlint/format@19.5.0:
-    resolution: {integrity: sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==}
+  /@commitlint/format@19.8.0:
+    resolution: {integrity: sha512-EOpA8IERpQstxwp/WGnDArA7S+wlZDeTeKi98WMOvaDLKbjptuHWdOYYr790iO7kTCif/z971PKPI2PkWMfOxg==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/types': 19.5.0
+      '@commitlint/types': 19.8.0
       chalk: 5.4.1
     dev: true
 
-  /@commitlint/is-ignored@19.7.1:
-    resolution: {integrity: sha512-3IaOc6HVg2hAoGleRK3r9vL9zZ3XY0rf1RsUf6jdQLuaD46ZHnXBiOPTyQ004C4IvYjSWqJwlh0/u2P73aIE3g==}
+  /@commitlint/is-ignored@19.8.0:
+    resolution: {integrity: sha512-L2Jv9yUg/I+jF3zikOV0rdiHUul9X3a/oU5HIXhAJLE2+TXTnEBfqYP9G5yMw/Yb40SnR764g4fyDK6WR2xtpw==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/types': 19.5.0
+      '@commitlint/types': 19.8.0
       semver: 7.7.1
     dev: true
 
-  /@commitlint/lint@19.7.1:
-    resolution: {integrity: sha512-LhcPfVjcOcOZA7LEuBBeO00o3MeZa+tWrX9Xyl1r9PMd5FWsEoZI9IgnGqTKZ0lZt5pO3ZlstgnRyY1CJJc9Xg==}
+  /@commitlint/lint@19.8.0:
+    resolution: {integrity: sha512-+/NZKyWKSf39FeNpqhfMebmaLa1P90i1Nrb1SrA7oSU5GNN/lksA4z6+ZTnsft01YfhRZSYMbgGsARXvkr/VLQ==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/is-ignored': 19.7.1
-      '@commitlint/parse': 19.5.0
-      '@commitlint/rules': 19.6.0
-      '@commitlint/types': 19.5.0
+      '@commitlint/is-ignored': 19.8.0
+      '@commitlint/parse': 19.8.0
+      '@commitlint/rules': 19.8.0
+      '@commitlint/types': 19.8.0
     dev: true
 
-  /@commitlint/load@19.6.1(@types/node@22.13.5)(typescript@5.7.3):
-    resolution: {integrity: sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==}
+  /@commitlint/load@19.8.0(@types/node@22.14.0)(typescript@5.8.3):
+    resolution: {integrity: sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/config-validator': 19.5.0
-      '@commitlint/execute-rule': 19.5.0
-      '@commitlint/resolve-extends': 19.5.0
-      '@commitlint/types': 19.5.0
+      '@commitlint/config-validator': 19.8.0
+      '@commitlint/execute-rule': 19.8.0
+      '@commitlint/resolve-extends': 19.8.0
+      '@commitlint/types': 19.8.0
       chalk: 5.4.1
-      cosmiconfig: 9.0.0(typescript@5.7.3)
-      cosmiconfig-typescript-loader: 6.1.0(@types/node@22.13.5)(cosmiconfig@9.0.0)(typescript@5.7.3)
+      cosmiconfig: 9.0.0(typescript@5.8.3)
+      cosmiconfig-typescript-loader: 6.1.0(@types/node@22.14.0)(cosmiconfig@9.0.0)(typescript@5.8.3)
       lodash.isplainobject: 4.0.6
       lodash.merge: 4.6.2
       lodash.uniq: 4.5.0
@@ -490,67 +351,67 @@ packages:
       - typescript
     dev: true
 
-  /@commitlint/message@19.5.0:
-    resolution: {integrity: sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==}
+  /@commitlint/message@19.8.0:
+    resolution: {integrity: sha512-qs/5Vi9bYjf+ZV40bvdCyBn5DvbuelhR6qewLE8Bh476F7KnNyLfdM/ETJ4cp96WgeeHo6tesA2TMXS0sh5X4A==}
     engines: {node: '>=v18'}
     dev: true
 
-  /@commitlint/parse@19.5.0:
-    resolution: {integrity: sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==}
+  /@commitlint/parse@19.8.0:
+    resolution: {integrity: sha512-YNIKAc4EXvNeAvyeEnzgvm1VyAe0/b3Wax7pjJSwXuhqIQ1/t2hD3OYRXb6D5/GffIvaX82RbjD+nWtMZCLL7Q==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/types': 19.5.0
+      '@commitlint/types': 19.8.0
       conventional-changelog-angular: 7.0.0
       conventional-commits-parser: 5.0.0
     dev: true
 
-  /@commitlint/read@19.5.0:
-    resolution: {integrity: sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==}
+  /@commitlint/read@19.8.0:
+    resolution: {integrity: sha512-6ywxOGYajcxK1y1MfzrOnwsXO6nnErna88gRWEl3qqOOP8MDu/DTeRkGLXBFIZuRZ7mm5yyxU5BmeUvMpNte5w==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/top-level': 19.5.0
-      '@commitlint/types': 19.5.0
+      '@commitlint/top-level': 19.8.0
+      '@commitlint/types': 19.8.0
       git-raw-commits: 4.0.0
       minimist: 1.2.8
       tinyexec: 0.3.2
     dev: true
 
-  /@commitlint/resolve-extends@19.5.0:
-    resolution: {integrity: sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==}
+  /@commitlint/resolve-extends@19.8.0:
+    resolution: {integrity: sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/config-validator': 19.5.0
-      '@commitlint/types': 19.5.0
+      '@commitlint/config-validator': 19.8.0
+      '@commitlint/types': 19.8.0
       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.6.0:
-    resolution: {integrity: sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==}
+  /@commitlint/rules@19.8.0:
+    resolution: {integrity: sha512-IZ5IE90h6DSWNuNK/cwjABLAKdy8tP8OgGVGbXe1noBEX5hSsu00uRlLu6JuruiXjWJz2dZc+YSw3H0UZyl/mA==}
     engines: {node: '>=v18'}
     dependencies:
-      '@commitlint/ensure': 19.5.0
-      '@commitlint/message': 19.5.0
-      '@commitlint/to-lines': 19.5.0
-      '@commitlint/types': 19.5.0
+      '@commitlint/ensure': 19.8.0
+      '@commitlint/message': 19.8.0
+      '@commitlint/to-lines': 19.8.0
+      '@commitlint/types': 19.8.0
     dev: true
 
-  /@commitlint/to-lines@19.5.0:
-    resolution: {integrity: sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==}
+  /@commitlint/to-lines@19.8.0:
+    resolution: {integrity: sha512-3CKLUw41Cur8VMjh16y8LcsOaKbmQjAKCWlXx6B0vOUREplp6em9uIVhI8Cv934qiwkbi2+uv+mVZPnXJi1o9A==}
     engines: {node: '>=v18'}
     dev: true
 
-  /@commitlint/top-level@19.5.0:
-    resolution: {integrity: sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==}
+  /@commitlint/top-level@19.8.0:
+    resolution: {integrity: sha512-Rphgoc/omYZisoNkcfaBRPQr4myZEHhLPx2/vTXNLjiCw4RgfPR1wEgUpJ9OOmDCiv5ZyIExhprNLhteqH4FuQ==}
     engines: {node: '>=v18'}
     dependencies:
       find-up: 7.0.0
     dev: true
 
-  /@commitlint/types@19.5.0:
-    resolution: {integrity: sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==}
+  /@commitlint/types@19.8.0:
+    resolution: {integrity: sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg==}
     engines: {node: '>=v18'}
     dependencies:
       '@types/conventional-commits-parser': 5.0.1
@@ -561,8 +422,8 @@ packages:
     resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
     dev: true
 
-  /@cypress/request@3.0.7:
-    resolution: {integrity: sha512-LzxlLEMbBOPYB85uXrDqvD4MgcenjRBLIns3zyhx7vTPj/0u2eQhzXvPiGcaJrV38Q9dbkExWp6cOHPJ+EtFYg==}
+  /@cypress/request@3.0.8:
+    resolution: {integrity: sha512-h0NFgh1mJmm1nr4jCwkGHwKneVYKghUyWe6TMNrk0B9zsjAJxpg8C4/+BAcmLgCPa1vj1V8rNUaILl+zYRUWBQ==}
     engines: {node: '>= 6'}
     dependencies:
       aws-sign2: 0.7.0
@@ -578,9 +439,9 @@ packages:
       json-stringify-safe: 5.0.1
       mime-types: 2.1.35
       performance-now: 2.1.0
-      qs: 6.13.1
+      qs: 6.14.0
       safe-buffer: 5.2.1
-      tough-cookie: 5.1.1
+      tough-cookie: 5.1.2
       tunnel-agent: 0.6.0
       uuid: 8.3.2
     dev: true
@@ -594,62 +455,8 @@ packages:
       - supports-color
     dev: true
 
-  /@docsearch/css@3.8.2:
-    resolution: {integrity: sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==}
-    dev: true
-
-  /@docsearch/js@3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3):
-    resolution: {integrity: sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==}
-    dependencies:
-      '@docsearch/react': 3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3)
-      preact: 10.26.2
-    transitivePeerDependencies:
-      - '@algolia/client-search'
-      - '@types/react'
-      - react
-      - react-dom
-      - search-insights
-    dev: true
-
-  /@docsearch/react@3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3):
-    resolution: {integrity: sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==}
-    peerDependencies:
-      '@types/react': '>= 16.8.0 < 19.0.0'
-      react: '>= 16.8.0 < 19.0.0'
-      react-dom: '>= 16.8.0 < 19.0.0'
-      search-insights: '>= 1 < 3'
-    peerDependenciesMeta:
-      '@types/react':
-        optional: true
-      react:
-        optional: true
-      react-dom:
-        optional: true
-      search-insights:
-        optional: true
-    dependencies:
-      '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)(search-insights@2.17.3)
-      '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.20.3)(algoliasearch@5.20.3)
-      '@docsearch/css': 3.8.2
-      algoliasearch: 5.20.3
-      react: 19.0.0
-      react-dom: 19.0.0(react@19.0.0)
-      search-insights: 2.17.3
-    transitivePeerDependencies:
-      - '@algolia/client-search'
-    dev: true
-
-  /@esbuild/aix-ppc64@0.21.5:
-    resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [aix]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/aix-ppc64@0.24.2:
-    resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
+  /@esbuild/aix-ppc64@0.25.2:
+    resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==}
     engines: {node: '>=18'}
     cpu: [ppc64]
     os: [aix]
@@ -657,26 +464,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/aix-ppc64@0.25.0:
-    resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==}
-    engines: {node: '>=18'}
-    cpu: [ppc64]
-    os: [aix]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/android-arm64@0.21.5:
-    resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/android-arm64@0.24.2:
-    resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
+  /@esbuild/android-arm64@0.25.2:
+    resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [android]
@@ -684,26 +473,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/android-arm64@0.25.0:
-    resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/android-arm@0.21.5:
-    resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/android-arm@0.24.2:
-    resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
+  /@esbuild/android-arm@0.25.2:
+    resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==}
     engines: {node: '>=18'}
     cpu: [arm]
     os: [android]
@@ -711,26 +482,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/android-arm@0.25.0:
-    resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==}
-    engines: {node: '>=18'}
-    cpu: [arm]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/android-x64@0.21.5:
-    resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/android-x64@0.24.2:
-    resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
+  /@esbuild/android-x64@0.25.2:
+    resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [android]
@@ -738,26 +491,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/android-x64@0.25.0:
-    resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [android]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/darwin-arm64@0.21.5:
-    resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/darwin-arm64@0.24.2:
-    resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
+  /@esbuild/darwin-arm64@0.25.2:
+    resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [darwin]
@@ -765,26 +500,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/darwin-arm64@0.25.0:
-    resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/darwin-x64@0.21.5:
-    resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/darwin-x64@0.24.2:
-    resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
+  /@esbuild/darwin-x64@0.25.2:
+    resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [darwin]
@@ -792,26 +509,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/darwin-x64@0.25.0:
-    resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [darwin]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/freebsd-arm64@0.21.5:
-    resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/freebsd-arm64@0.24.2:
-    resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
+  /@esbuild/freebsd-arm64@0.25.2:
+    resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [freebsd]
@@ -819,26 +518,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/freebsd-arm64@0.25.0:
-    resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/freebsd-x64@0.21.5:
-    resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/freebsd-x64@0.24.2:
-    resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
+  /@esbuild/freebsd-x64@0.25.2:
+    resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [freebsd]
@@ -846,26 +527,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/freebsd-x64@0.25.0:
-    resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [freebsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-arm64@0.21.5:
-    resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-arm64@0.24.2:
-    resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
+  /@esbuild/linux-arm64@0.25.2:
+    resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [linux]
@@ -873,26 +536,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-arm64@0.25.0:
-    resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-arm@0.21.5:
-    resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
-    engines: {node: '>=12'}
-    cpu: [arm]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-arm@0.24.2:
-    resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
+  /@esbuild/linux-arm@0.25.2:
+    resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==}
     engines: {node: '>=18'}
     cpu: [arm]
     os: [linux]
@@ -900,26 +545,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-arm@0.25.0:
-    resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==}
-    engines: {node: '>=18'}
-    cpu: [arm]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-ia32@0.21.5:
-    resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-ia32@0.24.2:
-    resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
+  /@esbuild/linux-ia32@0.25.2:
+    resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==}
     engines: {node: '>=18'}
     cpu: [ia32]
     os: [linux]
@@ -927,26 +554,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-ia32@0.25.0:
-    resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==}
-    engines: {node: '>=18'}
-    cpu: [ia32]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-loong64@0.21.5:
-    resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
-    engines: {node: '>=12'}
-    cpu: [loong64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-loong64@0.24.2:
-    resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
+  /@esbuild/linux-loong64@0.25.2:
+    resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==}
     engines: {node: '>=18'}
     cpu: [loong64]
     os: [linux]
@@ -954,26 +563,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-loong64@0.25.0:
-    resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==}
-    engines: {node: '>=18'}
-    cpu: [loong64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-mips64el@0.21.5:
-    resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
-    engines: {node: '>=12'}
-    cpu: [mips64el]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-mips64el@0.24.2:
-    resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
+  /@esbuild/linux-mips64el@0.25.2:
+    resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==}
     engines: {node: '>=18'}
     cpu: [mips64el]
     os: [linux]
@@ -981,26 +572,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-mips64el@0.25.0:
-    resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==}
-    engines: {node: '>=18'}
-    cpu: [mips64el]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-ppc64@0.21.5:
-    resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
-    engines: {node: '>=12'}
-    cpu: [ppc64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-ppc64@0.24.2:
-    resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
+  /@esbuild/linux-ppc64@0.25.2:
+    resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==}
     engines: {node: '>=18'}
     cpu: [ppc64]
     os: [linux]
@@ -1008,26 +581,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-ppc64@0.25.0:
-    resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==}
-    engines: {node: '>=18'}
-    cpu: [ppc64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-riscv64@0.21.5:
-    resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
-    engines: {node: '>=12'}
-    cpu: [riscv64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-riscv64@0.24.2:
-    resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
+  /@esbuild/linux-riscv64@0.25.2:
+    resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==}
     engines: {node: '>=18'}
     cpu: [riscv64]
     os: [linux]
@@ -1035,26 +590,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-riscv64@0.25.0:
-    resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==}
-    engines: {node: '>=18'}
-    cpu: [riscv64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-s390x@0.21.5:
-    resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
-    engines: {node: '>=12'}
-    cpu: [s390x]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-s390x@0.24.2:
-    resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
+  /@esbuild/linux-s390x@0.25.2:
+    resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==}
     engines: {node: '>=18'}
     cpu: [s390x]
     os: [linux]
@@ -1062,26 +599,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-s390x@0.25.0:
-    resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==}
-    engines: {node: '>=18'}
-    cpu: [s390x]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-x64@0.21.5:
-    resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/linux-x64@0.24.2:
-    resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
+  /@esbuild/linux-x64@0.25.2:
+    resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [linux]
@@ -1089,17 +608,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/linux-x64@0.25.0:
-    resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [linux]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/netbsd-arm64@0.24.2:
-    resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
+  /@esbuild/netbsd-arm64@0.25.2:
+    resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [netbsd]
@@ -1107,26 +617,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/netbsd-arm64@0.25.0:
-    resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [netbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/netbsd-x64@0.21.5:
-    resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [netbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/netbsd-x64@0.24.2:
-    resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
+  /@esbuild/netbsd-x64@0.25.2:
+    resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [netbsd]
@@ -1134,17 +626,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/netbsd-x64@0.25.0:
-    resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [netbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/openbsd-arm64@0.24.2:
-    resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
+  /@esbuild/openbsd-arm64@0.25.2:
+    resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [openbsd]
@@ -1152,26 +635,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/openbsd-arm64@0.25.0:
-    resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [openbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/openbsd-x64@0.21.5:
-    resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [openbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/openbsd-x64@0.24.2:
-    resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
+  /@esbuild/openbsd-x64@0.25.2:
+    resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [openbsd]
@@ -1179,26 +644,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/openbsd-x64@0.25.0:
-    resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [openbsd]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/sunos-x64@0.21.5:
-    resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [sunos]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/sunos-x64@0.24.2:
-    resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
+  /@esbuild/sunos-x64@0.25.2:
+    resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [sunos]
@@ -1206,26 +653,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/sunos-x64@0.25.0:
-    resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [sunos]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/win32-arm64@0.21.5:
-    resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
-    engines: {node: '>=12'}
-    cpu: [arm64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/win32-arm64@0.24.2:
-    resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
+  /@esbuild/win32-arm64@0.25.2:
+    resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==}
     engines: {node: '>=18'}
     cpu: [arm64]
     os: [win32]
@@ -1233,26 +662,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/win32-arm64@0.25.0:
-    resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==}
-    engines: {node: '>=18'}
-    cpu: [arm64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/win32-ia32@0.21.5:
-    resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
-    engines: {node: '>=12'}
-    cpu: [ia32]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/win32-ia32@0.24.2:
-    resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
+  /@esbuild/win32-ia32@0.25.2:
+    resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==}
     engines: {node: '>=18'}
     cpu: [ia32]
     os: [win32]
@@ -1260,26 +671,8 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/win32-ia32@0.25.0:
-    resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==}
-    engines: {node: '>=18'}
-    cpu: [ia32]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/win32-x64@0.21.5:
-    resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
-    engines: {node: '>=12'}
-    cpu: [x64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@esbuild/win32-x64@0.24.2:
-    resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
+  /@esbuild/win32-x64@0.25.2:
+    resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==}
     engines: {node: '>=18'}
     cpu: [x64]
     os: [win32]
@@ -1287,22 +680,13 @@ packages:
     dev: true
     optional: true
 
-  /@esbuild/win32-x64@0.25.0:
-    resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==}
-    engines: {node: '>=18'}
-    cpu: [x64]
-    os: [win32]
-    requiresBuild: true
-    dev: true
-    optional: true
-
-  /@eslint-community/eslint-utils@4.4.1(eslint@9.20.1):
-    resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
+  /@eslint-community/eslint-utils@4.5.1(eslint@9.24.0):
+    resolution: {integrity: sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
     dependencies:
-      eslint: 9.20.1
+      eslint: 9.24.0
       eslint-visitor-keys: 3.4.3
     dev: true
 
@@ -1311,8 +695,8 @@ packages:
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
     dev: true
 
-  /@eslint/config-array@0.19.2:
-    resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==}
+  /@eslint/config-array@0.20.0:
+    resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     dependencies:
       '@eslint/object-schema': 2.1.6
@@ -1322,15 +706,27 @@ packages:
       - supports-color
     dev: true
 
-  /@eslint/core@0.11.0:
-    resolution: {integrity: sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==}
+  /@eslint/config-helpers@0.2.1:
+    resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    dev: true
+
+  /@eslint/core@0.12.0:
+    resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     dependencies:
       '@types/json-schema': 7.0.15
     dev: true
 
-  /@eslint/eslintrc@3.2.0:
-    resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==}
+  /@eslint/core@0.13.0:
+    resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==}
+    engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+    dependencies:
+      '@types/json-schema': 7.0.15
+    dev: true
+
+  /@eslint/eslintrc@3.3.1:
+    resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     dependencies:
       ajv: 6.12.6
@@ -1344,23 +740,21 @@ packages:
       strip-json-comments: 3.1.1
     transitivePeerDependencies:
       - supports-color
-    dev: true
 
-  /@eslint/js@9.20.0:
-    resolution: {integrity: sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==}
+  /@eslint/js@9.24.0:
+    resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
-    dev: true
 
   /@eslint/object-schema@2.1.6:
     resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     dev: true
 
-  /@eslint/plugin-kit@0.2.6:
-    resolution: {integrity: sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==}
+  /@eslint/plugin-kit@0.2.8:
+    resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     dependencies:
-      '@eslint/core': 0.11.0
+      '@eslint/core': 0.13.0
       levn: 0.4.1
     dev: true
 
@@ -1392,24 +786,14 @@ packages:
     engines: {node: '>=18.18'}
     dev: true
 
-  /@iconify-json/simple-icons@1.2.25:
-    resolution: {integrity: sha512-2E1/gOCO97rF6usfhhiXxwzCb+UhdEsxW3lW1Sew+xZY0COY6dp82Z/r1rUt2fWKneWjuoGcNeJHHXQyG8mIuw==}
-    dependencies:
-      '@iconify/types': 2.0.0
-    dev: true
-
-  /@iconify/types@2.0.0:
-    resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
-    dev: true
-
-  /@inquirer/figures@1.0.10:
-    resolution: {integrity: sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==}
+  /@inquirer/figures@1.0.11:
+    resolution: {integrity: sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==}
     engines: {node: '>=18'}
     dev: true
 
-  /@intlify/bundle-utils@4.0.0(vue-i18n@9.14.2):
-    resolution: {integrity: sha512-klXrYT9VXyKEXsD6UY3pShg0O5MPC07n0TZ5RrSs5ry6T1eZVolIFGJi9c3qcDrh1qjJxgikRnPBmD7qGDqbjw==}
-    engines: {node: '>= 12'}
+  /@intlify/bundle-utils@8.0.0(vue-i18n@9.14.4):
+    resolution: {integrity: sha512-1B++zykRnMwQ+20SpsZI1JCnV/YJt9Oq7AGlEurzkWJOFtFAVqaGc/oV36PBRYeiKnTbY9VYfjBimr2Vt42wLQ==}
+    engines: {node: '>= 14.16'}
     peerDependencies:
       petite-vue-i18n: '*'
       vue-i18n: '*'
@@ -1419,47 +803,38 @@ packages:
       vue-i18n:
         optional: true
     dependencies:
-      '@intlify/message-compiler': 11.0.0-rc.1
-      '@intlify/shared': 11.0.0-rc.1
-      jsonc-eslint-parser: 1.4.1
-      source-map: 0.6.1
-      vue-i18n: 9.14.2(vue@3.5.13)
-      yaml-eslint-parser: 0.3.2
-    dev: true
-
-  /@intlify/core-base@9.14.2:
-    resolution: {integrity: sha512-DZyQ4Hk22sC81MP4qiCDuU+LdaYW91A6lCjq8AWPvY3+mGMzhGDfOCzvyR6YBQxtlPjFqMoFk9ylnNYRAQwXtQ==}
-    engines: {node: '>= 16'}
-    dependencies:
-      '@intlify/message-compiler': 9.14.2
-      '@intlify/shared': 9.14.2
-
-  /@intlify/message-compiler@11.0.0-rc.1:
-    resolution: {integrity: sha512-TGw2uBfuTFTegZf/BHtUQBEKxl7Q/dVGLoqRIdw8lFsp9g/53sYn5iD+0HxIzdYjbWL6BTJMXCPUHp9PxDTRPw==}
-    engines: {node: '>= 16'}
-    dependencies:
-      '@intlify/shared': 11.0.0-rc.1
+      '@intlify/message-compiler': 9.14.4
+      '@intlify/shared': 9.14.4
+      acorn: 8.14.1
+      escodegen: 2.1.0
+      estree-walker: 2.0.2
+      jsonc-eslint-parser: 2.4.0
+      mlly: 1.7.4
       source-map-js: 1.2.1
+      vue-i18n: 9.14.4(vue@3.5.13)
+      yaml-eslint-parser: 1.3.0
     dev: true
 
-  /@intlify/message-compiler@9.14.2:
-    resolution: {integrity: sha512-YsKKuV4Qv4wrLNsvgWbTf0E40uRv+Qiw1BeLQ0LAxifQuhiMe+hfTIzOMdWj/ZpnTDj4RSZtkXjJM7JDiiB5LQ==}
+  /@intlify/core-base@9.14.4:
+    resolution: {integrity: sha512-vtZCt7NqWhKEtHa3SD/322DlgP5uR9MqWxnE0y8Q0tjDs9H5Lxhss+b5wv8rmuXRoHKLESNgw9d+EN9ybBbj9g==}
     engines: {node: '>= 16'}
     dependencies:
-      '@intlify/shared': 9.14.2
+      '@intlify/message-compiler': 9.14.4
+      '@intlify/shared': 9.14.4
+
+  /@intlify/message-compiler@9.14.4:
+    resolution: {integrity: sha512-vcyCLiVRN628U38c3PbahrhbbXrckrM9zpy0KZVlDk2Z0OnGwv8uQNNXP3twwGtfLsCf4gu3ci6FMIZnPaqZsw==}
+    engines: {node: '>= 16'}
+    dependencies:
+      '@intlify/shared': 9.14.4
       source-map-js: 1.2.1
 
-  /@intlify/shared@11.0.0-rc.1:
-    resolution: {integrity: sha512-8tR1xe7ZEbkabTuE/tNhzpolygUn9OaYp9yuYAF4MgDNZg06C3Qny80bes2/e9/Wm3aVkPUlCw6WgU7mQd0yEg==}
-    engines: {node: '>= 16'}
-    dev: true
-
-  /@intlify/shared@9.14.2:
-    resolution: {integrity: sha512-uRAHAxYPeF+G5DBIboKpPgC/Waecd4Jz8ihtkpJQD5ycb5PwXp0k/+hBGl5dAjwF7w+l74kz/PKA8r8OK//RUw==}
+  /@intlify/shared@9.14.4:
+    resolution: {integrity: sha512-P9zv6i1WvMc9qDBWvIgKkymjY2ptIiQ065PjDv7z7fDqH3J/HBRBN5IoiR46r/ujRcU7hCuSIZWvCAFCyuOYZA==}
     engines: {node: '>= 16'}
 
-  /@intlify/unplugin-vue-i18n@0.8.2(vue-i18n@9.14.2):
-    resolution: {integrity: sha512-cRnzPqSEZQOmTD+p4pwc3RTS9HxreLqfID0keoqZDZweCy/CGRMLLTNd15S4TUf1vSBhPF03DItEFDr1F+8MDA==}
+  /@intlify/unplugin-vue-i18n@4.0.0(vue-i18n@9.14.4):
+    resolution: {integrity: sha512-q2Mhqa/mLi0tulfLFO4fMXXvEbkSZpI5yGhNNsLTNJJ41icEGUuyDe+j5zRZIKSkOJRgX6YbCyibTDJdRsukmw==}
     engines: {node: '>= 14.16'}
     peerDependencies:
       petite-vue-i18n: '*'
@@ -1473,9 +848,9 @@ packages:
       vue-i18n-bridge:
         optional: true
     dependencies:
-      '@intlify/bundle-utils': 4.0.0(vue-i18n@9.14.2)
-      '@intlify/shared': 11.0.0-rc.1
-      '@rollup/pluginutils': 4.2.1
+      '@intlify/bundle-utils': 8.0.0(vue-i18n@9.14.4)
+      '@intlify/shared': 9.14.4
+      '@rollup/pluginutils': 5.1.4
       '@vue/compiler-sfc': 3.5.13
       debug: 4.4.0(supports-color@8.1.1)
       fast-glob: 3.3.3
@@ -1483,10 +858,11 @@ packages:
       json5: 2.2.3
       pathe: 1.1.2
       picocolors: 1.1.1
-      source-map: 0.6.1
+      source-map-js: 1.2.1
       unplugin: 1.16.1
-      vue-i18n: 9.14.2(vue@3.5.13)
+      vue-i18n: 9.14.4(vue@3.5.13)
     transitivePeerDependencies:
+      - rollup
       - supports-color
     dev: true
 
@@ -1502,13 +878,6 @@ packages:
       wrap-ansi-cjs: /wrap-ansi@7.0.0
     dev: true
 
-  /@jest/schemas@29.6.3:
-    resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@sinclair/typebox': 0.27.8
-    dev: true
-
   /@jridgewell/gen-mapping@0.3.8:
     resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
     engines: {node: '>=6.0.0'}
@@ -1571,20 +940,17 @@ packages:
     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.19.0
-    dev: true
+      fastq: 1.19.1
 
   /@one-ini/wasm@0.1.1:
     resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
@@ -1738,7 +1104,7 @@ packages:
     peerDependencies:
       pinia: '>=2.2.6'
     dependencies:
-      pinia: 2.3.1(typescript@5.7.3)(vue@3.5.13)
+      pinia: 2.3.1(typescript@5.8.3)(vue@3.5.13)
       vue-demi: 0.14.10(vue@3.5.13)
     transitivePeerDependencies:
       - '@vue/composition-api'
@@ -1773,8 +1139,8 @@ packages:
       config-chain: 1.1.13
     dev: false
 
-  /@quasar/app-vite@2.1.0(@types/node@22.13.5)(eslint@9.20.1)(pinia@2.3.1)(quasar@2.17.7)(sass@1.85.0)(typescript@5.7.3)(vue-router@4.5.0)(vue@3.5.13):
-    resolution: {integrity: sha512-BzT1UW6fe3X+akyNgkWNqeIXZSV2+RX4+IYXmYORh09VNKl+Vd8/oOcYWBqh3XWpy4CYkKC+H484dQmaQU6uHA==}
+  /@quasar/app-vite@2.2.0(@types/node@22.14.0)(eslint@9.24.0)(pinia@2.3.1)(quasar@2.18.1)(sass@1.86.3)(typescript@5.8.3)(vue-router@4.5.0)(vue@3.5.13):
+    resolution: {integrity: sha512-MvCfJrCbxUYvoGaK5jPq0h0hjO8mbxYOWngf+dIKrxhwb+1h5ERh6aVYEUuCtMIwTMEVfPkCez4DIfZIoReuDw==}
     engines: {node: ^30 || ^28 || ^26 || ^24 || ^22 || ^20 || ^18, npm: '>= 6.14.12', yarn: '>= 1.17.3'}
     hasBin: true
     peerDependencies:
@@ -1803,15 +1169,15 @@ packages:
     dependencies:
       '@quasar/render-ssr-error': 1.0.3
       '@quasar/ssl-certificate': 1.0.0
-      '@quasar/vite-plugin': 1.9.0(@vitejs/plugin-vue@5.2.1)(quasar@2.17.7)(vite@6.1.1)(vue@3.5.13)
+      '@quasar/vite-plugin': 1.9.0(@vitejs/plugin-vue@5.2.3)(quasar@2.18.1)(vite@6.2.5)(vue@3.5.13)
       '@types/chrome': 0.0.262
       '@types/compression': 1.7.5
       '@types/cordova': 11.0.3
       '@types/express': 4.17.21
-      '@vitejs/plugin-vue': 5.2.1(vite@6.2.0)(vue@3.5.13)
+      '@vitejs/plugin-vue': 5.2.3(vite@6.2.5)(vue@3.5.13)
       archiver: 7.0.1
       chokidar: 3.6.0
-      ci-info: 4.1.0
+      ci-info: 4.2.0
       compression: 1.8.0
       confbox: 0.1.8
       cross-spawn: 7.0.6
@@ -1819,8 +1185,8 @@ packages:
       dotenv: 16.4.7
       dotenv-expand: 11.0.7
       elementtree: 0.1.7
-      esbuild: 0.24.2
-      eslint: 9.20.1
+      esbuild: 0.25.2
+      eslint: 9.24.0
       express: 4.21.2
       fs-extra: 11.3.0
       html-minifier-terser: 7.2.0
@@ -1829,18 +1195,19 @@ packages:
       kolorist: 1.8.0
       lodash: 4.17.21
       minimist: 1.2.8
+      mlly: 1.7.4
       open: 10.1.0
-      pinia: 2.3.1(typescript@5.7.3)(vue@3.5.13)
-      quasar: 2.17.7
+      pinia: 2.3.1(typescript@5.8.3)(vue@3.5.13)
+      quasar: 2.18.1
       rollup-plugin-visualizer: 5.14.0
-      sass-embedded: 1.85.0
+      sass-embedded: 1.86.3
       semver: 7.7.1
       serialize-javascript: 6.0.2
       tinyglobby: 0.2.12
-      ts-essentials: 9.4.2(typescript@5.7.3)
-      typescript: 5.7.3
-      vite: 6.1.1(@types/node@22.13.5)(sass-embedded@1.85.0)(sass@1.85.0)
-      vue: 3.5.13(typescript@5.7.3)
+      ts-essentials: 9.4.2(typescript@5.8.3)
+      typescript: 5.8.3
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
+      vue: 3.5.13(typescript@5.8.3)
       vue-router: 4.5.0(vue@3.5.13)
       webpack-merge: 6.0.1
     transitivePeerDependencies:
@@ -1859,13 +1226,13 @@ packages:
       - yaml
     dev: true
 
-  /@quasar/cli@2.4.1:
-    resolution: {integrity: sha512-MrOmlqdkQhBxfPMbSrch3O7ClCAc0sLTLp9AWLzdB7uNaLbxcLP6zXN8+EPhDzFfMyxdG7jBP0FKEi7Wh+ezrQ==}
+  /@quasar/cli@2.5.0:
+    resolution: {integrity: sha512-2Vdltr47k7iwjSAYdtpu2ekPdGCmtrKU84wrGMs4taPRsfFyVyRBnxM1jruSvcmk54eA5chwof+ljmrui37AOA==}
     engines: {node: '>= 16', npm: '>= 5.6.0', yarn: '>= 1.6.0'}
     hasBin: true
     dependencies:
       '@quasar/ssl-certificate': 1.0.0
-      ci-info: 4.1.0
+      ci-info: 4.2.0
       compression: 1.8.0
       connect-history-api-fallback: 2.0.0
       cors: 2.8.5
@@ -1895,7 +1262,7 @@ packages:
       '@quasar/quasar-ui-qcalendar': 4.1.2
     dev: true
 
-  /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.6)(quasar@2.17.7)(typescript@5.7.3)(vite@6.2.0)(vitest@0.34.6)(vue@3.5.13):
+  /@quasar/quasar-app-extension-testing-unit-vitest@0.4.0(@vue/test-utils@2.4.6)(quasar@2.18.1)(typescript@5.8.3)(vite@6.2.5)(vitest@3.1.1)(vue@3.5.13):
     resolution: {integrity: sha512-eyzdUdmZiCueNS+5nedjMmzdbpCetSrtdGIwW6KplW1dTzRbLiNvYUjpBOxQGmJCgEhWy9zuswJ7MZ/bTql24Q==}
     engines: {node: '>= 12.22.1', npm: '>= 6.14.12', yarn: '>= 1.17.3'}
     peerDependencies:
@@ -1911,11 +1278,11 @@ packages:
       '@vue/test-utils': 2.4.6
       happy-dom: 11.2.0
       lodash-es: 4.17.21
-      quasar: 2.17.7
-      vite-jsconfig-paths: 2.0.1(vite@6.2.0)
-      vite-tsconfig-paths: 4.3.2(typescript@5.7.3)(vite@6.2.0)
-      vitest: 0.34.6(sass@1.85.0)
-      vue: 3.5.13(typescript@5.7.3)
+      quasar: 2.18.1
+      vite-jsconfig-paths: 2.0.1(vite@6.2.5)
+      vite-tsconfig-paths: 4.3.2(typescript@5.8.3)(vite@6.2.5)
+      vitest: 3.1.1(@types/node@22.14.0)(sass@1.86.3)
+      vue: 3.5.13(typescript@5.8.3)
     transitivePeerDependencies:
       - supports-color
       - typescript
@@ -1940,7 +1307,7 @@ packages:
       fs-extra: 11.3.0
       selfsigned: 2.4.1
 
-  /@quasar/vite-plugin@1.9.0(@vitejs/plugin-vue@5.2.1)(quasar@2.17.7)(vite@6.1.1)(vue@3.5.13):
+  /@quasar/vite-plugin@1.9.0(@vitejs/plugin-vue@5.2.3)(quasar@2.18.1)(vite@6.2.5)(vue@3.5.13):
     resolution: {integrity: sha512-r1MFtI2QZJ2g20pe75Zuv4aoi0uoK8oP0yEdzLWRoOLCbhtf2+StJpUza9TydYi3KcvCl9+4HUf3OAWVKoxDmQ==}
     engines: {node: '>=18'}
     peerDependencies:
@@ -1949,230 +1316,188 @@ packages:
       vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
       vue: ^3.0.0
     dependencies:
-      '@vitejs/plugin-vue': 5.2.1(vite@6.2.0)(vue@3.5.13)
-      quasar: 2.17.7
-      vite: 6.1.1(@types/node@22.13.5)(sass-embedded@1.85.0)(sass@1.85.0)
-      vue: 3.5.13(typescript@5.7.3)
+      '@vitejs/plugin-vue': 5.2.3(vite@6.2.5)(vue@3.5.13)
+      quasar: 2.18.1
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
+      vue: 3.5.13(typescript@5.8.3)
     dev: true
 
-  /@rollup/pluginutils@4.2.1:
-    resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
-    engines: {node: '>= 8.0.0'}
+  /@rollup/pluginutils@5.1.4:
+    resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==}
+    engines: {node: '>=14.0.0'}
+    peerDependencies:
+      rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+    peerDependenciesMeta:
+      rollup:
+        optional: true
     dependencies:
+      '@types/estree': 1.0.7
       estree-walker: 2.0.2
-      picomatch: 2.3.1
+      picomatch: 4.0.2
     dev: true
 
-  /@rollup/rollup-android-arm-eabi@4.34.8:
-    resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==}
+  /@rollup/rollup-android-arm-eabi@4.39.0:
+    resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==}
     cpu: [arm]
     os: [android]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-android-arm64@4.34.8:
-    resolution: {integrity: sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==}
+  /@rollup/rollup-android-arm64@4.39.0:
+    resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==}
     cpu: [arm64]
     os: [android]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-darwin-arm64@4.34.8:
-    resolution: {integrity: sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==}
+  /@rollup/rollup-darwin-arm64@4.39.0:
+    resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==}
     cpu: [arm64]
     os: [darwin]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-darwin-x64@4.34.8:
-    resolution: {integrity: sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==}
+  /@rollup/rollup-darwin-x64@4.39.0:
+    resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==}
     cpu: [x64]
     os: [darwin]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-freebsd-arm64@4.34.8:
-    resolution: {integrity: sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==}
+  /@rollup/rollup-freebsd-arm64@4.39.0:
+    resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==}
     cpu: [arm64]
     os: [freebsd]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-freebsd-x64@4.34.8:
-    resolution: {integrity: sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==}
+  /@rollup/rollup-freebsd-x64@4.39.0:
+    resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==}
     cpu: [x64]
     os: [freebsd]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-arm-gnueabihf@4.34.8:
-    resolution: {integrity: sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==}
+  /@rollup/rollup-linux-arm-gnueabihf@4.39.0:
+    resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==}
     cpu: [arm]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-arm-musleabihf@4.34.8:
-    resolution: {integrity: sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==}
+  /@rollup/rollup-linux-arm-musleabihf@4.39.0:
+    resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==}
     cpu: [arm]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-arm64-gnu@4.34.8:
-    resolution: {integrity: sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==}
+  /@rollup/rollup-linux-arm64-gnu@4.39.0:
+    resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==}
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-arm64-musl@4.34.8:
-    resolution: {integrity: sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==}
+  /@rollup/rollup-linux-arm64-musl@4.39.0:
+    resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==}
     cpu: [arm64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-loongarch64-gnu@4.34.8:
-    resolution: {integrity: sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==}
+  /@rollup/rollup-linux-loongarch64-gnu@4.39.0:
+    resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==}
     cpu: [loong64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-powerpc64le-gnu@4.34.8:
-    resolution: {integrity: sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==}
+  /@rollup/rollup-linux-powerpc64le-gnu@4.39.0:
+    resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==}
     cpu: [ppc64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-riscv64-gnu@4.34.8:
-    resolution: {integrity: sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==}
+  /@rollup/rollup-linux-riscv64-gnu@4.39.0:
+    resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==}
     cpu: [riscv64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-s390x-gnu@4.34.8:
-    resolution: {integrity: sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==}
+  /@rollup/rollup-linux-riscv64-musl@4.39.0:
+    resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==}
+    cpu: [riscv64]
+    os: [linux]
+    requiresBuild: true
+    dev: true
+    optional: true
+
+  /@rollup/rollup-linux-s390x-gnu@4.39.0:
+    resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==}
     cpu: [s390x]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-x64-gnu@4.34.8:
-    resolution: {integrity: sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==}
+  /@rollup/rollup-linux-x64-gnu@4.39.0:
+    resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==}
     cpu: [x64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-linux-x64-musl@4.34.8:
-    resolution: {integrity: sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==}
+  /@rollup/rollup-linux-x64-musl@4.39.0:
+    resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==}
     cpu: [x64]
     os: [linux]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-win32-arm64-msvc@4.34.8:
-    resolution: {integrity: sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==}
+  /@rollup/rollup-win32-arm64-msvc@4.39.0:
+    resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==}
     cpu: [arm64]
     os: [win32]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-win32-ia32-msvc@4.34.8:
-    resolution: {integrity: sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==}
+  /@rollup/rollup-win32-ia32-msvc@4.39.0:
+    resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==}
     cpu: [ia32]
     os: [win32]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@rollup/rollup-win32-x64-msvc@4.34.8:
-    resolution: {integrity: sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==}
+  /@rollup/rollup-win32-x64-msvc@4.39.0:
+    resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==}
     cpu: [x64]
     os: [win32]
     requiresBuild: true
     dev: true
     optional: true
 
-  /@shikijs/core@2.5.0:
-    resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==}
-    dependencies:
-      '@shikijs/engine-javascript': 2.5.0
-      '@shikijs/engine-oniguruma': 2.5.0
-      '@shikijs/types': 2.5.0
-      '@shikijs/vscode-textmate': 10.0.2
-      '@types/hast': 3.0.4
-      hast-util-to-html: 9.0.5
-    dev: true
-
-  /@shikijs/engine-javascript@2.5.0:
-    resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==}
-    dependencies:
-      '@shikijs/types': 2.5.0
-      '@shikijs/vscode-textmate': 10.0.2
-      oniguruma-to-es: 3.1.1
-    dev: true
-
-  /@shikijs/engine-oniguruma@2.5.0:
-    resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==}
-    dependencies:
-      '@shikijs/types': 2.5.0
-      '@shikijs/vscode-textmate': 10.0.2
-    dev: true
-
-  /@shikijs/langs@2.5.0:
-    resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==}
-    dependencies:
-      '@shikijs/types': 2.5.0
-    dev: true
-
-  /@shikijs/themes@2.5.0:
-    resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==}
-    dependencies:
-      '@shikijs/types': 2.5.0
-    dev: true
-
-  /@shikijs/transformers@2.5.0:
-    resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==}
-    dependencies:
-      '@shikijs/core': 2.5.0
-      '@shikijs/types': 2.5.0
-    dev: true
-
-  /@shikijs/types@2.5.0:
-    resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==}
-    dependencies:
-      '@shikijs/vscode-textmate': 10.0.2
-      '@types/hast': 3.0.4
-    dev: true
-
-  /@shikijs/vscode-textmate@10.0.2:
-    resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==}
-    dev: true
-
-  /@sinclair/typebox@0.27.8:
-    resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
+  /@rtsao/scc@1.1.0:
+    resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
     dev: true
 
   /@sindresorhus/is@4.6.0:
@@ -2207,7 +1532,7 @@ packages:
     resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
     dependencies:
       '@types/connect': 3.4.38
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: true
 
   /@types/cacheable-request@6.0.3:
@@ -2215,20 +1540,10 @@ packages:
     dependencies:
       '@types/http-cache-semantics': 4.0.4
       '@types/keyv': 3.1.4
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
       '@types/responselike': 1.0.3
     dev: false
 
-  /@types/chai-subset@1.3.5:
-    resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==}
-    dependencies:
-      '@types/chai': 4.3.20
-    dev: true
-
-  /@types/chai@4.3.20:
-    resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==}
-    dev: true
-
   /@types/chrome@0.0.262:
     resolution: {integrity: sha512-TOoj3dqSYE13PD2fRuMQ6X6pggEvL9rRk/yOYOyWE6sfqRWxsJm4VoVm+wr9pkr4Sht/M5t7FFL4vXato8d1gA==}
     dependencies:
@@ -2245,13 +1560,13 @@ packages:
   /@types/connect@3.4.38:
     resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: true
 
   /@types/conventional-commits-parser@5.0.1:
     resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: true
 
   /@types/cordova@11.0.3:
@@ -2261,17 +1576,17 @@ packages:
   /@types/cors@2.8.17:
     resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==}
     dependencies:
-      '@types/node': 22.13.5
+      '@types/node': 22.14.0
     dev: true
 
-  /@types/estree@1.0.6:
-    resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+  /@types/estree@1.0.7:
+    resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
     dev: true
 
   /@types/express-serve-static-core@4.19.6:
     resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
       '@types/qs': 6.9.18
       '@types/range-parser': 1.2.7
       '@types/send': 0.17.4
@@ -2300,12 +1615,6 @@ packages:
     resolution: {integrity: sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==}
     dev: true
 
-  /@types/hast@3.0.4:
-    resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
-    dependencies:
-      '@types/unist': 3.0.3
-    dev: true
-
   /@types/http-cache-semantics@4.0.4:
     resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==}
     dev: false
@@ -2317,7 +1626,7 @@ packages:
   /@types/http-proxy@1.17.16:
     resolution: {integrity: sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: false
 
   /@types/json-schema@7.0.15:
@@ -2331,30 +1640,9 @@ packages:
   /@types/keyv@3.1.4:
     resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: false
 
-  /@types/linkify-it@5.0.0:
-    resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
-    dev: true
-
-  /@types/markdown-it@14.1.2:
-    resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
-    dependencies:
-      '@types/linkify-it': 5.0.0
-      '@types/mdurl': 2.0.0
-    dev: true
-
-  /@types/mdast@4.0.4:
-    resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
-    dependencies:
-      '@types/unist': 3.0.3
-    dev: true
-
-  /@types/mdurl@2.0.0:
-    resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
-    dev: true
-
   /@types/mime@1.3.5:
     resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
     dev: true
@@ -2362,18 +1650,12 @@ packages:
   /@types/node-forge@1.3.11:
     resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
 
-  /@types/node@22.13.4:
-    resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==}
+  /@types/node@22.14.0:
+    resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==}
     dependencies:
-      undici-types: 6.20.0
-
-  /@types/node@22.13.5:
-    resolution: {integrity: sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==}
-    dependencies:
-      undici-types: 6.20.0
-    dev: true
+      undici-types: 6.21.0
 
   /@types/qs@6.9.18:
     resolution: {integrity: sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==}
@@ -2386,21 +1668,21 @@ packages:
   /@types/responselike@1.0.3:
     resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
     dependencies:
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: false
 
   /@types/send@0.17.4:
     resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==}
     dependencies:
       '@types/mime': 1.3.5
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
     dev: true
 
   /@types/serve-static@1.15.7:
     resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==}
     dependencies:
       '@types/http-errors': 2.0.4
-      '@types/node': 22.13.4
+      '@types/node': 22.14.0
       '@types/send': 0.17.4
     dev: true
 
@@ -2412,24 +1694,16 @@ packages:
     resolution: {integrity: sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==}
     dev: true
 
-  /@types/unist@3.0.3:
-    resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
-    dev: true
-
-  /@types/web-bluetooth@0.0.20:
-    resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
-    dev: true
-
   /@types/yauzl@2.10.3:
     resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
     requiresBuild: true
     dependencies:
-      '@types/node': 22.13.5
+      '@types/node': 22.14.0
     dev: true
     optional: true
 
-  /@uiw/codemirror-extensions-basic-setup@4.23.8(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.3):
-    resolution: {integrity: sha512-XJR/8AEVcE7ufy1BhW2nCN9qSVDYEdCtYLfvhaMwl6Q3qcaYYCGE2K5QbFCy7LsdP/3uZKvc1OskuqatoOPdhQ==}
+  /@uiw/codemirror-extensions-basic-setup@4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.1)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.5):
+    resolution: {integrity: sha512-zpbmSeNs3OU/f/Eyd6brFnjsBUYwv2mFjWxlAsIRSwTlW+skIT60rQHFBSfsj/5UVSxSLWVeUYczN7AyXvgTGQ==}
     peerDependencies:
       '@codemirror/autocomplete': '>=6.0.0'
       '@codemirror/commands': '>=6.0.0'
@@ -2440,16 +1714,16 @@ packages:
       '@codemirror/view': '>=6.0.0'
     dependencies:
       '@codemirror/autocomplete': 6.18.6
-      '@codemirror/commands': 6.8.0
-      '@codemirror/language': 6.10.8
-      '@codemirror/lint': 6.8.4
+      '@codemirror/commands': 6.8.1
+      '@codemirror/language': 6.11.0
+      '@codemirror/lint': 6.8.5
       '@codemirror/search': 6.5.10
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
     dev: true
 
-  /@uiw/react-codemirror@4.23.8(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0):
-    resolution: {integrity: sha512-/NA5Pj4MmXkLSlmlUm4yfEmRLntrNq5TkQKBSINn7TukXQ4fc+C6Bk0U60Qa4rkvCSgwzZdQ2exyP0t0+2GtqA==}
+  /@uiw/react-codemirror@4.23.10(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0):
+    resolution: {integrity: sha512-AbN4eVHOL4ckRuIXpZxkzEqL/1ChVA+BSdEnAKjIB68pLQvKsVoYbiFP8zkXkYc4+Fcgq5KbAjvYqdo4ewemKw==}
     peerDependencies:
       '@babel/runtime': '>=7.11.0'
       '@codemirror/state': '>=6.0.0'
@@ -2459,15 +1733,15 @@ packages:
       react: '>=16.8.0'
       react-dom: '>=16.8.0'
     dependencies:
-      '@babel/runtime': 7.26.9
-      '@codemirror/commands': 6.8.0
+      '@babel/runtime': 7.27.0
+      '@codemirror/commands': 6.8.1
       '@codemirror/state': 6.5.2
       '@codemirror/theme-one-dark': 6.1.2
-      '@codemirror/view': 6.36.3
-      '@uiw/codemirror-extensions-basic-setup': 4.23.8(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.3)
+      '@codemirror/view': 6.36.5
+      '@uiw/codemirror-extensions-basic-setup': 4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.1)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.36.5)
       codemirror: 6.0.1
-      react: 19.0.0
-      react-dom: 19.0.0(react@19.0.0)
+      react: 19.1.0
+      react-dom: 19.1.0(react@19.1.0)
     transitivePeerDependencies:
       - '@codemirror/autocomplete'
       - '@codemirror/language'
@@ -2475,74 +1749,82 @@ packages:
       - '@codemirror/search'
     dev: true
 
-  /@ungap/structured-clone@1.3.0:
-    resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
-    dev: true
-
-  /@vitejs/plugin-vue@5.2.1(vite@5.4.14)(vue@3.5.13):
-    resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
+  /@vitejs/plugin-vue@5.2.3(vite@6.2.5)(vue@3.5.13):
+    resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==}
     engines: {node: ^18.0.0 || >=20.0.0}
     peerDependencies:
       vite: ^5.0.0 || ^6.0.0
       vue: ^3.2.25
     dependencies:
-      vite: 5.4.14(@types/node@22.13.5)(sass@1.85.0)
-      vue: 3.5.13(typescript@5.7.3)
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
+      vue: 3.5.13(typescript@5.8.3)
     dev: true
 
-  /@vitejs/plugin-vue@5.2.1(vite@6.2.0)(vue@3.5.13):
-    resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
-    engines: {node: ^18.0.0 || >=20.0.0}
+  /@vitest/expect@3.1.1:
+    resolution: {integrity: sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==}
+    dependencies:
+      '@vitest/spy': 3.1.1
+      '@vitest/utils': 3.1.1
+      chai: 5.2.0
+      tinyrainbow: 2.0.0
+    dev: true
+
+  /@vitest/mocker@3.1.1(vite@6.2.5):
+    resolution: {integrity: sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==}
     peerDependencies:
+      msw: ^2.4.9
       vite: ^5.0.0 || ^6.0.0
-      vue: ^3.2.25
-    dependencies:
-      vite: 6.2.0(@types/node@22.13.5)(sass@1.85.0)
-      vue: 3.5.13(typescript@5.7.3)
-    dev: true
-
-  /@vitest/expect@0.34.6:
-    resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==}
-    dependencies:
-      '@vitest/spy': 0.34.6
-      '@vitest/utils': 0.34.6
-      chai: 4.5.0
-    dev: true
-
-  /@vitest/runner@0.34.6:
-    resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==}
-    dependencies:
-      '@vitest/utils': 0.34.6
-      p-limit: 4.0.0
-      pathe: 1.1.2
-    dev: true
-
-  /@vitest/snapshot@0.34.6:
-    resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==}
+    peerDependenciesMeta:
+      msw:
+        optional: true
+      vite:
+        optional: true
     dependencies:
+      '@vitest/spy': 3.1.1
+      estree-walker: 3.0.3
       magic-string: 0.30.17
-      pathe: 1.1.2
-      pretty-format: 29.7.0
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
     dev: true
 
-  /@vitest/spy@0.34.6:
-    resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==}
+  /@vitest/pretty-format@3.1.1:
+    resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==}
     dependencies:
-      tinyspy: 2.2.1
+      tinyrainbow: 2.0.0
     dev: true
 
-  /@vitest/utils@0.34.6:
-    resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==}
+  /@vitest/runner@3.1.1:
+    resolution: {integrity: sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==}
     dependencies:
-      diff-sequences: 29.6.3
-      loupe: 2.3.7
-      pretty-format: 29.7.0
+      '@vitest/utils': 3.1.1
+      pathe: 2.0.3
+    dev: true
+
+  /@vitest/snapshot@3.1.1:
+    resolution: {integrity: sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==}
+    dependencies:
+      '@vitest/pretty-format': 3.1.1
+      magic-string: 0.30.17
+      pathe: 2.0.3
+    dev: true
+
+  /@vitest/spy@3.1.1:
+    resolution: {integrity: sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==}
+    dependencies:
+      tinyspy: 3.0.2
+    dev: true
+
+  /@vitest/utils@3.1.1:
+    resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==}
+    dependencies:
+      '@vitest/pretty-format': 3.1.1
+      loupe: 3.1.3
+      tinyrainbow: 2.0.0
     dev: true
 
   /@vue/compiler-core@3.5.13:
     resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
     dependencies:
-      '@babel/parser': 7.26.9
+      '@babel/parser': 7.27.0
       '@vue/shared': 3.5.13
       entities: 4.5.0
       estree-walker: 2.0.2
@@ -2557,7 +1839,7 @@ packages:
   /@vue/compiler-sfc@3.5.13:
     resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==}
     dependencies:
-      '@babel/parser': 7.26.9
+      '@babel/parser': 7.27.0
       '@vue/compiler-core': 3.5.13
       '@vue/compiler-dom': 3.5.13
       '@vue/compiler-ssr': 3.5.13
@@ -2576,30 +1858,6 @@ packages:
   /@vue/devtools-api@6.6.4:
     resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
 
-  /@vue/devtools-api@7.7.2:
-    resolution: {integrity: sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==}
-    dependencies:
-      '@vue/devtools-kit': 7.7.2
-    dev: true
-
-  /@vue/devtools-kit@7.7.2:
-    resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==}
-    dependencies:
-      '@vue/devtools-shared': 7.7.2
-      birpc: 0.2.19
-      hookable: 5.5.3
-      mitt: 3.0.1
-      perfect-debounce: 1.0.0
-      speakingurl: 14.0.1
-      superjson: 2.2.2
-    dev: true
-
-  /@vue/devtools-shared@7.7.2:
-    resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==}
-    dependencies:
-      rfdc: 1.4.1
-    dev: true
-
   /@vue/reactivity@3.5.13:
     resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==}
     dependencies:
@@ -2626,7 +1884,7 @@ packages:
     dependencies:
       '@vue/compiler-ssr': 3.5.13
       '@vue/shared': 3.5.13
-      vue: 3.5.13(typescript@5.7.3)
+      vue: 3.5.13(typescript@5.8.3)
 
   /@vue/shared@3.5.13:
     resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==}
@@ -2634,81 +1892,8 @@ packages:
   /@vue/test-utils@2.4.6:
     resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==}
     dependencies:
-      js-beautify: 1.15.3
-      vue-component-type-helpers: 2.2.2
-    dev: true
-
-  /@vueuse/core@12.7.0(typescript@5.7.3):
-    resolution: {integrity: sha512-jtK5B7YjZXmkGNHjviyGO4s3ZtEhbzSgrbX+s5o+Lr8i2nYqNyHuPVOeTdM1/hZ5Tkxg/KktAuAVDDiHMraMVA==}
-    dependencies:
-      '@types/web-bluetooth': 0.0.20
-      '@vueuse/metadata': 12.7.0
-      '@vueuse/shared': 12.7.0(typescript@5.7.3)
-      vue: 3.5.13(typescript@5.7.3)
-    transitivePeerDependencies:
-      - typescript
-    dev: true
-
-  /@vueuse/integrations@12.7.0(axios@1.7.9)(focus-trap@7.6.4)(typescript@5.7.3):
-    resolution: {integrity: sha512-IEq7K4bCl7mn3uKJaWtNXnd1CAPaHLUMuyj5K1/k/pVcItt0VONZW8xiGxdIovJcQjkzOHjImhX5t6gija+0/g==}
-    peerDependencies:
-      async-validator: ^4
-      axios: ^1
-      change-case: ^5
-      drauu: ^0.4
-      focus-trap: ^7
-      fuse.js: ^7
-      idb-keyval: ^6
-      jwt-decode: ^4
-      nprogress: ^0.2
-      qrcode: ^1.5
-      sortablejs: ^1
-      universal-cookie: ^7
-    peerDependenciesMeta:
-      async-validator:
-        optional: true
-      axios:
-        optional: true
-      change-case:
-        optional: true
-      drauu:
-        optional: true
-      focus-trap:
-        optional: true
-      fuse.js:
-        optional: true
-      idb-keyval:
-        optional: true
-      jwt-decode:
-        optional: true
-      nprogress:
-        optional: true
-      qrcode:
-        optional: true
-      sortablejs:
-        optional: true
-      universal-cookie:
-        optional: true
-    dependencies:
-      '@vueuse/core': 12.7.0(typescript@5.7.3)
-      '@vueuse/shared': 12.7.0(typescript@5.7.3)
-      axios: 1.7.9
-      focus-trap: 7.6.4
-      vue: 3.5.13(typescript@5.7.3)
-    transitivePeerDependencies:
-      - typescript
-    dev: true
-
-  /@vueuse/metadata@12.7.0:
-    resolution: {integrity: sha512-4VvTH9mrjXqFN5LYa5YfqHVRI6j7R00Vy4995Rw7PQxyCL3z0Lli86iN4UemWqixxEvYfRjG+hF9wL8oLOn+3g==}
-    dev: true
-
-  /@vueuse/shared@12.7.0(typescript@5.7.3):
-    resolution: {integrity: sha512-coLlUw2HHKsm7rPN6WqHJQr18WymN4wkA/3ThFaJ4v4gWGWAQQGK+MJxLuJTBs4mojQiazlVWAKNJNpUWGRkNw==}
-    dependencies:
-      vue: 3.5.13(typescript@5.7.3)
-    transitivePeerDependencies:
-      - typescript
+      js-beautify: 1.15.4
+      vue-component-type-helpers: 2.2.8
     dev: true
 
   /JSONStream@1.3.5:
@@ -2719,9 +1904,9 @@ packages:
       through: 2.3.8
     dev: true
 
-  /abbrev@3.0.0:
-    resolution: {integrity: sha512-+/kfrslGQ7TNV2ecmQwMJj/B65g5KVq1/L3SGVZ3tCYGqlzFuFCGBZJtMP99wH3NpEUyAjn0zPdPUg0D+DwrOA==}
-    engines: {node: ^18.17.0 || >=20.5.0}
+  /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
 
   /abort-controller@3.0.0:
@@ -2738,40 +1923,17 @@ packages:
       mime-types: 2.1.35
       negotiator: 0.6.3
 
-  /acorn-jsx@5.3.2(acorn@7.4.1):
+  /acorn-jsx@5.3.2(acorn@8.14.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: 8.14.1
 
-  /acorn-jsx@5.3.2(acorn@8.14.0):
-    resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
-    peerDependencies:
-      acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
-    dependencies:
-      acorn: 8.14.0
-    dev: true
-
-  /acorn-walk@8.3.4:
-    resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
-    engines: {node: '>=0.4.0'}
-    dependencies:
-      acorn: 8.14.0
-    dev: true
-
-  /acorn@7.4.1:
-    resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==}
+  /acorn@8.14.1:
+    resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==}
     engines: {node: '>=0.4.0'}
     hasBin: true
-    dev: true
-
-  /acorn@8.14.0:
-    resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
-    engines: {node: '>=0.4.0'}
-    hasBin: true
-    dev: true
 
   /aggregate-error@3.1.0:
     resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
@@ -2788,7 +1950,6 @@ packages:
       fast-json-stable-stringify: 2.1.0
       json-schema-traverse: 0.4.1
       uri-js: 4.4.1
-    dev: true
 
   /ajv@8.17.1:
     resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
@@ -2799,25 +1960,6 @@ packages:
       require-from-string: 2.0.2
     dev: true
 
-  /algoliasearch@5.20.3:
-    resolution: {integrity: sha512-iNC6BGvipaalFfDfDnXUje8GUlW5asj0cTMsZJwO/0rhsyLx1L7GZFAY8wW+eQ6AM4Yge2p5GSE5hrBlfSD90Q==}
-    engines: {node: '>= 14.0.0'}
-    dependencies:
-      '@algolia/client-abtesting': 5.20.3
-      '@algolia/client-analytics': 5.20.3
-      '@algolia/client-common': 5.20.3
-      '@algolia/client-insights': 5.20.3
-      '@algolia/client-personalization': 5.20.3
-      '@algolia/client-query-suggestions': 5.20.3
-      '@algolia/client-search': 5.20.3
-      '@algolia/ingestion': 1.20.3
-      '@algolia/monitoring': 1.20.3
-      '@algolia/recommend': 5.20.3
-      '@algolia/requester-browser-xhr': 5.20.3
-      '@algolia/requester-fetch': 5.20.3
-      '@algolia/requester-node-http': 5.20.3
-    dev: true
-
   /ansi-align@3.0.1:
     resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
     dependencies:
@@ -2851,11 +1993,6 @@ packages:
       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'}
@@ -2904,6 +2041,13 @@ packages:
 
   /argparse@2.0.1:
     resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+  /array-buffer-byte-length@1.0.2:
+    resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      is-array-buffer: 3.0.5
     dev: true
 
   /array-flatten@1.1.1:
@@ -2913,6 +2057,64 @@ packages:
     resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==}
     dev: true
 
+  /array-includes@3.1.8:
+    resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-object-atoms: 1.1.1
+      get-intrinsic: 1.3.0
+      is-string: 1.1.1
+    dev: true
+
+  /array.prototype.findlastindex@1.2.6:
+    resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-errors: 1.3.0
+      es-object-atoms: 1.1.1
+      es-shim-unscopables: 1.1.0
+    dev: true
+
+  /array.prototype.flat@1.3.3:
+    resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-shim-unscopables: 1.1.0
+    dev: true
+
+  /array.prototype.flatmap@1.3.3:
+    resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-shim-unscopables: 1.1.0
+    dev: true
+
+  /arraybuffer.prototype.slice@1.0.4:
+    resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      array-buffer-byte-length: 1.0.2
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-errors: 1.3.0
+      get-intrinsic: 1.3.0
+      is-array-buffer: 3.0.5
+    dev: true
+
   /asn1@0.2.6:
     resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==}
     dependencies:
@@ -2924,8 +2126,9 @@ packages:
     engines: {node: '>=0.8'}
     dev: true
 
-  /assertion-error@1.1.0:
-    resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
+  /assertion-error@2.0.1:
+    resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+    engines: {node: '>=12'}
     dev: true
 
   /astral-regex@2.0.0:
@@ -2933,6 +2136,11 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /async-function@1.0.0:
+    resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
   /async@3.2.6:
     resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
     dev: true
@@ -2945,15 +2153,15 @@ packages:
     engines: {node: '>= 4.0.0'}
     dev: true
 
-  /autoprefixer@10.4.20(postcss@8.5.3):
-    resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
+  /autoprefixer@10.4.21(postcss@8.5.3):
+    resolution: {integrity: sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==}
     engines: {node: ^10 || ^12 || >=14}
     hasBin: true
     peerDependencies:
       postcss: ^8.1.0
     dependencies:
       browserslist: 4.24.4
-      caniuse-lite: 1.0.30001700
+      caniuse-lite: 1.0.30001712
       fraction.js: 4.3.7
       normalize-range: 0.1.2
       picocolors: 1.1.1
@@ -2961,6 +2169,13 @@ packages:
       postcss-value-parser: 4.2.0
     dev: true
 
+  /available-typed-arrays@1.0.7:
+    resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      possible-typed-array-names: 1.1.0
+    dev: true
+
   /aws-sign2@0.7.0:
     resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
     dev: true
@@ -2969,14 +2184,15 @@ packages:
     resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==}
     dev: true
 
-  /axios@1.7.9:
-    resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
+  /axios@1.8.4:
+    resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==}
     dependencies:
       follow-redirects: 1.15.9
       form-data: 4.0.2
       proxy-from-env: 1.1.0
     transitivePeerDependencies:
       - debug
+    dev: false
 
   /b4a@1.6.7:
     resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==}
@@ -3016,10 +2232,6 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /birpc@0.2.19:
-    resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
-    dev: true
-
   /bl@4.1.0:
     resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
     dependencies:
@@ -3107,10 +2319,10 @@ packages:
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
     dependencies:
-      caniuse-lite: 1.0.30001700
-      electron-to-chromium: 1.5.102
+      caniuse-lite: 1.0.30001712
+      electron-to-chromium: 1.5.132
       node-releases: 2.0.19
-      update-browserslist-db: 1.1.2(browserslist@4.24.4)
+      update-browserslist-db: 1.1.3(browserslist@4.24.4)
     dev: true
 
   /buffer-builder@0.2.0:
@@ -3212,17 +2424,26 @@ packages:
       es-errors: 1.3.0
       function-bind: 1.1.2
 
-  /call-bound@1.0.3:
-    resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==}
+  /call-bind@1.0.8:
+    resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind-apply-helpers: 1.0.2
-      get-intrinsic: 1.2.7
+      es-define-property: 1.0.1
+      get-intrinsic: 1.3.0
+      set-function-length: 1.2.2
+    dev: true
+
+  /call-bound@1.0.4:
+    resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind-apply-helpers: 1.0.2
+      get-intrinsic: 1.3.0
 
   /callsites@3.1.0:
     resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
     engines: {node: '>=6'}
-    dev: true
 
   /camel-case@4.1.2:
     resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
@@ -3246,29 +2467,23 @@ packages:
     engines: {node: '>=14.16'}
     dev: false
 
-  /caniuse-lite@1.0.30001700:
-    resolution: {integrity: sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==}
+  /caniuse-lite@1.0.30001712:
+    resolution: {integrity: sha512-MBqPpGYYdQ7/hfKiet9SCI+nmN5/hp4ZzveOJubl5DTAMa5oggjAuoi0Z4onBpKPFI2ePGnQuQIzF3VxDjDJig==}
     dev: true
 
   /caseless@0.12.0:
     resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
     dev: true
 
-  /ccount@2.0.1:
-    resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
-    dev: true
-
-  /chai@4.5.0:
-    resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==}
-    engines: {node: '>=4'}
+  /chai@5.2.0:
+    resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
+    engines: {node: '>=12'}
     dependencies:
-      assertion-error: 1.1.0
-      check-error: 1.0.3
-      deep-eql: 4.1.4
-      get-func-name: 2.0.2
-      loupe: 2.3.7
-      pathval: 1.1.1
-      type-detect: 4.1.0
+      assertion-error: 2.0.1
+      check-error: 2.1.1
+      deep-eql: 5.0.2
+      loupe: 3.1.3
+      pathval: 2.0.0
     dev: true
 
   /chalk@4.1.2:
@@ -3283,22 +2498,13 @@ packages:
     resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
     engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
 
-  /character-entities-html4@2.1.0:
-    resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
-    dev: true
-
-  /character-entities-legacy@3.0.0:
-    resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
-    dev: true
-
   /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
+  /check-error@2.1.1:
+    resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
+    engines: {node: '>= 16'}
     dev: true
 
   /check-more-types@2.24.0:
@@ -3350,8 +2556,8 @@ packages:
     engines: {node: '>=8'}
     dev: false
 
-  /ci-info@4.1.0:
-    resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==}
+  /ci-info@4.2.0:
+    resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==}
     engines: {node: '>=8'}
 
   /clean-css@5.3.3:
@@ -3446,12 +2652,12 @@ packages:
     resolution: {integrity: sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==}
     dependencies:
       '@codemirror/autocomplete': 6.18.6
-      '@codemirror/commands': 6.8.0
-      '@codemirror/language': 6.10.8
-      '@codemirror/lint': 6.8.4
+      '@codemirror/commands': 6.8.1
+      '@codemirror/language': 6.11.0
+      '@codemirror/lint': 6.8.5
       '@codemirror/search': 6.5.10
       '@codemirror/state': 6.5.2
-      '@codemirror/view': 6.36.3
+      '@codemirror/view': 6.36.5
     dev: true
 
   /color-convert@2.0.1:
@@ -3479,10 +2685,6 @@ packages:
     dependencies:
       delayed-stream: 1.0.0
 
-  /comma-separated-tokens@2.0.3:
-    resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
-    dev: true
-
   /commander@10.0.1:
     resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
     engines: {node: '>=14'}
@@ -3529,7 +2731,7 @@ packages:
     resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
     engines: {node: '>= 0.6'}
     dependencies:
-      mime-db: 1.53.0
+      mime-db: 1.54.0
 
   /compression@1.8.0:
     resolution: {integrity: sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==}
@@ -3636,13 +2838,6 @@ packages:
     engines: {node: '>= 0.6'}
     dev: true
 
-  /copy-anything@3.0.5:
-    resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
-    engines: {node: '>=12.13'}
-    dependencies:
-      is-what: 4.1.16
-    dev: true
-
   /core-util-is@1.0.2:
     resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
     dev: true
@@ -3657,7 +2852,7 @@ packages:
       object-assign: 4.1.1
       vary: 1.1.2
 
-  /cosmiconfig-typescript-loader@6.1.0(@types/node@22.13.5)(cosmiconfig@9.0.0)(typescript@5.7.3):
+  /cosmiconfig-typescript-loader@6.1.0(@types/node@22.14.0)(cosmiconfig@9.0.0)(typescript@5.8.3):
     resolution: {integrity: sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==}
     engines: {node: '>=v18'}
     peerDependencies:
@@ -3665,13 +2860,13 @@ packages:
       cosmiconfig: '>=9'
       typescript: '>=5'
     dependencies:
-      '@types/node': 22.13.5
-      cosmiconfig: 9.0.0(typescript@5.7.3)
+      '@types/node': 22.14.0
+      cosmiconfig: 9.0.0(typescript@5.8.3)
       jiti: 2.4.2
-      typescript: 5.7.3
+      typescript: 5.8.3
     dev: true
 
-  /cosmiconfig@9.0.0(typescript@5.7.3):
+  /cosmiconfig@9.0.0(typescript@5.8.3):
     resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -3684,7 +2879,7 @@ packages:
       import-fresh: 3.3.1
       js-yaml: 4.1.0
       parse-json: 5.2.0
-      typescript: 5.7.3
+      typescript: 5.8.3
     dev: true
 
   /crc-32@1.2.2:
@@ -3737,7 +2932,7 @@ packages:
   /csstype@3.1.3:
     resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
 
-  /cypress-mochawesome-reporter@3.8.2(cypress@14.1.0)(mocha@11.1.0):
+  /cypress-mochawesome-reporter@3.8.2(cypress@14.2.1)(mocha@11.1.0):
     resolution: {integrity: sha512-oJZkNzhNmN9ZD+LmZyFuPb8aWaIijyHyqYh52YOBvR6B6ckfJNCHP3A98a+/nG0H4t46CKTNwo+wNpMa4d2kjA==}
     engines: {node: '>=14'}
     hasBin: true
@@ -3745,7 +2940,7 @@ packages:
       cypress: '>=6.2.0'
     dependencies:
       commander: 10.0.1
-      cypress: 14.1.0
+      cypress: 14.2.1
       fs-extra: 10.1.0
       mochawesome: 7.1.3(mocha@11.1.0)
       mochawesome-merge: 4.4.1
@@ -3754,13 +2949,13 @@ packages:
       - mocha
     dev: true
 
-  /cypress@14.1.0:
-    resolution: {integrity: sha512-pPPj8Uu9NwjaaiXAEcjYZZmgsq6v9Zs1Nw6a+zRF+ANgYSNhH4S32SjFRsvMcuOHR/8dp4GBJhBPqIPSs+TxaA==}
+  /cypress@14.2.1:
+    resolution: {integrity: sha512-5xd0E7fUp0pjjib1D7ljkmCwFDgMkWuW06jWiz8dKrI7MNRrDo0C65i4Sh+oZ9YHjMHZRJBR0XZk1DfekOhOUw==}
     engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
     requiresBuild: true
     dependencies:
-      '@cypress/request': 3.0.7
+      '@cypress/request': 3.0.8
       '@cypress/xvfb': 1.2.4(supports-color@8.1.1)
       '@types/sinonjs__fake-timers': 8.1.1
       '@types/sizzle': 2.3.9
@@ -3771,7 +2966,7 @@ packages:
       cachedir: 2.4.0
       chalk: 4.1.2
       check-more-types: 2.24.0
-      ci-info: 4.1.0
+      ci-info: 4.2.0
       cli-cursor: 3.1.0
       cli-table3: 0.6.5
       commander: 6.2.1
@@ -3817,6 +3012,33 @@ packages:
       assert-plus: 1.0.0
     dev: true
 
+  /data-view-buffer@1.0.2:
+    resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      es-errors: 1.3.0
+      is-data-view: 1.0.2
+    dev: true
+
+  /data-view-byte-length@1.0.2:
+    resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      es-errors: 1.3.0
+      is-data-view: 1.0.2
+    dev: true
+
+  /data-view-byte-offset@1.0.1:
+    resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      es-errors: 1.3.0
+      is-data-view: 1.0.2
+    dev: true
+
   /dateformat@4.6.3:
     resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
     dev: true
@@ -3903,11 +3125,9 @@ packages:
       mimic-response: 3.1.0
     dev: false
 
-  /deep-eql@4.1.4:
-    resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==}
+  /deep-eql@5.0.2:
+    resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
     engines: {node: '>=6'}
-    dependencies:
-      type-detect: 4.1.0
     dev: true
 
   /deep-extend@0.6.0:
@@ -3961,6 +3181,15 @@ packages:
     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.1
+      es-errors: 1.3.0
+      gopd: 1.2.0
+    dev: true
+
   /define-lazy-prop@2.0.0:
     resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
     engines: {node: '>=8'}
@@ -3970,6 +3199,15 @@ packages:
     resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
     engines: {node: '>=12'}
 
+  /define-properties@1.2.1:
+    resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.4
+      has-property-descriptors: 1.0.2
+      object-keys: 1.1.1
+    dev: true
+
   /delayed-stream@1.0.0:
     resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
     engines: {node: '>=0.4.0'}
@@ -3978,11 +3216,6 @@ packages:
     resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
     engines: {node: '>= 0.8'}
 
-  /dequal@2.0.3:
-    resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
-    engines: {node: '>=6'}
-    dev: true
-
   /destroy@1.2.0:
     resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
     engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -4000,22 +3233,18 @@ packages:
     dev: true
     optional: true
 
-  /devlop@1.1.0:
-    resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
-    dependencies:
-      dequal: 2.0.3
-    dev: true
-
-  /diff-sequences@29.6.3:
-    resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dev: true
-
   /diff@5.2.0:
     resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
     engines: {node: '>=0.3.1'}
     dev: true
 
+  /doctrine@2.1.0:
+    resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
+    engines: {node: '>=0.10.0'}
+    dependencies:
+      esutils: 2.0.3
+    dev: true
+
   /dot-case@3.0.4:
     resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==}
     dependencies:
@@ -4041,7 +3270,7 @@ packages:
     resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==}
     engines: {node: '>=18'}
     dependencies:
-      type-fest: 4.35.0
+      type-fest: 4.39.1
     dev: true
 
   /dotenv-expand@11.0.7:
@@ -4088,8 +3317,8 @@ packages:
   /ee-first@1.1.1:
     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
 
-  /electron-to-chromium@1.5.102:
-    resolution: {integrity: sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==}
+  /electron-to-chromium@1.5.132:
+    resolution: {integrity: sha512-QgX9EBvWGmvSRa74zqfnG7+Eno0Ak0vftBll0Pt2/z5b3bEGYL6OUXLgKPtvx73dn3dvwrlyVkjPKRRlhLYTEg==}
     dev: true
 
   /elementtree@0.1.7:
@@ -4099,10 +3328,6 @@ packages:
       sax: 1.1.4
     dev: true
 
-  /emoji-regex-xs@1.0.0:
-    resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==}
-    dev: true
-
   /emoji-regex@8.0.0:
     resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
 
@@ -4132,7 +3357,7 @@ packages:
     engines: {node: '>=10.2.0'}
     dependencies:
       '@types/cors': 2.8.17
-      '@types/node': 22.13.5
+      '@types/node': 22.14.0
       accepts: 1.3.8
       base64id: 2.0.0
       cookie: 0.7.2
@@ -4169,6 +3394,63 @@ packages:
       is-arrayish: 0.2.1
     dev: true
 
+  /es-abstract@1.23.9:
+    resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      array-buffer-byte-length: 1.0.2
+      arraybuffer.prototype.slice: 1.0.4
+      available-typed-arrays: 1.0.7
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      data-view-buffer: 1.0.2
+      data-view-byte-length: 1.0.2
+      data-view-byte-offset: 1.0.1
+      es-define-property: 1.0.1
+      es-errors: 1.3.0
+      es-object-atoms: 1.1.1
+      es-set-tostringtag: 2.1.0
+      es-to-primitive: 1.3.0
+      function.prototype.name: 1.1.8
+      get-intrinsic: 1.3.0
+      get-proto: 1.0.1
+      get-symbol-description: 1.1.0
+      globalthis: 1.0.4
+      gopd: 1.2.0
+      has-property-descriptors: 1.0.2
+      has-proto: 1.2.0
+      has-symbols: 1.1.0
+      hasown: 2.0.2
+      internal-slot: 1.1.0
+      is-array-buffer: 3.0.5
+      is-callable: 1.2.7
+      is-data-view: 1.0.2
+      is-regex: 1.2.1
+      is-shared-array-buffer: 1.0.4
+      is-string: 1.1.1
+      is-typed-array: 1.1.15
+      is-weakref: 1.1.1
+      math-intrinsics: 1.1.0
+      object-inspect: 1.13.4
+      object-keys: 1.1.1
+      object.assign: 4.1.7
+      own-keys: 1.0.1
+      regexp.prototype.flags: 1.5.4
+      safe-array-concat: 1.1.3
+      safe-push-apply: 1.0.0
+      safe-regex-test: 1.1.0
+      set-proto: 1.0.0
+      string.prototype.trim: 1.2.10
+      string.prototype.trimend: 1.0.9
+      string.prototype.trimstart: 1.0.8
+      typed-array-buffer: 1.0.3
+      typed-array-byte-length: 1.0.3
+      typed-array-byte-offset: 1.0.4
+      typed-array-length: 1.0.7
+      unbox-primitive: 1.1.0
+      which-typed-array: 1.1.19
+    dev: true
+
   /es-define-property@1.0.1:
     resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
     engines: {node: '>= 0.4'}
@@ -4177,6 +3459,9 @@ packages:
     resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
     engines: {node: '>= 0.4'}
 
+  /es-module-lexer@1.6.0:
+    resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==}
+
   /es-object-atoms@1.1.1:
     resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
     engines: {node: '>= 0.4'}
@@ -4188,105 +3473,57 @@ packages:
     engines: {node: '>= 0.4'}
     dependencies:
       es-errors: 1.3.0
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       has-tostringtag: 1.0.2
       hasown: 2.0.2
 
-  /esbuild@0.21.5:
-    resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
-    engines: {node: '>=12'}
-    hasBin: true
-    requiresBuild: true
-    optionalDependencies:
-      '@esbuild/aix-ppc64': 0.21.5
-      '@esbuild/android-arm': 0.21.5
-      '@esbuild/android-arm64': 0.21.5
-      '@esbuild/android-x64': 0.21.5
-      '@esbuild/darwin-arm64': 0.21.5
-      '@esbuild/darwin-x64': 0.21.5
-      '@esbuild/freebsd-arm64': 0.21.5
-      '@esbuild/freebsd-x64': 0.21.5
-      '@esbuild/linux-arm': 0.21.5
-      '@esbuild/linux-arm64': 0.21.5
-      '@esbuild/linux-ia32': 0.21.5
-      '@esbuild/linux-loong64': 0.21.5
-      '@esbuild/linux-mips64el': 0.21.5
-      '@esbuild/linux-ppc64': 0.21.5
-      '@esbuild/linux-riscv64': 0.21.5
-      '@esbuild/linux-s390x': 0.21.5
-      '@esbuild/linux-x64': 0.21.5
-      '@esbuild/netbsd-x64': 0.21.5
-      '@esbuild/openbsd-x64': 0.21.5
-      '@esbuild/sunos-x64': 0.21.5
-      '@esbuild/win32-arm64': 0.21.5
-      '@esbuild/win32-ia32': 0.21.5
-      '@esbuild/win32-x64': 0.21.5
+  /es-shim-unscopables@1.1.0:
+    resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      hasown: 2.0.2
     dev: true
 
-  /esbuild@0.24.2:
-    resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
+  /es-to-primitive@1.3.0:
+    resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-callable: 1.2.7
+      is-date-object: 1.1.0
+      is-symbol: 1.1.1
+    dev: true
+
+  /esbuild@0.25.2:
+    resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==}
     engines: {node: '>=18'}
     hasBin: true
     requiresBuild: true
     optionalDependencies:
-      '@esbuild/aix-ppc64': 0.24.2
-      '@esbuild/android-arm': 0.24.2
-      '@esbuild/android-arm64': 0.24.2
-      '@esbuild/android-x64': 0.24.2
-      '@esbuild/darwin-arm64': 0.24.2
-      '@esbuild/darwin-x64': 0.24.2
-      '@esbuild/freebsd-arm64': 0.24.2
-      '@esbuild/freebsd-x64': 0.24.2
-      '@esbuild/linux-arm': 0.24.2
-      '@esbuild/linux-arm64': 0.24.2
-      '@esbuild/linux-ia32': 0.24.2
-      '@esbuild/linux-loong64': 0.24.2
-      '@esbuild/linux-mips64el': 0.24.2
-      '@esbuild/linux-ppc64': 0.24.2
-      '@esbuild/linux-riscv64': 0.24.2
-      '@esbuild/linux-s390x': 0.24.2
-      '@esbuild/linux-x64': 0.24.2
-      '@esbuild/netbsd-arm64': 0.24.2
-      '@esbuild/netbsd-x64': 0.24.2
-      '@esbuild/openbsd-arm64': 0.24.2
-      '@esbuild/openbsd-x64': 0.24.2
-      '@esbuild/sunos-x64': 0.24.2
-      '@esbuild/win32-arm64': 0.24.2
-      '@esbuild/win32-ia32': 0.24.2
-      '@esbuild/win32-x64': 0.24.2
-    dev: true
-
-  /esbuild@0.25.0:
-    resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==}
-    engines: {node: '>=18'}
-    hasBin: true
-    requiresBuild: true
-    optionalDependencies:
-      '@esbuild/aix-ppc64': 0.25.0
-      '@esbuild/android-arm': 0.25.0
-      '@esbuild/android-arm64': 0.25.0
-      '@esbuild/android-x64': 0.25.0
-      '@esbuild/darwin-arm64': 0.25.0
-      '@esbuild/darwin-x64': 0.25.0
-      '@esbuild/freebsd-arm64': 0.25.0
-      '@esbuild/freebsd-x64': 0.25.0
-      '@esbuild/linux-arm': 0.25.0
-      '@esbuild/linux-arm64': 0.25.0
-      '@esbuild/linux-ia32': 0.25.0
-      '@esbuild/linux-loong64': 0.25.0
-      '@esbuild/linux-mips64el': 0.25.0
-      '@esbuild/linux-ppc64': 0.25.0
-      '@esbuild/linux-riscv64': 0.25.0
-      '@esbuild/linux-s390x': 0.25.0
-      '@esbuild/linux-x64': 0.25.0
-      '@esbuild/netbsd-arm64': 0.25.0
-      '@esbuild/netbsd-x64': 0.25.0
-      '@esbuild/openbsd-arm64': 0.25.0
-      '@esbuild/openbsd-x64': 0.25.0
-      '@esbuild/sunos-x64': 0.25.0
-      '@esbuild/win32-arm64': 0.25.0
-      '@esbuild/win32-ia32': 0.25.0
-      '@esbuild/win32-x64': 0.25.0
+      '@esbuild/aix-ppc64': 0.25.2
+      '@esbuild/android-arm': 0.25.2
+      '@esbuild/android-arm64': 0.25.2
+      '@esbuild/android-x64': 0.25.2
+      '@esbuild/darwin-arm64': 0.25.2
+      '@esbuild/darwin-x64': 0.25.2
+      '@esbuild/freebsd-arm64': 0.25.2
+      '@esbuild/freebsd-x64': 0.25.2
+      '@esbuild/linux-arm': 0.25.2
+      '@esbuild/linux-arm64': 0.25.2
+      '@esbuild/linux-ia32': 0.25.2
+      '@esbuild/linux-loong64': 0.25.2
+      '@esbuild/linux-mips64el': 0.25.2
+      '@esbuild/linux-ppc64': 0.25.2
+      '@esbuild/linux-riscv64': 0.25.2
+      '@esbuild/linux-s390x': 0.25.2
+      '@esbuild/linux-x64': 0.25.2
+      '@esbuild/netbsd-arm64': 0.25.2
+      '@esbuild/netbsd-x64': 0.25.2
+      '@esbuild/openbsd-arm64': 0.25.2
+      '@esbuild/openbsd-x64': 0.25.2
+      '@esbuild/sunos-x64': 0.25.2
+      '@esbuild/win32-arm64': 0.25.2
+      '@esbuild/win32-ia32': 0.25.2
+      '@esbuild/win32-x64': 0.25.2
     dev: true
 
   /escalade@3.2.0:
@@ -4312,38 +3549,133 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /eslint-config-prettier@10.0.1(eslint@9.20.1):
-    resolution: {integrity: sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==}
+  /escodegen@2.1.0:
+    resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
+    engines: {node: '>=6.0'}
+    hasBin: true
+    dependencies:
+      esprima: 4.0.1
+      estraverse: 5.3.0
+      esutils: 2.0.3
+    optionalDependencies:
+      source-map: 0.6.1
+    dev: true
+
+  /eslint-config-prettier@10.1.1(eslint@9.24.0):
+    resolution: {integrity: sha512-4EQQr6wXwS+ZJSzaR5ZCrYgLxqvUjdXctaEtBqHcbkW944B1NQyO4qpdHQbXBONfwxXdkAY81HH4+LUfrg+zPw==}
     hasBin: true
     peerDependencies:
       eslint: '>=7.0.0'
     dependencies:
-      eslint: 9.20.1
+      eslint: 9.24.0
     dev: true
 
-  /eslint-plugin-cypress@4.1.0(eslint@9.20.1):
-    resolution: {integrity: sha512-JhqkMY02mw74USwK9OFhectx3YSj6Co1NgWBxlGdKvlqiAp9vdEuQqt33DKGQFvvGS/NWtduuhWXWNnU29xDSg==}
+  /eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.31.0):
+    resolution: {integrity: sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w==}
+    engines: {node: '>= 4'}
+    peerDependencies:
+      eslint-plugin-import: '>=1.4.0'
+    dependencies:
+      eslint-plugin-import: 2.31.0(eslint@9.24.0)
+    dev: true
+
+  /eslint-import-resolver-node@0.3.9:
+    resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
+    dependencies:
+      debug: 3.2.7(supports-color@8.1.1)
+      is-core-module: 2.16.1
+      resolve: 1.22.10
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /eslint-module-utils@2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.24.0):
+    resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@typescript-eslint/parser': '*'
+      eslint: '*'
+      eslint-import-resolver-node: '*'
+      eslint-import-resolver-typescript: '*'
+      eslint-import-resolver-webpack: '*'
+    peerDependenciesMeta:
+      '@typescript-eslint/parser':
+        optional: true
+      eslint:
+        optional: true
+      eslint-import-resolver-node:
+        optional: true
+      eslint-import-resolver-typescript:
+        optional: true
+      eslint-import-resolver-webpack:
+        optional: true
+    dependencies:
+      debug: 3.2.7(supports-color@8.1.1)
+      eslint: 9.24.0
+      eslint-import-resolver-node: 0.3.9
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /eslint-plugin-cypress@4.2.0(eslint@9.24.0):
+    resolution: {integrity: sha512-v5cyt0VYb1tEEODBJSE44PocYOwQsckyexJhCs7LtdD3FGO6D2GjnZB2s2Sts4RcxdxECTWX01nObOZRs26bQw==}
     peerDependencies:
       eslint: '>=9'
     dependencies:
-      eslint: 9.20.1
+      eslint: 9.24.0
       globals: 15.15.0
     dev: true
 
-  /eslint-plugin-vue@9.32.0(eslint@9.20.1):
-    resolution: {integrity: sha512-b/Y05HYmnB/32wqVcjxjHZzNpwxj1onBOvqW89W+V+XNG1dRuaFbNd3vT9CLbr2LXjEoq+3vn8DanWf7XU22Ug==}
+  /eslint-plugin-import@2.31.0(eslint@9.24.0):
+    resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==}
+    engines: {node: '>=4'}
+    peerDependencies:
+      '@typescript-eslint/parser': '*'
+      eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9
+    peerDependenciesMeta:
+      '@typescript-eslint/parser':
+        optional: true
+    dependencies:
+      '@rtsao/scc': 1.1.0
+      array-includes: 3.1.8
+      array.prototype.findlastindex: 1.2.6
+      array.prototype.flat: 1.3.3
+      array.prototype.flatmap: 1.3.3
+      debug: 3.2.7(supports-color@8.1.1)
+      doctrine: 2.1.0
+      eslint: 9.24.0
+      eslint-import-resolver-node: 0.3.9
+      eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.24.0)
+      hasown: 2.0.2
+      is-core-module: 2.16.1
+      is-glob: 4.0.3
+      minimatch: 3.1.2
+      object.fromentries: 2.0.8
+      object.groupby: 1.0.3
+      object.values: 1.2.1
+      semver: 6.3.1
+      string.prototype.trimend: 1.0.9
+      tsconfig-paths: 3.15.0
+    transitivePeerDependencies:
+      - eslint-import-resolver-typescript
+      - eslint-import-resolver-webpack
+      - supports-color
+    dev: true
+
+  /eslint-plugin-vue@9.33.0(eslint@9.24.0):
+    resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.1(eslint@9.20.1)
-      eslint: 9.20.1
+      '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0)
+      eslint: 9.24.0
       globals: 13.24.0
       natural-compare: 1.4.0
       nth-check: 2.1.1
       postcss-selector-parser: 6.1.2
       semver: 7.7.1
-      vue-eslint-parser: 9.4.3(eslint@9.20.1)
+      vue-eslint-parser: 9.4.3(eslint@9.24.0)
       xml-name-validator: 4.0.0
     transitivePeerDependencies:
       - supports-color
@@ -4357,26 +3689,14 @@ packages:
       estraverse: 5.3.0
     dev: true
 
-  /eslint-scope@8.2.0:
-    resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==}
+  /eslint-scope@8.3.0:
+    resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.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}
@@ -4385,10 +3705,9 @@ packages:
   /eslint-visitor-keys@4.2.0:
     resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
-    dev: true
 
-  /eslint@9.20.1:
-    resolution: {integrity: sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==}
+  /eslint@9.24.0:
+    resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     hasBin: true
     peerDependencies:
@@ -4397,24 +3716,25 @@ packages:
       jiti:
         optional: true
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.1(eslint@9.20.1)
+      '@eslint-community/eslint-utils': 4.5.1(eslint@9.24.0)
       '@eslint-community/regexpp': 4.12.1
-      '@eslint/config-array': 0.19.2
-      '@eslint/core': 0.11.0
-      '@eslint/eslintrc': 3.2.0
-      '@eslint/js': 9.20.0
-      '@eslint/plugin-kit': 0.2.6
+      '@eslint/config-array': 0.20.0
+      '@eslint/config-helpers': 0.2.1
+      '@eslint/core': 0.12.0
+      '@eslint/eslintrc': 3.3.1
+      '@eslint/js': 9.24.0
+      '@eslint/plugin-kit': 0.2.8
       '@humanfs/node': 0.16.6
       '@humanwhocodes/module-importer': 1.0.1
       '@humanwhocodes/retry': 0.4.2
-      '@types/estree': 1.0.6
+      '@types/estree': 1.0.7
       '@types/json-schema': 7.0.15
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.6
       debug: 4.4.0(supports-color@8.1.1)
       escape-string-regexp: 4.0.0
-      eslint-scope: 8.2.0
+      eslint-scope: 8.3.0
       eslint-visitor-keys: 4.2.0
       espree: 10.3.0
       esquery: 1.6.0
@@ -4439,29 +3759,25 @@ packages:
     resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     dependencies:
-      acorn: 8.14.0
-      acorn-jsx: 5.3.2(acorn@8.14.0)
+      acorn: 8.14.1
+      acorn-jsx: 5.3.2(acorn@8.14.1)
       eslint-visitor-keys: 4.2.0
-    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.14.0
-      acorn-jsx: 5.3.2(acorn@8.14.0)
+      acorn: 8.14.1
+      acorn-jsx: 5.3.2(acorn@8.14.1)
       eslint-visitor-keys: 3.4.3
     dev: true
 
+  /esprima@4.0.1:
+    resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+    engines: {node: '>=4'}
+    hasBin: true
+    dev: true
+
   /esquery@1.6.0:
     resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
     engines: {node: '>=0.10'}
@@ -4484,6 +3800,12 @@ packages:
   /estree-walker@2.0.2:
     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
 
+  /estree-walker@3.0.3:
+    resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+    dependencies:
+      '@types/estree': 1.0.7
+    dev: true
+
   /esutils@2.0.3:
     resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
     engines: {node: '>=0.10.0'}
@@ -4563,6 +3885,11 @@ packages:
       pify: 2.3.0
     dev: true
 
+  /expect-type@1.2.1:
+    resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
+    engines: {node: '>=12.0.0'}
+    dev: true
+
   /express@4.21.2:
     resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==}
     engines: {node: '>= 0.10.0'}
@@ -4647,7 +3974,6 @@ packages:
 
   /fast-deep-equal@3.1.3:
     resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
-    dev: true
 
   /fast-fifo@1.3.2:
     resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
@@ -4662,11 +3988,9 @@ packages:
       glob-parent: 5.1.2
       merge2: 1.4.1
       micromatch: 4.0.8
-    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==}
@@ -4676,11 +4000,10 @@ packages:
     resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==}
     dev: true
 
-  /fastq@1.19.0:
-    resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==}
+  /fastq@1.19.1:
+    resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==}
     dependencies:
-      reusify: 1.0.4
-    dev: true
+      reusify: 1.1.0
 
   /fd-slicer@1.1.0:
     resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
@@ -4774,12 +4097,6 @@ packages:
     resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
     dev: true
 
-  /focus-trap@7.6.4:
-    resolution: {integrity: sha512-xx560wGBk7seZ6y933idtjJQc1l+ck+pI3sKvhKozdBV1dRZoKhkW5xoCaFv9tQiX5RH1xfSxjuNu6g+lmN/gw==}
-    dependencies:
-      tabbable: 6.2.0
-    dev: true
-
   /follow-redirects@1.15.9:
     resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
     engines: {node: '>=4.0'}
@@ -4788,9 +4105,17 @@ packages:
     peerDependenciesMeta:
       debug:
         optional: true
+    dev: false
 
-  /foreground-child@3.3.0:
-    resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+  /for-each@0.3.5:
+    resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-callable: 1.2.7
+    dev: true
+
+  /foreground-child@3.3.1:
+    resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
     engines: {node: '>=14'}
     dependencies:
       cross-spawn: 7.0.6
@@ -4885,17 +4210,29 @@ packages:
   /function-bind@1.1.2:
     resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
 
+  /function.prototype.name@1.1.8:
+    resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      define-properties: 1.2.1
+      functions-have-names: 1.2.3
+      hasown: 2.0.2
+      is-callable: 1.2.7
+    dev: true
+
+  /functions-have-names@1.2.3:
+    resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
+    dev: true
+
   /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.7:
-    resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==}
+  /get-intrinsic@1.3.0:
+    resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
     engines: {node: '>= 0.4'}
     dependencies:
       call-bind-apply-helpers: 1.0.2
@@ -4932,6 +4269,15 @@ packages:
     engines: {node: '>=10'}
     dev: false
 
+  /get-symbol-description@1.1.0:
+    resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      es-errors: 1.3.0
+      get-intrinsic: 1.3.0
+    dev: true
+
   /getos@3.2.1:
     resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==}
     dependencies:
@@ -4959,7 +4305,6 @@ packages:
     engines: {node: '>= 6'}
     dependencies:
       is-glob: 4.0.3
-    dev: true
 
   /glob-parent@6.0.2:
     resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
@@ -4976,7 +4321,7 @@ packages:
     resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
     hasBin: true
     dependencies:
-      foreground-child: 3.3.0
+      foreground-child: 3.3.1
       jackspeak: 3.4.3
       minimatch: 9.0.5
       minipass: 7.1.2
@@ -5018,13 +4363,25 @@ packages:
   /globals@14.0.0:
     resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
     engines: {node: '>=18'}
-    dev: true
 
   /globals@15.15.0:
     resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==}
     engines: {node: '>=18'}
     dev: true
 
+  /globals@16.0.0:
+    resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==}
+    engines: {node: '>=18'}
+    dev: true
+
+  /globalthis@1.0.4:
+    resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-properties: 1.2.1
+      gopd: 1.2.0
+    dev: true
+
   /globrex@0.1.2:
     resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==}
     dev: true
@@ -5098,10 +4455,28 @@ packages:
       whatwg-mimetype: 3.0.0
     dev: true
 
+  /has-bigints@1.1.0:
+    resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
+    engines: {node: '>= 0.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.1
+    dev: true
+
+  /has-proto@1.2.0:
+    resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      dunder-proto: 1.0.1
+    dev: true
+
   /has-symbols@1.1.0:
     resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
     engines: {node: '>= 0.4'}
@@ -5123,37 +4498,11 @@ packages:
     dependencies:
       function-bind: 1.1.2
 
-  /hast-util-to-html@9.0.5:
-    resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==}
-    dependencies:
-      '@types/hast': 3.0.4
-      '@types/unist': 3.0.3
-      ccount: 2.0.1
-      comma-separated-tokens: 2.0.3
-      hast-util-whitespace: 3.0.0
-      html-void-elements: 3.0.0
-      mdast-util-to-hast: 13.2.0
-      property-information: 7.0.0
-      space-separated-tokens: 2.0.2
-      stringify-entities: 4.0.4
-      zwitch: 2.0.4
-    dev: true
-
-  /hast-util-whitespace@3.0.0:
-    resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
-    dependencies:
-      '@types/hast': 3.0.4
-    dev: true
-
   /he@1.2.0:
     resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
     hasBin: true
     dev: true
 
-  /hookable@5.5.3:
-    resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
-    dev: true
-
   /html-minifier-terser@7.2.0:
     resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==}
     engines: {node: ^14.13.1 || >=16.0.0}
@@ -5168,10 +4517,6 @@ packages:
       terser: 5.39.0
     dev: true
 
-  /html-void-elements@3.0.0:
-    resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
-    dev: true
-
   /http-cache-semantics@4.1.1:
     resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
     dev: false
@@ -5281,10 +4626,9 @@ packages:
   /ignore@5.3.2:
     resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
     engines: {node: '>= 4'}
-    dev: true
 
-  /immutable@5.0.3:
-    resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==}
+  /immutable@5.1.1:
+    resolution: {integrity: sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==}
     dev: true
 
   /import-fresh@3.3.1:
@@ -5293,7 +4637,6 @@ packages:
     dependencies:
       parent-module: 1.0.1
       resolve-from: 4.0.0
-    dev: true
 
   /import-lazy@4.0.0:
     resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
@@ -5339,20 +4682,29 @@ packages:
     resolution: {integrity: sha512-LJKFHCSeIRq9hanN14IlOtPSTe3lNES7TYDTE2xxdAy1LS5rYphajK1qtwvj3YmQXvvk0U2Vbmcni8P9EIQW9w==}
     engines: {node: '>=18'}
     dependencies:
-      '@inquirer/figures': 1.0.10
+      '@inquirer/figures': 1.0.11
       ansi-escapes: 4.3.2
       cli-width: 4.1.0
       external-editor: 3.1.0
       mute-stream: 1.0.0
       ora: 5.4.1
       run-async: 3.0.0
-      rxjs: 7.8.1
+      rxjs: 7.8.2
       string-width: 4.2.3
       strip-ansi: 6.0.1
       wrap-ansi: 6.2.0
       yoctocolors-cjs: 2.1.2
     dev: true
 
+  /internal-slot@1.1.0:
+    resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-errors: 1.3.0
+      hasown: 2.0.2
+      side-channel: 1.1.0
+    dev: true
+
   /ip@1.1.9:
     resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==}
     dev: true
@@ -5361,10 +4713,37 @@ packages:
     resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
     engines: {node: '>= 0.10'}
 
+  /is-array-buffer@3.0.5:
+    resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      get-intrinsic: 1.3.0
+    dev: true
+
   /is-arrayish@0.2.1:
     resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
     dev: true
 
+  /is-async-function@2.1.1:
+    resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      async-function: 1.0.0
+      call-bound: 1.0.4
+      get-proto: 1.0.1
+      has-tostringtag: 1.0.2
+      safe-regex-test: 1.1.0
+    dev: true
+
+  /is-bigint@1.1.0:
+    resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      has-bigints: 1.1.0
+    dev: true
+
   /is-binary-path@2.1.0:
     resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
     engines: {node: '>=8'}
@@ -5372,6 +4751,19 @@ packages:
       binary-extensions: 2.3.0
     dev: true
 
+  /is-boolean-object@1.2.2:
+    resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-callable@1.2.7:
+    resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
   /is-ci@3.0.1:
     resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
     hasBin: true
@@ -5379,6 +4771,30 @@ packages:
       ci-info: 3.9.0
     dev: false
 
+  /is-core-module@2.16.1:
+    resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      hasown: 2.0.2
+    dev: true
+
+  /is-data-view@1.0.2:
+    resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      get-intrinsic: 1.3.0
+      is-typed-array: 1.1.15
+    dev: true
+
+  /is-date-object@1.1.0:
+    resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      has-tostringtag: 1.0.2
+    dev: true
+
   /is-docker@2.2.1:
     resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
     engines: {node: '>=8'}
@@ -5393,10 +4809,27 @@ packages:
     resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
     engines: {node: '>=0.10.0'}
 
+  /is-finalizationregistry@1.1.1:
+    resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+    dev: true
+
   /is-fullwidth-code-point@3.0.0:
     resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
     engines: {node: '>=8'}
 
+  /is-generator-function@1.1.0:
+    resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      get-proto: 1.0.1
+      has-tostringtag: 1.0.2
+      safe-regex-test: 1.1.0
+    dev: true
+
   /is-glob@4.0.3:
     resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
     engines: {node: '>=0.10.0'}
@@ -5422,11 +4855,24 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /is-map@2.0.3:
+    resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
+    engines: {node: '>= 0.4'}
+    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-object@1.1.1:
+    resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      has-tostringtag: 1.0.2
+    dev: true
+
   /is-number@7.0.0:
     resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
     engines: {node: '>=0.12.0'}
@@ -5456,6 +4902,28 @@ packages:
       isobject: 3.0.1
     dev: true
 
+  /is-regex@1.2.1:
+    resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      gopd: 1.2.0
+      has-tostringtag: 1.0.2
+      hasown: 2.0.2
+    dev: true
+
+  /is-set@2.0.3:
+    resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /is-shared-array-buffer@1.0.4:
+    resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+    dev: true
+
   /is-stream@2.0.1:
     resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
     engines: {node: '>=8'}
@@ -5465,6 +4933,23 @@ packages:
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     dev: false
 
+  /is-string@1.1.1:
+    resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      has-tostringtag: 1.0.2
+    dev: true
+
+  /is-symbol@1.1.1:
+    resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      has-symbols: 1.1.0
+      safe-regex-test: 1.1.0
+    dev: true
+
   /is-text-path@2.0.0:
     resolution: {integrity: sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==}
     engines: {node: '>=8'}
@@ -5472,6 +4957,13 @@ packages:
       text-extensions: 2.4.0
     dev: true
 
+  /is-typed-array@1.1.15:
+    resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      which-typed-array: 1.1.19
+    dev: true
+
   /is-typedarray@1.0.0:
     resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
 
@@ -5480,9 +4972,24 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /is-what@4.1.16:
-    resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
-    engines: {node: '>=12.13'}
+  /is-weakmap@2.0.2:
+    resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /is-weakref@1.1.1:
+    resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+    dev: true
+
+  /is-weakset@2.0.4:
+    resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      get-intrinsic: 1.3.0
     dev: true
 
   /is-wsl@2.2.0:
@@ -5506,6 +5013,10 @@ packages:
   /isarray@1.0.0:
     resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
 
+  /isarray@2.0.5:
+    resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
+    dev: true
+
   /isbinaryfile@5.0.4:
     resolution: {integrity: sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==}
     engines: {node: '>= 18.0.0'}
@@ -5536,8 +5047,8 @@ packages:
     hasBin: true
     dev: true
 
-  /js-beautify@1.15.3:
-    resolution: {integrity: sha512-rKKGuyTxGNlyN4EQKWzNndzXpi0bOl8Gl8YQAW1as/oMz0XhD6sHJO1hTvoBDOSzKuJb9WkwoAb34FfdkKMv2A==}
+  /js-beautify@1.15.4:
+    resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
     engines: {node: '>=14'}
     hasBin: true
     dependencies:
@@ -5545,7 +5056,7 @@ packages:
       editorconfig: 1.0.4
       glob: 10.4.5
       js-cookie: 3.0.5
-      nopt: 8.1.0
+      nopt: 7.2.1
     dev: true
 
   /js-cookie@3.0.5:
@@ -5562,7 +5073,6 @@ packages:
     hasBin: true
     dependencies:
       argparse: 2.0.1
-    dev: true
 
   /jsbn@0.1.1:
     resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==}
@@ -5577,7 +5087,6 @@ packages:
 
   /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==}
@@ -5608,15 +5117,14 @@ packages:
     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'}
+  /jsonc-eslint-parser@2.4.0:
+    resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==}
+    engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.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
+      acorn: 8.14.1
+      eslint-visitor-keys: 3.4.3
+      espree: 9.6.1
+      semver: 7.7.1
     dev: true
 
   /jsonfile@4.0.0:
@@ -5716,16 +5224,11 @@ packages:
       log-update: 4.0.0
       p-map: 4.0.0
       rfdc: 1.4.1
-      rxjs: 7.8.1
+      rxjs: 7.8.2
       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@5.0.0:
     resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
     engines: {node: '>=8'}
@@ -5836,10 +5339,8 @@ packages:
       js-tokens: 4.0.0
     dev: true
 
-  /loupe@2.3.7:
-    resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
-    dependencies:
-      get-func-name: 2.0.2
+  /loupe@3.1.3:
+    resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==}
     dev: true
 
   /lower-case@2.0.2:
@@ -5880,28 +5381,10 @@ packages:
     dependencies:
       '@jridgewell/sourcemap-codec': 1.5.0
 
-  /mark.js@8.11.1:
-    resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
-    dev: true
-
   /math-intrinsics@1.1.0:
     resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
     engines: {node: '>= 0.4'}
 
-  /mdast-util-to-hast@13.2.0:
-    resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
-    dependencies:
-      '@types/hast': 3.0.4
-      '@types/mdast': 4.0.4
-      '@ungap/structured-clone': 1.3.0
-      devlop: 1.1.0
-      micromark-util-sanitize-uri: 2.0.1
-      trim-lines: 3.0.1
-      unist-util-position: 5.0.0
-      unist-util-visit: 5.0.0
-      vfile: 6.0.3
-    dev: true
-
   /media-typer@0.3.0:
     resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
     engines: {node: '>= 0.6'}
@@ -5920,7 +5403,6 @@ packages:
   /merge2@1.4.1:
     resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
     engines: {node: '>= 8'}
-    dev: true
 
   /merge@2.1.1:
     resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==}
@@ -5930,33 +5412,6 @@ packages:
     resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==}
     engines: {node: '>= 0.6'}
 
-  /micromark-util-character@2.1.1:
-    resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==}
-    dependencies:
-      micromark-util-symbol: 2.0.1
-      micromark-util-types: 2.0.1
-    dev: true
-
-  /micromark-util-encode@2.0.1:
-    resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==}
-    dev: true
-
-  /micromark-util-sanitize-uri@2.0.1:
-    resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==}
-    dependencies:
-      micromark-util-character: 2.1.1
-      micromark-util-encode: 2.0.1
-      micromark-util-symbol: 2.0.1
-    dev: true
-
-  /micromark-util-symbol@2.0.1:
-    resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==}
-    dev: true
-
-  /micromark-util-types@2.0.1:
-    resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==}
-    dev: true
-
   /micromatch@4.0.8:
     resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
     engines: {node: '>=8.6'}
@@ -5968,8 +5423,8 @@ packages:
     resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
     engines: {node: '>= 0.6'}
 
-  /mime-db@1.53.0:
-    resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==}
+  /mime-db@1.54.0:
+    resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
     engines: {node: '>= 0.6'}
 
   /mime-types@2.1.35:
@@ -6041,14 +5496,6 @@ packages:
     engines: {node: '>=16 || 14 >=14.17'}
     dev: true
 
-  /minisearch@7.1.2:
-    resolution: {integrity: sha512-R1Pd9eF+MD5JYDDSPAp/q1ougKglm14uEkPMvQ/05RGmx6G9wvmLTrTI/Q5iPNJLYqNdsDQ7qTGIcNWR+FrHmA==}
-    dev: true
-
-  /mitt@3.0.1:
-    resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
-    dev: true
-
   /mkdirp@0.5.6:
     resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
     hasBin: true
@@ -6058,10 +5505,10 @@ packages:
   /mlly@1.7.4:
     resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==}
     dependencies:
-      acorn: 8.14.0
+      acorn: 8.14.1
       pathe: 2.0.3
       pkg-types: 1.3.1
-      ufo: 1.5.4
+      ufo: 1.6.0
     dev: true
 
   /mocha@11.1.0:
@@ -6115,7 +5562,7 @@ packages:
       prop-types: 15.8.1
       tcomb: 3.2.29
       tcomb-validation: 3.4.1
-      validator: 13.12.0
+      validator: 13.15.0
       yargs: 17.7.2
     dev: true
 
@@ -6160,8 +5607,8 @@ packages:
       thenify-all: 1.6.0
     dev: true
 
-  /nanoid@3.3.8:
-    resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+  /nanoid@3.3.11:
+    resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
     hasBin: true
 
@@ -6202,12 +5649,12 @@ packages:
     resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==}
     dev: true
 
-  /nopt@8.1.0:
-    resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==}
-    engines: {node: ^18.17.0 || >=20.5.0}
+  /nopt@7.2.1:
+    resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
+    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
     hasBin: true
     dependencies:
-      abbrev: 3.0.0
+      abbrev: 2.0.0
     dev: true
 
   /normalize-path@3.0.0:
@@ -6257,6 +5704,52 @@ packages:
     resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
     engines: {node: '>= 0.4'}
 
+  /object-keys@1.1.1:
+    resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
+  /object.assign@4.1.7:
+    resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      define-properties: 1.2.1
+      es-object-atoms: 1.1.1
+      has-symbols: 1.1.0
+      object-keys: 1.1.1
+    dev: true
+
+  /object.fromentries@2.0.8:
+    resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-object-atoms: 1.1.1
+    dev: true
+
+  /object.groupby@1.0.3:
+    resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+    dev: true
+
+  /object.values@1.2.1:
+    resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      define-properties: 1.2.1
+      es-object-atoms: 1.1.1
+    dev: true
+
   /on-finished@2.4.1:
     resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
     engines: {node: '>= 0.8'}
@@ -6285,14 +5778,6 @@ packages:
       mimic-fn: 4.0.0
     dev: false
 
-  /oniguruma-to-es@3.1.1:
-    resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==}
-    dependencies:
-      emoji-regex-xs: 1.0.0
-      regex: 6.0.1
-      regex-recursion: 6.0.2
-    dev: true
-
   /open@10.1.0:
     resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==}
     engines: {node: '>=18'}
@@ -6362,6 +5847,15 @@ packages:
     resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==}
     dev: true
 
+  /own-keys@1.0.1:
+    resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      get-intrinsic: 1.3.0
+      object-keys: 1.1.1
+      safe-push-apply: 1.0.0
+    dev: true
+
   /p-cancelable@2.1.1:
     resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
     engines: {node: '>=8'}
@@ -6390,7 +5884,7 @@ packages:
     resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     dependencies:
-      yocto-queue: 1.1.1
+      yocto-queue: 1.2.1
     dev: true
 
   /p-locate@4.1.0:
@@ -6452,7 +5946,6 @@ packages:
     engines: {node: '>=6'}
     dependencies:
       callsites: 3.1.0
-    dev: true
 
   /parse-json@5.2.0:
     resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
@@ -6498,6 +5991,10 @@ packages:
     engines: {node: '>=12'}
     dev: false
 
+  /path-parse@1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+    dev: true
+
   /path-scurry@1.11.1:
     resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
     engines: {node: '>=16 || 14 >=14.18'}
@@ -6517,17 +6014,14 @@ packages:
     resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
     dev: true
 
-  /pathval@1.1.1:
-    resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
+  /pathval@2.0.0:
+    resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
+    engines: {node: '>= 14.16'}
     dev: true
 
   /pend@1.2.0:
     resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
 
-  /perfect-debounce@1.0.0:
-    resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
-    dev: true
-
   /performance-now@2.1.0:
     resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
     dev: true
@@ -6549,7 +6043,7 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
-  /pinia@2.3.1(typescript@5.7.3)(vue@3.5.13):
+  /pinia@2.3.1(typescript@5.8.3)(vue@3.5.13):
     resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==}
     peerDependencies:
       typescript: '>=4.4.4'
@@ -6559,14 +6053,14 @@ packages:
         optional: true
     dependencies:
       '@vue/devtools-api': 6.6.4
-      typescript: 5.7.3
-      vue: 3.5.13(typescript@5.7.3)
+      typescript: 5.8.3
+      vue: 3.5.13(typescript@5.8.3)
       vue-demi: 0.14.10(vue@3.5.13)
     transitivePeerDependencies:
       - '@vue/composition-api'
 
-  /pirates@4.0.6:
-    resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+  /pirates@4.0.7:
+    resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
     engines: {node: '>= 6'}
     dev: true
 
@@ -6578,6 +6072,11 @@ packages:
       pathe: 2.0.3
     dev: true
 
+  /possible-typed-array-names@1.1.0:
+    resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
   /postcss-selector-parser@6.1.2:
     resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
     engines: {node: '>=4'}
@@ -6594,21 +6093,17 @@ packages:
     resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
     engines: {node: ^10 || ^12 || >=14}
     dependencies:
-      nanoid: 3.3.8
+      nanoid: 3.3.11
       picocolors: 1.1.1
       source-map-js: 1.2.1
 
-  /preact@10.26.2:
-    resolution: {integrity: sha512-0gNmv4qpS9HaN3+40CLBAnKe0ZfyE4ZWo5xKlC1rVrr0ckkEvJvAQqKaHANdFKsGstoxrY4AItZ7kZSGVoVjgg==}
-    dev: true
-
   /prelude-ls@1.2.1:
     resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
     engines: {node: '>= 0.8.0'}
     dev: true
 
-  /prettier@3.5.1:
-    resolution: {integrity: sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==}
+  /prettier@3.5.3:
+    resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==}
     engines: {node: '>=14'}
     hasBin: true
     dev: true
@@ -6618,15 +6113,6 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
-  /pretty-format@29.7.0:
-    resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/schemas': 29.6.3
-      ansi-styles: 5.2.0
-      react-is: 18.3.1
-    dev: true
-
   /process-nextick-args@2.0.1:
     resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
 
@@ -6648,10 +6134,6 @@ packages:
       react-is: 16.13.1
     dev: true
 
-  /property-information@7.0.0:
-    resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==}
-    dev: true
-
   /proto-list@1.2.4:
     resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
 
@@ -6668,6 +6150,7 @@ packages:
 
   /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==}
@@ -6682,7 +6165,6 @@ packages:
   /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==}
@@ -6697,20 +6179,19 @@ packages:
     dependencies:
       side-channel: 1.1.0
 
-  /qs@6.13.1:
-    resolution: {integrity: sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==}
+  /qs@6.14.0:
+    resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
     engines: {node: '>=0.6'}
     dependencies:
       side-channel: 1.1.0
     dev: true
 
-  /quasar@2.17.7:
-    resolution: {integrity: sha512-nPJdHoONlcW7WEU2Ody907Wx945Zfyuea/KP4LBaEn5AcL95PUWp8Gz/0zDYNnFw0aCWRtye3SUAdQl5tmrn5w==}
+  /quasar@2.18.1:
+    resolution: {integrity: sha512-db/P64Mzpt1uXJ0MapaG+IYJQ9hHDb5KtTCoszwC78DR7sA+Uoj7nBW2EytwYykIExEmqavOvKrdasTvqhkgEg==}
     engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'}
 
   /queue-microtask@1.2.3:
     resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
-    dev: true
 
   /quick-lru@5.1.1:
     resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
@@ -6746,25 +6227,21 @@ packages:
       strip-json-comments: 2.0.1
     dev: false
 
-  /react-dom@19.0.0(react@19.0.0):
-    resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
+  /react-dom@19.1.0(react@19.1.0):
+    resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==}
     peerDependencies:
-      react: ^19.0.0
+      react: ^19.1.0
     dependencies:
-      react: 19.0.0
-      scheduler: 0.25.0
+      react: 19.1.0
+      scheduler: 0.26.0
     dev: true
 
   /react-is@16.13.1:
     resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
     dev: true
 
-  /react-is@18.3.1:
-    resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
-    dev: true
-
-  /react@19.0.0:
-    resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
+  /react@19.1.0:
+    resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==}
     engines: {node: '>=0.10.0'}
     dev: true
 
@@ -6827,24 +6304,34 @@ packages:
       tslib: 1.14.1
     dev: true
 
+  /reflect.getprototypeof@1.0.10:
+    resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-errors: 1.3.0
+      es-object-atoms: 1.1.1
+      get-intrinsic: 1.3.0
+      get-proto: 1.0.1
+      which-builtin-type: 1.2.1
+    dev: true
+
   /regenerator-runtime@0.14.1:
     resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
     dev: true
 
-  /regex-recursion@6.0.2:
-    resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==}
+  /regexp.prototype.flags@1.5.4:
+    resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
+    engines: {node: '>= 0.4'}
     dependencies:
-      regex-utilities: 2.3.0
-    dev: true
-
-  /regex-utilities@2.3.0:
-    resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==}
-    dev: true
-
-  /regex@6.0.1:
-    resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==}
-    dependencies:
-      regex-utilities: 2.3.0
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-errors: 1.3.0
+      get-proto: 1.0.1
+      gopd: 1.2.0
+      set-function-name: 2.0.2
     dev: true
 
   /registry-auth-token@5.1.0:
@@ -6897,13 +6384,22 @@ packages:
   /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.10:
+    resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==}
+    engines: {node: '>= 0.4'}
+    hasBin: true
+    dependencies:
+      is-core-module: 2.16.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:
@@ -6925,10 +6421,9 @@ packages:
       signal-exit: 3.0.7
     dev: true
 
-  /reusify@1.0.4:
-    resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+  /reusify@1.1.0:
+    resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
     engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
-    dev: true
 
   /rfdc@1.4.1:
     resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
@@ -6961,32 +6456,33 @@ packages:
       yargs: 17.7.2
     dev: true
 
-  /rollup@4.34.8:
-    resolution: {integrity: sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==}
+  /rollup@4.39.0:
+    resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==}
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
     dependencies:
-      '@types/estree': 1.0.6
+      '@types/estree': 1.0.7
     optionalDependencies:
-      '@rollup/rollup-android-arm-eabi': 4.34.8
-      '@rollup/rollup-android-arm64': 4.34.8
-      '@rollup/rollup-darwin-arm64': 4.34.8
-      '@rollup/rollup-darwin-x64': 4.34.8
-      '@rollup/rollup-freebsd-arm64': 4.34.8
-      '@rollup/rollup-freebsd-x64': 4.34.8
-      '@rollup/rollup-linux-arm-gnueabihf': 4.34.8
-      '@rollup/rollup-linux-arm-musleabihf': 4.34.8
-      '@rollup/rollup-linux-arm64-gnu': 4.34.8
-      '@rollup/rollup-linux-arm64-musl': 4.34.8
-      '@rollup/rollup-linux-loongarch64-gnu': 4.34.8
-      '@rollup/rollup-linux-powerpc64le-gnu': 4.34.8
-      '@rollup/rollup-linux-riscv64-gnu': 4.34.8
-      '@rollup/rollup-linux-s390x-gnu': 4.34.8
-      '@rollup/rollup-linux-x64-gnu': 4.34.8
-      '@rollup/rollup-linux-x64-musl': 4.34.8
-      '@rollup/rollup-win32-arm64-msvc': 4.34.8
-      '@rollup/rollup-win32-ia32-msvc': 4.34.8
-      '@rollup/rollup-win32-x64-msvc': 4.34.8
+      '@rollup/rollup-android-arm-eabi': 4.39.0
+      '@rollup/rollup-android-arm64': 4.39.0
+      '@rollup/rollup-darwin-arm64': 4.39.0
+      '@rollup/rollup-darwin-x64': 4.39.0
+      '@rollup/rollup-freebsd-arm64': 4.39.0
+      '@rollup/rollup-freebsd-x64': 4.39.0
+      '@rollup/rollup-linux-arm-gnueabihf': 4.39.0
+      '@rollup/rollup-linux-arm-musleabihf': 4.39.0
+      '@rollup/rollup-linux-arm64-gnu': 4.39.0
+      '@rollup/rollup-linux-arm64-musl': 4.39.0
+      '@rollup/rollup-linux-loongarch64-gnu': 4.39.0
+      '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0
+      '@rollup/rollup-linux-riscv64-gnu': 4.39.0
+      '@rollup/rollup-linux-riscv64-musl': 4.39.0
+      '@rollup/rollup-linux-s390x-gnu': 4.39.0
+      '@rollup/rollup-linux-x64-gnu': 4.39.0
+      '@rollup/rollup-linux-x64-musl': 4.39.0
+      '@rollup/rollup-win32-arm64-msvc': 4.39.0
+      '@rollup/rollup-win32-ia32-msvc': 4.39.0
+      '@rollup/rollup-win32-x64-msvc': 4.39.0
       fsevents: 2.3.3
     dev: true
 
@@ -7020,25 +6516,52 @@ packages:
     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==}
+  /rxjs@7.8.2:
+    resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==}
     dependencies:
       tslib: 2.8.1
     dev: true
 
+  /safe-array-concat@1.1.3:
+    resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
+    engines: {node: '>=0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      get-intrinsic: 1.3.0
+      has-symbols: 1.1.0
+      isarray: 2.0.5
+    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==}
 
+  /safe-push-apply@1.0.0:
+    resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      es-errors: 1.3.0
+      isarray: 2.0.5
+    dev: true
+
+  /safe-regex-test@1.1.0:
+    resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      es-errors: 1.3.0
+      is-regex: 1.2.1
+    dev: true
+
   /safer-buffer@2.1.2:
     resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
 
-  /sass-embedded-android-arm64@1.85.0:
-    resolution: {integrity: sha512-4itDzRwezwrW8+YzMLIwHtMeH+qrBNdBsRn9lTVI15K+cNLC8z5JWJi6UCZ8TNNZr9LDBfsh5jUdjSub0yF7jg==}
+  /sass-embedded-android-arm64@1.86.3:
+    resolution: {integrity: sha512-q+XwFp6WgAv+UgnQhsB8KQ95kppvWAB7DSoJp+8Vino8b9ND+1ai3cUUZPE5u4SnLZrgo5NtrbPvN5KLc4Pfyg==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [android]
@@ -7046,8 +6569,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-android-arm@1.85.0:
-    resolution: {integrity: sha512-pPBT7Ad6G8Mlao8ypVNXW2ya7I/Bhcny+RYZ/EmrunEXfhzCNp4PWV2VAweitPO9RnPIJwvUTkLc8Fu6K3nVmw==}
+  /sass-embedded-android-arm@1.86.3:
+    resolution: {integrity: sha512-UyeXrFzZSvrGbvrWUBcspbsbivGgAgebLGJdSqJulgSyGbA6no3DWQ5Qpdd6+OAUC39BlpPu74Wx9s4RrVuaFw==}
     engines: {node: '>=14.0.0'}
     cpu: [arm]
     os: [android]
@@ -7055,8 +6578,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-android-ia32@1.85.0:
-    resolution: {integrity: sha512-bwqKq95hzbGbMTeXCMQhH7yEdc2xJVwIXj7rGdD3McvyFWbED6362XRFFPI5YyjfD2wRJd9yWLh/hn+6VyjcYA==}
+  /sass-embedded-android-ia32@1.86.3:
+    resolution: {integrity: sha512-gTJjVh2cRzvGujXj5ApPk/owUTL5SiO7rDtNLrzYAzi1N5HRuLYXqk3h1IQY3+eCOBjGl7mQ9XyySbJs/3hDvg==}
     engines: {node: '>=14.0.0'}
     cpu: [ia32]
     os: [android]
@@ -7064,8 +6587,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-android-riscv64@1.85.0:
-    resolution: {integrity: sha512-Fgkgay+5EePJXZFHR5Vlkutnsmox2V6nX4U3mfGbSN1xjLRm8F5ST72V2s5Z0mnIFpGvEu/v7hfptgViqMvaxg==}
+  /sass-embedded-android-riscv64@1.86.3:
+    resolution: {integrity: sha512-Po3JnyiCS16kd6REo1IMUbFGYtvL9O0rmKaXx5vOuBaJD1LPy2LiSSp7TU7wkJ9IxsTDGzFaSeP1I9qb6D8VVg==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [android]
@@ -7073,8 +6596,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-android-x64@1.85.0:
-    resolution: {integrity: sha512-/bG3JgTn3eoIDHCiJNVkLeJgUesat4ghxqYmKMZUJx++4e6iKCDj8XwQTJAgm+QDrsPKXHBacHEANJ9LEAuTqg==}
+  /sass-embedded-android-x64@1.86.3:
+    resolution: {integrity: sha512-+7h3jdDv/0kUFx0BvxYlq2fa7CcHiDPlta6k5OxO5K6jyqJwo9hc0Z052BoYEauWTqZ+vK6bB5rv2BIzq4U9nA==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [android]
@@ -7082,8 +6605,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-darwin-arm64@1.85.0:
-    resolution: {integrity: sha512-plp8TyMz97YFBCB3ndftEvoW29vyfsSBJILM5U84cGzr06SvLh/Npjj8psfUeRw+upEk1zkFtw5u61sRCdgwIw==}
+  /sass-embedded-darwin-arm64@1.86.3:
+    resolution: {integrity: sha512-EgLwV4ORm5Hr0DmIXo0Xw/vlzwLnfAiqD2jDXIglkBsc5czJmo4/IBdGXOP65TRnsgJEqvbU3aQhuawX5++x9A==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [darwin]
@@ -7091,8 +6614,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-darwin-x64@1.85.0:
-    resolution: {integrity: sha512-LP8Zv8DG57Gn6PmSwWzC0gEZUsGdg36Ps3m0i1fVTOelql7N3HZIrlPYRjJvidL8ZlB3ISxNANebTREUHn/wkQ==}
+  /sass-embedded-darwin-x64@1.86.3:
+    resolution: {integrity: sha512-dfKhfrGPRNLWLC82vy/vQGmNKmAiKWpdFuWiePRtg/E95pqw+sCu6080Y6oQLfFu37Iq3MpnXiSpDuSo7UnPWA==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [darwin]
@@ -7100,8 +6623,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-arm64@1.85.0:
-    resolution: {integrity: sha512-JRIRKVOY5Y8M1zlUOv9AQGju4P6lj8i5vLJZsVYVN/uY8Cd2dDJZPC8EOhjntp+IpF8AOGIHqCeCkHBceIyIjA==}
+  /sass-embedded-linux-arm64@1.86.3:
+    resolution: {integrity: sha512-tYq5rywR53Qtc+0KI6pPipOvW7a47ETY69VxfqI9BR2RKw2hBbaz0bIw6OaOgEBv2/XNwcWb7a4sr7TqgkqKAA==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
@@ -7109,8 +6632,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-arm@1.85.0:
-    resolution: {integrity: sha512-18xOAEfazJt1MMVS2TRHV94n81VyMnywOoJ7/S7I79qno/zx26OoqqP4XvH107xu8+mZ9Gg54LrUH6ZcgHk08g==}
+  /sass-embedded-linux-arm@1.86.3:
+    resolution: {integrity: sha512-+fVCIH+OR0SMHn2NEhb/VfbpHuUxcPtqMS34OCV3Ka99LYZUJZqth4M3lT/ppGl52mwIVLNYzR4iLe6mdZ6mYA==}
     engines: {node: '>=14.0.0'}
     cpu: [arm]
     os: [linux]
@@ -7118,8 +6641,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-ia32@1.85.0:
-    resolution: {integrity: sha512-4JH+h+gLt9So22nNPQtsKojEsLzjld9ol3zWcOtMGclv+HojZGbCuhJUrLUcK72F8adXYsULmWhJPKROLIwYMA==}
+  /sass-embedded-linux-ia32@1.86.3:
+    resolution: {integrity: sha512-CmQ5OkqnaeLdaF+bMqlYGooBuenqm3LvEN9H8BLhjkpWiFW8hnYMetiqMcJjhrXLvDw601KGqA5sr/Rsg5s45g==}
     engines: {node: '>=14.0.0'}
     cpu: [ia32]
     os: [linux]
@@ -7127,8 +6650,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-musl-arm64@1.85.0:
-    resolution: {integrity: sha512-aoQjUjK28bvdw9XKTjQeayn8oWQ2QqvoTD11myklGd3IHH7Jj0nwXUstI4NxDueCKt3wghuZoIQkjOheReQxlg==}
+  /sass-embedded-linux-musl-arm64@1.86.3:
+    resolution: {integrity: sha512-4zOr2C/eW89rxb4ozTfn7lBzyyM5ZigA1ZSRTcAR26Qbg/t2UksLdGnVX9/yxga0d6aOi0IvO/7iM2DPPRRotg==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [linux]
@@ -7136,8 +6659,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-musl-arm@1.85.0:
-    resolution: {integrity: sha512-Z1j4ageDVFihqNUBnm89fxY46pY0zD/Clp1D3ZdI7S+D280+AEpbm5vMoH8LLhBQfQLf2w7H++SZGpQwrisudQ==}
+  /sass-embedded-linux-musl-arm@1.86.3:
+    resolution: {integrity: sha512-SEm65SQknI4pl+mH5Xf231hOkHJyrlgh5nj4qDbiBG6gFeutaNkNIeRgKEg3cflXchCr8iV/q/SyPgjhhzQb7w==}
     engines: {node: '>=14.0.0'}
     cpu: [arm]
     os: [linux]
@@ -7145,8 +6668,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-musl-ia32@1.85.0:
-    resolution: {integrity: sha512-/cJCSXOfXmQFH8deE+3U9x+BSz8i0d1Tt9gKV/Gat1Xm43Oumw8pmZgno+cDuGjYQInr9ryW5121pTMlj/PBXQ==}
+  /sass-embedded-linux-musl-ia32@1.86.3:
+    resolution: {integrity: sha512-84Tcld32LB1loiqUvczWyVBQRCChm0wNLlkT59qF29nxh8njFIVf9yaPgXcSyyjpPoD9Tu0wnq3dvVzoMCh9AQ==}
     engines: {node: '>=14.0.0'}
     cpu: [ia32]
     os: [linux]
@@ -7154,8 +6677,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-musl-riscv64@1.85.0:
-    resolution: {integrity: sha512-l+FJxMXkmg42RZq5RFKXg4InX0IA7yEiPHe4kVSdrczP7z3NLxk+W9wVkPnoRKYIMe1qZPPQ25y0TgI4HNWouA==}
+  /sass-embedded-linux-musl-riscv64@1.86.3:
+    resolution: {integrity: sha512-IxEqoiD7vdNpiOwccybbV93NljBy64wSTkUOknGy21SyV43C8uqESOwTwW9ywa3KufImKm8L3uQAW/B0KhJMWg==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [linux]
@@ -7163,8 +6686,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-musl-x64@1.85.0:
-    resolution: {integrity: sha512-M9ffjcYfFcRvkFA6V3DpOS955AyvmpvPAhL/xNK45d/ma1n1ehTWpd24tVeKiNK5CZkNjjMEfyw2fHa6MpqmEA==}
+  /sass-embedded-linux-musl-x64@1.86.3:
+    resolution: {integrity: sha512-ePeTPXUxPK6JgHcUfnrkIyDtyt+zlAvF22mVZv6y1g/PZFm1lSfX+Za7TYHg9KaYqaaXDiw6zICX4i44HhR8rA==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
@@ -7172,8 +6695,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-riscv64@1.85.0:
-    resolution: {integrity: sha512-yqPXQWfM+qiIPkfn++48GOlbmSvUZIyL9nwFstBk0k4x40UhbhilfknqeTUpxoHfQzylTGVhrm5JE7MjM+LNZA==}
+  /sass-embedded-linux-riscv64@1.86.3:
+    resolution: {integrity: sha512-NuXQ72dwfNLe35E+RaXJ4Noq4EkFwM65eWwCwxEWyJO9qxOx1EXiCAJii6x8kkOh5daWuMU0VAI1B9RsJaqqQQ==}
     engines: {node: '>=14.0.0'}
     cpu: [riscv64]
     os: [linux]
@@ -7181,8 +6704,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-linux-x64@1.85.0:
-    resolution: {integrity: sha512-NTDeQFZcuVR7COoaRy8pZD6/+QznwBR8kVFsj7NpmvX9aJ7TX/q+OQZHX7Bfb3tsfKXhf1YZozegPuYxRnMKAQ==}
+  /sass-embedded-linux-x64@1.86.3:
+    resolution: {integrity: sha512-t8be9zJ5B82+og9bQmIQ83yMGYZMTMrlGA+uGWtYacmwg6w3093dk91Fx0YzNSZBp3Tk60qVYjCZnEIwy60x0g==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [linux]
@@ -7190,8 +6713,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-win32-arm64@1.85.0:
-    resolution: {integrity: sha512-gO0VAuxC4AdV+uZYJESRWVVHQWCGzNs0C3OKCAdH4r1vGRugooMi7J/5wbwUdXDA1MV9ICfhlKsph2n3GiPdqA==}
+  /sass-embedded-win32-arm64@1.86.3:
+    resolution: {integrity: sha512-4ghuAzjX4q8Nksm0aifRz8hgXMMxS0SuymrFfkfJlrSx68pIgvAge6AOw0edoZoe0Tf5ZbsWUWamhkNyNxkTvw==}
     engines: {node: '>=14.0.0'}
     cpu: [arm64]
     os: [win32]
@@ -7199,8 +6722,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-win32-ia32@1.85.0:
-    resolution: {integrity: sha512-PCyn6xeFIBUgBceNypuf73/5DWF2VWPlPqPuBprPsTvpZOMUJeBtP+Lf4mnu3dNy1z76mYVnpaCnQmzZ0zHZaA==}
+  /sass-embedded-win32-ia32@1.86.3:
+    resolution: {integrity: sha512-tCaK4zIRq9mLRPxLzBAdYlfCuS/xLNpmjunYxeWkIwlJo+k53h1udyXH/FInnQ2GgEz0xMXyvH3buuPgzwWYsw==}
     engines: {node: '>=14.0.0'}
     cpu: [ia32]
     os: [win32]
@@ -7208,8 +6731,8 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded-win32-x64@1.85.0:
-    resolution: {integrity: sha512-AknE2jLp6OBwrR5hQ8pDsG94KhJCeSheFJ2xgbnk8RUjZX909JiNbgh2sNt9LG+RXf4xZa55dDL537gZoCx/iw==}
+  /sass-embedded-win32-x64@1.86.3:
+    resolution: {integrity: sha512-zS+YNKfTF4SnOfpC77VTb0qNZyTXrxnAezSoRV0xnw6HlY+1WawMSSB6PbWtmbvyfXNgpmJUttoTtsvJjRCucg==}
     engines: {node: '>=14.0.0'}
     cpu: [x64]
     os: [win32]
@@ -7217,49 +6740,49 @@ packages:
     dev: true
     optional: true
 
-  /sass-embedded@1.85.0:
-    resolution: {integrity: sha512-x3Vv54g0jv1aPSW8OTA/0GzQCs/HMQOjIkLtZJ3Xsn/I4vnyjKbVTQmFTax9bQjldqLEEkdbvy6ES/cOOnYNwA==}
+  /sass-embedded@1.86.3:
+    resolution: {integrity: sha512-3pZSp24ibO1hdopj+W9DuiWsZOb2YY6AFRo/jjutKLBkqJGM1nJjXzhAYfzRV+Xn5BX1eTI4bBTE09P0XNHOZg==}
     engines: {node: '>=16.0.0'}
     hasBin: true
     dependencies:
-      '@bufbuild/protobuf': 2.2.3
+      '@bufbuild/protobuf': 2.2.5
       buffer-builder: 0.2.0
       colorjs.io: 0.5.2
-      immutable: 5.0.3
-      rxjs: 7.8.1
+      immutable: 5.1.1
+      rxjs: 7.8.2
       supports-color: 8.1.1
       sync-child-process: 1.0.2
       varint: 6.0.0
     optionalDependencies:
-      sass-embedded-android-arm: 1.85.0
-      sass-embedded-android-arm64: 1.85.0
-      sass-embedded-android-ia32: 1.85.0
-      sass-embedded-android-riscv64: 1.85.0
-      sass-embedded-android-x64: 1.85.0
-      sass-embedded-darwin-arm64: 1.85.0
-      sass-embedded-darwin-x64: 1.85.0
-      sass-embedded-linux-arm: 1.85.0
-      sass-embedded-linux-arm64: 1.85.0
-      sass-embedded-linux-ia32: 1.85.0
-      sass-embedded-linux-musl-arm: 1.85.0
-      sass-embedded-linux-musl-arm64: 1.85.0
-      sass-embedded-linux-musl-ia32: 1.85.0
-      sass-embedded-linux-musl-riscv64: 1.85.0
-      sass-embedded-linux-musl-x64: 1.85.0
-      sass-embedded-linux-riscv64: 1.85.0
-      sass-embedded-linux-x64: 1.85.0
-      sass-embedded-win32-arm64: 1.85.0
-      sass-embedded-win32-ia32: 1.85.0
-      sass-embedded-win32-x64: 1.85.0
+      sass-embedded-android-arm: 1.86.3
+      sass-embedded-android-arm64: 1.86.3
+      sass-embedded-android-ia32: 1.86.3
+      sass-embedded-android-riscv64: 1.86.3
+      sass-embedded-android-x64: 1.86.3
+      sass-embedded-darwin-arm64: 1.86.3
+      sass-embedded-darwin-x64: 1.86.3
+      sass-embedded-linux-arm: 1.86.3
+      sass-embedded-linux-arm64: 1.86.3
+      sass-embedded-linux-ia32: 1.86.3
+      sass-embedded-linux-musl-arm: 1.86.3
+      sass-embedded-linux-musl-arm64: 1.86.3
+      sass-embedded-linux-musl-ia32: 1.86.3
+      sass-embedded-linux-musl-riscv64: 1.86.3
+      sass-embedded-linux-musl-x64: 1.86.3
+      sass-embedded-linux-riscv64: 1.86.3
+      sass-embedded-linux-x64: 1.86.3
+      sass-embedded-win32-arm64: 1.86.3
+      sass-embedded-win32-ia32: 1.86.3
+      sass-embedded-win32-x64: 1.86.3
     dev: true
 
-  /sass@1.85.0:
-    resolution: {integrity: sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==}
+  /sass@1.86.3:
+    resolution: {integrity: sha512-iGtg8kus4GrsGLRDLRBRHY9dNVA78ZaS7xr01cWnS7PEMQyFtTqBiyCrfpTYTZXRWM94akzckYjh8oADfFNTzw==}
     engines: {node: '>=14.0.0'}
     hasBin: true
     dependencies:
       chokidar: 4.0.3
-      immutable: 5.0.3
+      immutable: 5.1.1
       source-map-js: 1.2.1
     optionalDependencies:
       '@parcel/watcher': 2.5.1
@@ -7273,12 +6796,8 @@ packages:
     resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
     dev: true
 
-  /scheduler@0.25.0:
-    resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
-    dev: true
-
-  /search-insights@2.17.3:
-    resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==}
+  /scheduler@0.26.0:
+    resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==}
     dev: true
 
   /selfsigned@2.4.1:
@@ -7346,6 +6865,37 @@ packages:
     resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
     dev: true
 
+  /set-function-length@1.2.2:
+    resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.4
+      es-errors: 1.3.0
+      function-bind: 1.1.2
+      get-intrinsic: 1.3.0
+      gopd: 1.2.0
+      has-property-descriptors: 1.0.2
+    dev: true
+
+  /set-function-name@2.0.2:
+    resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      define-data-property: 1.1.4
+      es-errors: 1.3.0
+      functions-have-names: 1.2.3
+      has-property-descriptors: 1.0.2
+    dev: true
+
+  /set-proto@1.0.0:
+    resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      dunder-proto: 1.0.1
+      es-errors: 1.3.0
+      es-object-atoms: 1.1.1
+    dev: true
+
   /setprototypeof@1.2.0:
     resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
 
@@ -7366,19 +6916,6 @@ packages:
     resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
     engines: {node: '>=8'}
 
-  /shiki@2.5.0:
-    resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==}
-    dependencies:
-      '@shikijs/core': 2.5.0
-      '@shikijs/engine-javascript': 2.5.0
-      '@shikijs/engine-oniguruma': 2.5.0
-      '@shikijs/langs': 2.5.0
-      '@shikijs/themes': 2.5.0
-      '@shikijs/types': 2.5.0
-      '@shikijs/vscode-textmate': 10.0.2
-      '@types/hast': 3.0.4
-    dev: true
-
   /side-channel-list@1.0.0:
     resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
     engines: {node: '>= 0.4'}
@@ -7390,18 +6927,18 @@ packages:
     resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
     engines: {node: '>= 0.4'}
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       es-errors: 1.3.0
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       object-inspect: 1.13.4
 
   /side-channel-weakmap@1.0.2:
     resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
     engines: {node: '>= 0.4'}
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       es-errors: 1.3.0
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       object-inspect: 1.13.4
       side-channel-map: 1.0.1
 
@@ -7509,15 +7046,6 @@ packages:
     engines: {node: '>= 8'}
     dev: true
 
-  /space-separated-tokens@2.0.2:
-    resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
-    dev: true
-
-  /speakingurl@14.0.1:
-    resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
-    engines: {node: '>=0.10.0'}
-    dev: true
-
   /split2@4.2.0:
     resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
     engines: {node: '>= 10.x'}
@@ -7552,8 +7080,8 @@ packages:
     resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
     engines: {node: '>= 0.8'}
 
-  /std-env@3.8.0:
-    resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==}
+  /std-env@3.9.0:
+    resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
     dev: true
 
   /streamx@2.22.0:
@@ -7581,6 +7109,38 @@ packages:
       emoji-regex: 9.2.2
       strip-ansi: 7.1.0
 
+  /string.prototype.trim@1.2.10:
+    resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      define-data-property: 1.1.4
+      define-properties: 1.2.1
+      es-abstract: 1.23.9
+      es-object-atoms: 1.1.1
+      has-property-descriptors: 1.0.2
+    dev: true
+
+  /string.prototype.trimend@1.0.9:
+    resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      define-properties: 1.2.1
+      es-object-atoms: 1.1.1
+    dev: true
+
+  /string.prototype.trimstart@1.0.8:
+    resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      define-properties: 1.2.1
+      es-object-atoms: 1.1.1
+    dev: true
+
   /string_decoder@1.1.1:
     resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
     dependencies:
@@ -7592,13 +7152,6 @@ packages:
       safe-buffer: 5.2.1
     dev: true
 
-  /stringify-entities@4.0.4:
-    resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
-    dependencies:
-      character-entities-html4: 2.1.0
-      character-entities-legacy: 3.0.0
-    dev: true
-
   /strip-ansi@6.0.1:
     resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
     engines: {node: '>=8'}
@@ -7633,13 +7186,6 @@ packages:
   /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.14.0
-    dev: true
 
   /style-mod@4.1.2:
     resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==}
@@ -7655,17 +7201,10 @@ packages:
       glob: 10.4.5
       lines-and-columns: 1.2.4
       mz: 2.7.0
-      pirates: 4.0.6
+      pirates: 4.0.7
       ts-interface-checker: 0.1.13
     dev: true
 
-  /superjson@2.2.2:
-    resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==}
-    engines: {node: '>=16'}
-    dependencies:
-      copy-anything: 3.0.5
-    dev: true
-
   /supports-color@7.2.0:
     resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
     engines: {node: '>=8'}
@@ -7679,6 +7218,11 @@ packages:
     dependencies:
       has-flag: 4.0.0
 
+  /supports-preserve-symlinks-flag@1.0.0:
+    resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+    engines: {node: '>= 0.4'}
+    dev: true
+
   /sync-child-process@1.0.2:
     resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==}
     engines: {node: '>=16.0.0'}
@@ -7691,10 +7235,6 @@ packages:
     engines: {node: '>=16.0.0'}
     dev: true
 
-  /tabbable@6.2.0:
-    resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
-    dev: true
-
   /tar-stream@3.1.7:
     resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
     dependencies:
@@ -7719,7 +7259,7 @@ packages:
     hasBin: true
     dependencies:
       '@jridgewell/source-map': 0.3.6
-      acorn: 8.14.0
+      acorn: 8.14.1
       commander: 2.20.3
       source-map-support: 0.5.21
     dev: true
@@ -7772,13 +7312,18 @@ packages:
       picomatch: 4.0.2
     dev: true
 
-  /tinypool@0.7.0:
-    resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==}
+  /tinypool@1.0.2:
+    resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    dev: true
+
+  /tinyrainbow@2.0.0:
+    resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==}
     engines: {node: '>=14.0.0'}
     dev: true
 
-  /tinyspy@2.2.1:
-    resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
+  /tinyspy@3.0.2:
+    resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
     engines: {node: '>=14.0.0'}
     dev: true
 
@@ -7787,15 +7332,15 @@ packages:
     engines: {node: '>=12'}
     dev: false
 
-  /tldts-core@6.1.78:
-    resolution: {integrity: sha512-jS0svNsB99jR6AJBmfmEWuKIgz91Haya91Z43PATaeHJ24BkMoNRb/jlaD37VYjb0mYf6gRL/HOnvS1zEnYBiw==}
+  /tldts-core@6.1.85:
+    resolution: {integrity: sha512-DTjUVvxckL1fIoPSb3KE7ISNtkWSawZdpfxGxwiIrZoO6EbHVDXXUIlIuWympPaeS+BLGyggozX/HTMsRAdsoA==}
     dev: true
 
-  /tldts@6.1.78:
-    resolution: {integrity: sha512-fSgYrW0ITH0SR/CqKMXIruYIPpNu5aDgUp22UhYoSrnUQwc7SBqifEBFNce7AAcygUPBo6a/gbtcguWdmko4RQ==}
+  /tldts@6.1.85:
+    resolution: {integrity: sha512-gBdZ1RjCSevRPFix/hpaUWeak2/RNUZB4/8frF1r5uYMHjFptkiT0JXIebWvgI/0ZHXvxaUDDJshiA0j6GdL3w==}
     hasBin: true
     dependencies:
-      tldts-core: 6.1.78
+      tldts-core: 6.1.85
     dev: true
 
   /tmp@0.0.33:
@@ -7819,11 +7364,11 @@ packages:
     resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
     engines: {node: '>=0.6'}
 
-  /tough-cookie@5.1.1:
-    resolution: {integrity: sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA==}
+  /tough-cookie@5.1.2:
+    resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
     engines: {node: '>=16'}
     dependencies:
-      tldts: 6.1.78
+      tldts: 6.1.85
     dev: true
 
   /tree-kill@1.2.2:
@@ -7831,11 +7376,7 @@ packages:
     hasBin: true
     dev: true
 
-  /trim-lines@3.0.1:
-    resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
-    dev: true
-
-  /ts-essentials@9.4.2(typescript@5.7.3):
+  /ts-essentials@9.4.2(typescript@5.8.3):
     resolution: {integrity: sha512-mB/cDhOvD7pg3YCLk2rOtejHjjdSi9in/IBYE13S+8WA5FBSraYf4V/ws55uvs0IvQ/l0wBOlXy5yBNZ9Bl8ZQ==}
     peerDependencies:
       typescript: '>=4.1.0'
@@ -7843,14 +7384,14 @@ packages:
       typescript:
         optional: true
     dependencies:
-      typescript: 5.7.3
+      typescript: 5.8.3
     dev: true
 
   /ts-interface-checker@0.1.13:
     resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
     dev: true
 
-  /tsconfck@3.1.5(typescript@5.7.3):
+  /tsconfck@3.1.5(typescript@5.8.3):
     resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==}
     engines: {node: ^18 || >=20}
     hasBin: true
@@ -7860,7 +7401,7 @@ packages:
       typescript:
         optional: true
     dependencies:
-      typescript: 5.7.3
+      typescript: 5.8.3
     dev: true
 
   /tsconfig-paths@3.15.0:
@@ -7902,11 +7443,6 @@ packages:
       prelude-ls: 1.2.1
     dev: true
 
-  /type-detect@4.1.0:
-    resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==}
-    engines: {node: '>=4'}
-    dev: true
-
   /type-fest@0.20.2:
     resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
     engines: {node: '>=10'}
@@ -7927,8 +7463,8 @@ packages:
     engines: {node: '>=12.20'}
     dev: false
 
-  /type-fest@4.35.0:
-    resolution: {integrity: sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==}
+  /type-fest@4.39.1:
+    resolution: {integrity: sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==}
     engines: {node: '>=16'}
     dev: true
 
@@ -7939,6 +7475,51 @@ packages:
       media-typer: 0.3.0
       mime-types: 2.1.35
 
+  /typed-array-buffer@1.0.3:
+    resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      es-errors: 1.3.0
+      is-typed-array: 1.1.15
+    dev: true
+
+  /typed-array-byte-length@1.0.3:
+    resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      for-each: 0.3.5
+      gopd: 1.2.0
+      has-proto: 1.2.0
+      is-typed-array: 1.1.15
+    dev: true
+
+  /typed-array-byte-offset@1.0.4:
+    resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.7
+      call-bind: 1.0.8
+      for-each: 0.3.5
+      gopd: 1.2.0
+      has-proto: 1.2.0
+      is-typed-array: 1.1.15
+      reflect.getprototypeof: 1.0.10
+    dev: true
+
+  /typed-array-length@1.0.7:
+    resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bind: 1.0.8
+      for-each: 0.3.5
+      gopd: 1.2.0
+      is-typed-array: 1.1.15
+      possible-typed-array-names: 1.1.0
+      reflect.getprototypeof: 1.0.10
+    dev: true
+
   /typedarray-to-buffer@3.1.5:
     resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
     dependencies:
@@ -7949,13 +7530,13 @@ packages:
     resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
     dev: false
 
-  /typescript@5.7.3:
-    resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
+  /typescript@5.8.3:
+    resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==}
     engines: {node: '>=14.17'}
     hasBin: true
 
-  /ufo@1.5.4:
-    resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
+  /ufo@1.6.0:
+    resolution: {integrity: sha512-AkgU2cV/+Xb4Uz6cic0kMZbtM42nbltnGvTVOt/8gMCbO2/z64nE47TOygh7HjgFPkUkVRBEyNFqpqi3zo+BJA==}
     dev: true
 
   /uglify-js@3.19.3:
@@ -7966,8 +7547,18 @@ packages:
     dev: true
     optional: true
 
-  /undici-types@6.20.0:
-    resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==}
+  /unbox-primitive@1.1.0:
+    resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      has-bigints: 1.1.0
+      has-symbols: 1.1.0
+      which-boxed-primitive: 1.1.1
+    dev: true
+
+  /undici-types@6.21.0:
+    resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
 
   /unicorn-magic@0.1.0:
     resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
@@ -7981,39 +7572,6 @@ packages:
       crypto-random-string: 4.0.0
     dev: false
 
-  /unist-util-is@6.0.0:
-    resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
-    dependencies:
-      '@types/unist': 3.0.3
-    dev: true
-
-  /unist-util-position@5.0.0:
-    resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
-    dependencies:
-      '@types/unist': 3.0.3
-    dev: true
-
-  /unist-util-stringify-position@4.0.0:
-    resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
-    dependencies:
-      '@types/unist': 3.0.3
-    dev: true
-
-  /unist-util-visit-parents@6.0.1:
-    resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
-    dependencies:
-      '@types/unist': 3.0.3
-      unist-util-is: 6.0.0
-    dev: true
-
-  /unist-util-visit@5.0.0:
-    resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
-    dependencies:
-      '@types/unist': 3.0.3
-      unist-util-is: 6.0.0
-      unist-util-visit-parents: 6.0.1
-    dev: true
-
   /universalify@0.1.2:
     resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
     engines: {node: '>= 4.0.0'}
@@ -8031,7 +7589,7 @@ packages:
     resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==}
     engines: {node: '>=14.0.0'}
     dependencies:
-      acorn: 8.14.0
+      acorn: 8.14.1
       webpack-virtual-modules: 0.6.2
     dev: true
 
@@ -8039,8 +7597,8 @@ packages:
     resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
     engines: {node: '>=8'}
 
-  /update-browserslist-db@1.1.2(browserslist@4.24.4):
-    resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==}
+  /update-browserslist-db@1.1.3(browserslist@4.24.4):
+    resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==}
     hasBin: true
     peerDependencies:
       browserslist: '>= 4.21.0'
@@ -8074,7 +7632,6 @@ packages:
     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
     dependencies:
       punycode: 2.3.1
-    dev: true
 
   /util-deprecate@1.0.2:
     resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -8088,8 +7645,8 @@ packages:
     hasBin: true
     dev: true
 
-  /validator@13.12.0:
-    resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==}
+  /validator@13.15.0:
+    resolution: {integrity: sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==}
     engines: {node: '>= 0.10'}
 
   /varint@6.0.0:
@@ -8109,21 +7666,7 @@ packages:
       extsprintf: 1.3.0
     dev: true
 
-  /vfile-message@4.0.2:
-    resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
-    dependencies:
-      '@types/unist': 3.0.3
-      unist-util-stringify-position: 4.0.0
-    dev: true
-
-  /vfile@6.0.3:
-    resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
-    dependencies:
-      '@types/unist': 3.0.3
-      vfile-message: 4.0.2
-    dev: true
-
-  /vite-jsconfig-paths@2.0.1(vite@6.2.0):
+  /vite-jsconfig-paths@2.0.1(vite@6.2.5):
     resolution: {integrity: sha512-rabcTTfKs0MdAsQWcZjbIMo5fcp6jthZce7uFEPgVPgpSY+RNOwjzIJOPES6cB/GJZLSoLGfHM9kt5HNmJvp7A==}
     peerDependencies:
       vite: '>2.0.0-0'
@@ -8132,24 +7675,24 @@ packages:
       globrex: 0.1.2
       recrawl-sync: 2.2.3
       tsconfig-paths: 3.15.0
-      vite: 6.2.0(@types/node@22.13.5)(sass@1.85.0)
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /vite-node@0.34.6(@types/node@22.13.4)(sass@1.85.0):
-    resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
-    engines: {node: '>=v14.18.0'}
+  /vite-node@3.1.1(@types/node@22.14.0)(sass@1.86.3):
+    resolution: {integrity: sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==}
+    engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
     dependencies:
       cac: 6.7.14
       debug: 4.4.0(supports-color@8.1.1)
-      mlly: 1.7.4
-      pathe: 1.1.2
-      picocolors: 1.1.1
-      vite: 5.4.14(@types/node@22.13.4)(sass@1.85.0)
+      es-module-lexer: 1.6.0
+      pathe: 2.0.3
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
     transitivePeerDependencies:
       - '@types/node'
+      - jiti
       - less
       - lightningcss
       - sass
@@ -8158,9 +7701,11 @@ packages:
       - sugarss
       - supports-color
       - terser
+      - tsx
+      - yaml
     dev: true
 
-  /vite-tsconfig-paths@4.3.2(typescript@5.7.3)(vite@6.2.0):
+  /vite-tsconfig-paths@4.3.2(typescript@5.8.3)(vite@6.2.5):
     resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==}
     peerDependencies:
       vite: '*'
@@ -8170,95 +7715,15 @@ packages:
     dependencies:
       debug: 4.4.0(supports-color@8.1.1)
       globrex: 0.1.2
-      tsconfck: 3.1.5(typescript@5.7.3)
-      vite: 6.2.0(@types/node@22.13.5)(sass@1.85.0)
+      tsconfck: 3.1.5(typescript@5.8.3)
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
     transitivePeerDependencies:
       - supports-color
       - typescript
     dev: true
 
-  /vite@5.4.14(@types/node@22.13.4)(sass@1.85.0):
-    resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
-    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: '*'
-      sass-embedded: '*'
-      stylus: '*'
-      sugarss: '*'
-      terser: ^5.4.0
-    peerDependenciesMeta:
-      '@types/node':
-        optional: true
-      less:
-        optional: true
-      lightningcss:
-        optional: true
-      sass:
-        optional: true
-      sass-embedded:
-        optional: true
-      stylus:
-        optional: true
-      sugarss:
-        optional: true
-      terser:
-        optional: true
-    dependencies:
-      '@types/node': 22.13.4
-      esbuild: 0.21.5
-      postcss: 8.5.3
-      rollup: 4.34.8
-      sass: 1.85.0
-    optionalDependencies:
-      fsevents: 2.3.3
-    dev: true
-
-  /vite@5.4.14(@types/node@22.13.5)(sass@1.85.0):
-    resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
-    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: '*'
-      sass-embedded: '*'
-      stylus: '*'
-      sugarss: '*'
-      terser: ^5.4.0
-    peerDependenciesMeta:
-      '@types/node':
-        optional: true
-      less:
-        optional: true
-      lightningcss:
-        optional: true
-      sass:
-        optional: true
-      sass-embedded:
-        optional: true
-      stylus:
-        optional: true
-      sugarss:
-        optional: true
-      terser:
-        optional: true
-    dependencies:
-      '@types/node': 22.13.5
-      esbuild: 0.21.5
-      postcss: 8.5.3
-      rollup: 4.34.8
-      sass: 1.85.0
-    optionalDependencies:
-      fsevents: 2.3.3
-    dev: true
-
-  /vite@6.1.1(@types/node@22.13.5)(sass-embedded@1.85.0)(sass@1.85.0):
-    resolution: {integrity: sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==}
+  /vite@6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3):
+    resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==}
     engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
     peerDependencies:
@@ -8297,140 +7762,35 @@ packages:
       yaml:
         optional: true
     dependencies:
-      '@types/node': 22.13.5
-      esbuild: 0.24.2
+      '@types/node': 22.14.0
+      esbuild: 0.25.2
       postcss: 8.5.3
-      rollup: 4.34.8
-      sass: 1.85.0
-      sass-embedded: 1.85.0
+      rollup: 4.39.0
+      sass: 1.86.3
+      sass-embedded: 1.86.3
     optionalDependencies:
       fsevents: 2.3.3
     dev: true
 
-  /vite@6.2.0(@types/node@22.13.5)(sass@1.85.0):
-    resolution: {integrity: sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==}
+  /vitest@3.1.1(@types/node@22.14.0)(sass@1.86.3):
+    resolution: {integrity: sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==}
     engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
     hasBin: true
-    peerDependencies:
-      '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
-      jiti: '>=1.21.0'
-      less: '*'
-      lightningcss: ^1.21.0
-      sass: '*'
-      sass-embedded: '*'
-      stylus: '*'
-      sugarss: '*'
-      terser: ^5.16.0
-      tsx: ^4.8.1
-      yaml: ^2.4.2
-    peerDependenciesMeta:
-      '@types/node':
-        optional: true
-      jiti:
-        optional: true
-      less:
-        optional: true
-      lightningcss:
-        optional: true
-      sass:
-        optional: true
-      sass-embedded:
-        optional: true
-      stylus:
-        optional: true
-      sugarss:
-        optional: true
-      terser:
-        optional: true
-      tsx:
-        optional: true
-      yaml:
-        optional: true
-    dependencies:
-      '@types/node': 22.13.5
-      esbuild: 0.25.0
-      postcss: 8.5.3
-      rollup: 4.34.8
-      sass: 1.85.0
-    optionalDependencies:
-      fsevents: 2.3.3
-    dev: true
-
-  /vitepress@1.6.3(@algolia/client-search@5.20.3)(@types/node@22.13.5)(axios@1.7.9)(postcss@8.5.3)(react-dom@19.0.0)(react@19.0.0)(sass@1.85.0)(search-insights@2.17.3)(typescript@5.7.3):
-    resolution: {integrity: sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw==}
-    hasBin: true
-    peerDependencies:
-      markdown-it-mathjax3: ^4
-      postcss: ^8
-    peerDependenciesMeta:
-      markdown-it-mathjax3:
-        optional: true
-      postcss:
-        optional: true
-    dependencies:
-      '@docsearch/css': 3.8.2
-      '@docsearch/js': 3.8.2(@algolia/client-search@5.20.3)(react-dom@19.0.0)(react@19.0.0)(search-insights@2.17.3)
-      '@iconify-json/simple-icons': 1.2.25
-      '@shikijs/core': 2.5.0
-      '@shikijs/transformers': 2.5.0
-      '@shikijs/types': 2.5.0
-      '@types/markdown-it': 14.1.2
-      '@vitejs/plugin-vue': 5.2.1(vite@5.4.14)(vue@3.5.13)
-      '@vue/devtools-api': 7.7.2
-      '@vue/shared': 3.5.13
-      '@vueuse/core': 12.7.0(typescript@5.7.3)
-      '@vueuse/integrations': 12.7.0(axios@1.7.9)(focus-trap@7.6.4)(typescript@5.7.3)
-      focus-trap: 7.6.4
-      mark.js: 8.11.1
-      minisearch: 7.1.2
-      postcss: 8.5.3
-      shiki: 2.5.0
-      vite: 5.4.14(@types/node@22.13.5)(sass@1.85.0)
-      vue: 3.5.13(typescript@5.7.3)
-    transitivePeerDependencies:
-      - '@algolia/client-search'
-      - '@types/node'
-      - '@types/react'
-      - async-validator
-      - axios
-      - change-case
-      - drauu
-      - fuse.js
-      - idb-keyval
-      - jwt-decode
-      - less
-      - lightningcss
-      - nprogress
-      - qrcode
-      - react
-      - react-dom
-      - sass
-      - sass-embedded
-      - search-insights
-      - sortablejs
-      - stylus
-      - sugarss
-      - terser
-      - typescript
-      - universal-cookie
-    dev: true
-
-  /vitest@0.34.6(sass@1.85.0):
-    resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
-    engines: {node: '>=v14.18.0'}
-    hasBin: true
     peerDependencies:
       '@edge-runtime/vm': '*'
-      '@vitest/browser': '*'
-      '@vitest/ui': '*'
+      '@types/debug': ^4.1.12
+      '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+      '@vitest/browser': 3.1.1
+      '@vitest/ui': 3.1.1
       happy-dom: '*'
       jsdom: '*'
-      playwright: '*'
-      safaridriver: '*'
-      webdriverio: '*'
     peerDependenciesMeta:
       '@edge-runtime/vm':
         optional: true
+      '@types/debug':
+        optional: true
+      '@types/node':
+        optional: true
       '@vitest/browser':
         optional: true
       '@vitest/ui':
@@ -8439,50 +7799,45 @@ packages:
         optional: true
       jsdom:
         optional: true
-      playwright:
-        optional: true
-      safaridriver:
-        optional: true
-      webdriverio:
-        optional: true
     dependencies:
-      '@types/chai': 4.3.20
-      '@types/chai-subset': 1.3.5
-      '@types/node': 22.13.4
-      '@vitest/expect': 0.34.6
-      '@vitest/runner': 0.34.6
-      '@vitest/snapshot': 0.34.6
-      '@vitest/spy': 0.34.6
-      '@vitest/utils': 0.34.6
-      acorn: 8.14.0
-      acorn-walk: 8.3.4
-      cac: 6.7.14
-      chai: 4.5.0
+      '@types/node': 22.14.0
+      '@vitest/expect': 3.1.1
+      '@vitest/mocker': 3.1.1(vite@6.2.5)
+      '@vitest/pretty-format': 3.1.1
+      '@vitest/runner': 3.1.1
+      '@vitest/snapshot': 3.1.1
+      '@vitest/spy': 3.1.1
+      '@vitest/utils': 3.1.1
+      chai: 5.2.0
       debug: 4.4.0(supports-color@8.1.1)
-      local-pkg: 0.4.3
+      expect-type: 1.2.1
       magic-string: 0.30.17
-      pathe: 1.1.2
-      picocolors: 1.1.1
-      std-env: 3.8.0
-      strip-literal: 1.3.0
+      pathe: 2.0.3
+      std-env: 3.9.0
       tinybench: 2.9.0
-      tinypool: 0.7.0
-      vite: 5.4.14(@types/node@22.13.4)(sass@1.85.0)
-      vite-node: 0.34.6(@types/node@22.13.4)(sass@1.85.0)
+      tinyexec: 0.3.2
+      tinypool: 1.0.2
+      tinyrainbow: 2.0.0
+      vite: 6.2.5(@types/node@22.14.0)(sass-embedded@1.86.3)(sass@1.86.3)
+      vite-node: 3.1.1(@types/node@22.14.0)(sass@1.86.3)
       why-is-node-running: 2.3.0
     transitivePeerDependencies:
+      - jiti
       - less
       - lightningcss
+      - msw
       - sass
       - sass-embedded
       - stylus
       - sugarss
       - supports-color
       - terser
+      - tsx
+      - yaml
     dev: true
 
-  /vue-component-type-helpers@2.2.2:
-    resolution: {integrity: sha512-6lLY+n2xz2kCYshl59mL6gy8OUUTmkscmDFMO8i7Lj+QKwgnIFUZmM1i/iTYObtrczZVdw7UakPqDTGwVSGaRg==}
+  /vue-component-type-helpers@2.2.8:
+    resolution: {integrity: sha512-4bjIsC284coDO9om4HPA62M7wfsTvcmZyzdfR0aUlFXqq4tXxM1APyXpNVxPC8QazKw9OhmZNHBVDA6ODaZsrA==}
     dev: true
 
   /vue-demi@0.14.10(vue@3.5.13):
@@ -8497,16 +7852,16 @@ packages:
       '@vue/composition-api':
         optional: true
     dependencies:
-      vue: 3.5.13(typescript@5.7.3)
+      vue: 3.5.13(typescript@5.8.3)
 
-  /vue-eslint-parser@9.4.3(eslint@9.20.1):
+  /vue-eslint-parser@9.4.3(eslint@9.24.0):
     resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=6.0.0'
     dependencies:
       debug: 4.4.0(supports-color@8.1.1)
-      eslint: 9.20.1
+      eslint: 9.24.0
       eslint-scope: 7.2.2
       eslint-visitor-keys: 3.4.3
       espree: 9.6.1
@@ -8517,16 +7872,16 @@ packages:
       - supports-color
     dev: true
 
-  /vue-i18n@9.14.2(vue@3.5.13):
-    resolution: {integrity: sha512-JK9Pm80OqssGJU2Y6F7DcM8RFHqVG4WkuCqOZTVsXkEzZME7ABejAUqUdA931zEBedc4thBgSUWxeQh4uocJAQ==}
+  /vue-i18n@9.14.4(vue@3.5.13):
+    resolution: {integrity: sha512-B934C8yUyWLT0EMud3DySrwSUJI7ZNiWYsEEz2gknTthqKiG4dzWE/WSa8AzCuSQzwBEv4HtG1jZDhgzPfWSKQ==}
     engines: {node: '>= 16'}
     peerDependencies:
       vue: ^3.0.0
     dependencies:
-      '@intlify/core-base': 9.14.2
-      '@intlify/shared': 9.14.2
+      '@intlify/core-base': 9.14.4
+      '@intlify/shared': 9.14.4
       '@vue/devtools-api': 6.6.4
-      vue: 3.5.13(typescript@5.7.3)
+      vue: 3.5.13(typescript@5.8.3)
 
   /vue-router@4.5.0(vue@3.5.13):
     resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==}
@@ -8534,9 +7889,9 @@ packages:
       vue: ^3.2.0
     dependencies:
       '@vue/devtools-api': 6.6.4
-      vue: 3.5.13(typescript@5.7.3)
+      vue: 3.5.13(typescript@5.8.3)
 
-  /vue@3.5.13(typescript@5.7.3):
+  /vue@3.5.13(typescript@5.8.3):
     resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==}
     peerDependencies:
       typescript: '*'
@@ -8549,7 +7904,7 @@ packages:
       '@vue/runtime-dom': 3.5.13
       '@vue/server-renderer': 3.5.13(vue@3.5.13)
       '@vue/shared': 3.5.13
-      typescript: 5.7.3
+      typescript: 5.8.3
 
   /w3c-keyname@2.2.8:
     resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
@@ -8591,10 +7946,63 @@ packages:
     engines: {node: '>=12'}
     dev: true
 
+  /which-boxed-primitive@1.1.1:
+    resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-bigint: 1.1.0
+      is-boolean-object: 1.2.2
+      is-number-object: 1.1.1
+      is-string: 1.1.1
+      is-symbol: 1.1.1
+    dev: true
+
+  /which-builtin-type@1.2.1:
+    resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      call-bound: 1.0.4
+      function.prototype.name: 1.1.8
+      has-tostringtag: 1.0.2
+      is-async-function: 2.1.1
+      is-date-object: 1.1.0
+      is-finalizationregistry: 1.1.1
+      is-generator-function: 1.1.0
+      is-regex: 1.2.1
+      is-weakref: 1.1.1
+      isarray: 2.0.5
+      which-boxed-primitive: 1.1.1
+      which-collection: 1.0.2
+      which-typed-array: 1.1.19
+    dev: true
+
+  /which-collection@1.0.2:
+    resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      is-map: 2.0.3
+      is-set: 2.0.3
+      is-weakmap: 2.0.2
+      is-weakset: 2.0.4
+    dev: true
+
   /which-module@2.0.1:
     resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
     dev: true
 
+  /which-typed-array@1.1.19:
+    resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
+    engines: {node: '>= 0.4'}
+    dependencies:
+      available-typed-arrays: 1.0.7
+      call-bind: 1.0.8
+      call-bound: 1.0.4
+      for-each: 0.3.5
+      get-proto: 1.0.1
+      gopd: 1.2.0
+      has-tostringtag: 1.0.2
+    dev: true
+
   /which@2.0.2:
     resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
     engines: {node: '>= 8'}
@@ -8700,7 +8108,7 @@ packages:
     resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==}
     engines: {node: '>=4.0.0'}
     dependencies:
-      sax: 1.1.4
+      sax: 1.4.1
       xmlbuilder: 11.0.1
     dev: true
 
@@ -8715,11 +8123,11 @@ packages:
       sax: 1.4.1
     dev: true
 
-  /xunit-viewer@10.6.1(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0):
+  /xunit-viewer@10.6.1(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0):
     resolution: {integrity: sha512-ZMprLPVhCQJf2KD56tv2hlOjc4T+KnUe1E9DkEBHnuliOq7IOXWJf61pxyBMo/7H83B7Ln0DIeWNMMbx/3I7Jg==}
     hasBin: true
     dependencies:
-      '@uiw/react-codemirror': 4.23.8(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.3)(codemirror@6.0.1)(react-dom@19.0.0)(react@19.0.0)
+      '@uiw/react-codemirror': 4.23.10(@babel/runtime@7.27.0)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.11.0)(@codemirror/lint@6.8.5)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.36.5)(codemirror@6.0.1)(react-dom@19.1.0)(react@19.1.0)
       chalk: 5.4.1
       chokidar: 3.6.0
       console-clear: 1.1.1
@@ -8764,17 +8172,18 @@ packages:
     resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
     dev: false
 
-  /yaml-eslint-parser@0.3.2:
-    resolution: {integrity: sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==}
+  /yaml-eslint-parser@1.3.0:
+    resolution: {integrity: sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==}
+    engines: {node: ^14.17.0 || >=16.0.0}
     dependencies:
-      eslint-visitor-keys: 1.3.0
-      lodash: 4.17.21
-      yaml: 1.10.2
+      eslint-visitor-keys: 3.4.3
+      yaml: 2.7.1
     dev: true
 
-  /yaml@1.10.2:
-    resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
-    engines: {node: '>= 6'}
+  /yaml@2.7.1:
+    resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==}
+    engines: {node: '>= 14'}
+    hasBin: true
     dev: true
 
   /yargs-parser@18.1.3:
@@ -8841,8 +8250,8 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /yocto-queue@1.1.1:
-    resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==}
+  /yocto-queue@1.2.1:
+    resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==}
     engines: {node: '>=12.20'}
     dev: true
 
@@ -8859,7 +8268,3 @@ packages:
       compress-commons: 6.0.2
       readable-stream: 4.7.0
     dev: true
-
-  /zwitch@2.0.4:
-    resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
-    dev: true
diff --git a/quasar.config.js b/quasar.config.js
index 8b6125a90..2bc0be37f 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -53,7 +53,7 @@ export default configure(function (/* ctx */) {
         build: {
             target: {
                 browser: ['es2022', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
-                node: 'node18',
+                node: 'node20',
             },
 
             vueRouterMode: 'hash', // available values: 'hash', 'history'
@@ -92,6 +92,7 @@ export default configure(function (/* ctx */) {
             vitePlugins: [
                 [
                     VueI18nPlugin({
+                        strictMessage: false,
                         runtimeOnly: false,
                         include: [
                             path.resolve(__dirname, './src/i18n/locale/**'),
diff --git a/quasar.config.js.temporary.compiled.1744020058024.mjs b/quasar.config.js.temporary.compiled.1744020058024.mjs
new file mode 100644
index 000000000..54ecb84d9
--- /dev/null
+++ b/quasar.config.js.temporary.compiled.1744020058024.mjs
@@ -0,0 +1,227 @@
+/* eslint-disable */
+/**
+ * THIS FILE IS GENERATED AUTOMATICALLY.
+ * 1. DO NOT edit this file directly as it won't do anything.
+ * 2. EDIT the original quasar.config file INSTEAD.
+ * 3. DO NOT git commit this file. It should be ignored.
+ *
+ * This file is still here because there was an error in
+ * the original quasar.config file and this allows you to
+ * investigate the Node.js stack error.
+ *
+ * After you fix the original file, this file will be
+ * deleted automatically.
+ **/
+
+
+// quasar.config.js
+import { configure } from "quasar/wrappers";
+import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
+import path from "path";
+var __quasar_inject_dirname__ = "/home/jsegarra/Projects/salix-front";
+var target = `http://${process.env.CI ? "back" : "localhost"}:3000`;
+var quasar_config_default = configure(function() {
+  return {
+    eslint: {
+      // fix: true,
+      // include = [],
+      // exclude = [],
+      // rawOptions = {},
+      warnings: true,
+      errors: true
+    },
+    // https://v2.quasar.dev/quasar-cli/prefetch-feature
+    // preFetch: true,
+    // app boot file (/src/boot)
+    // --> boot files are part of "main.js"
+    // https://v2.quasar.dev/quasar-cli/boot-files
+    boot: ["i18n", "axios", "vnDate", "validations", "quasar", "quasar.defaults"],
+    // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
+    css: ["app.scss"],
+    // https://github.com/quasarframework/quasar/tree/dev/extras
+    extras: [
+      // 'ionicons-v4',
+      // 'mdi-v5',
+      // 'fontawesome-v6',
+      // 'eva-icons',
+      // 'themify',
+      // 'line-awesome',
+      // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
+      "roboto-font",
+      "material-icons-outlined",
+      "material-symbols-outlined"
+    ],
+    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
+    build: {
+      target: {
+        browser: ["es2022", "edge88", "firefox78", "chrome87", "safari13.1"],
+        node: "node20"
+      },
+      vueRouterMode: "hash",
+      // available values: 'hash', 'history'
+      // vueRouterBase,
+      // vueDevtools,
+      // vueOptionsAPI: false,
+      // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup
+      // publicPath: '/',
+      // analyze: true,
+      // env: {},
+      rawDefine: {
+        "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
+      },
+      // ignorePublicFolder: true,
+      // minify: false,
+      // polyfillModulePreload: true,
+      // distDir
+      extendViteConf(viteConf) {
+        delete viteConf.build.polyfillModulePreload;
+        viteConf.build.modulePreload = {
+          polyfill: false
+        };
+      },
+      // viteVuePluginOptions: {},
+      alias: {
+        composables: path.join(__quasar_inject_dirname__, "./src/composables"),
+        filters: path.join(__quasar_inject_dirname__, "./src/filters")
+      },
+      vitePlugins: [
+        [
+          VueI18nPlugin({
+            strictMessage: false,
+            runtimeOnly: false,
+            include: [
+              path.resolve(__quasar_inject_dirname__, "./src/i18n/locale/**"),
+              path.resolve(__quasar_inject_dirname__, "./src/pages/**/locale/**")
+            ]
+          })
+        ]
+      ]
+    },
+    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
+    devServer: {
+      server: {
+        type: "http"
+      },
+      proxy: {
+        "/api": {
+          target,
+          logLevel: "debug",
+          changeOrigin: true,
+          secure: false
+        }
+      },
+      open: false,
+      allowedHosts: [
+        "front",
+        // Agrega este nombre de host
+        "localhost"
+        // Opcional, para pruebas locales
+      ]
+    },
+    // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
+    framework: {
+      config: {
+        config: {
+          dark: "auto"
+        }
+      },
+      lang: "en-GB",
+      // iconSet: 'material-icons', // Quasar icon set
+      // lang: 'en-US', // Quasar language pack
+      // For special cases outside of where the auto-import strategy can have an impact
+      // (like functional components as one of the examples),
+      // you can manually specify Quasar components/directives to be available everywhere:
+      //
+      // components: [],
+      // directives: [],
+      // Quasar plugins
+      plugins: ["Notify", "Dialog"],
+      all: "auto",
+      autoImportComponentCase: "pascal"
+    },
+    // animations: 'all', // --- includes all animations
+    // https://v2.quasar.dev/options/animations
+    animations: [],
+    // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles
+    // sourceFiles: {
+    //   rootComponent: 'src/App.vue',
+    //   router: 'src/router/index',
+    //   store: 'src/store/index',
+    //   registerServiceWorker: 'src-pwa/register-service-worker',
+    //   serviceWorker: 'src-pwa/custom-service-worker',
+    //   pwaManifestFile: 'src-pwa/manifest.json',
+    //   electronMain: 'src-electron/electron-main',
+    //   electronPreload: 'src-electron/electron-preload'
+    // },
+    // https://v2.quasar.dev/quasar-cli/developing-ssr/configuring-ssr
+    ssr: {
+      // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
+      // will mess up SSR
+      // extendSSRWebserverConf (esbuildConf) {},
+      // extendPackageJson (json) {},
+      pwa: false,
+      // manualStoreHydration: true,
+      // manualPostHydrationTrigger: true,
+      prodPort: 3e3,
+      // The default port that the production server should use
+      // (gets superseded if process.env.PORT is specified at runtime)
+      middlewares: [
+        "render"
+        // keep this as last one
+      ]
+    },
+    // https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
+    pwa: {
+      workboxMode: "generateSW",
+      // or 'injectManifest'
+      injectPwaMetaTags: true,
+      swFilename: "sw.js",
+      manifestFilename: "manifest.json",
+      useCredentialsForManifestTag: false
+      // useFilenameHashes: true,
+      // extendGenerateSWOptions (cfg) {}
+      // extendInjectManifestOptions (cfg) {},
+      // extendManifestJson (json) {}
+      // extendPWACustomSWConf (esbuildConf) {}
+    },
+    // Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
+    cordova: {
+      // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
+    },
+    // Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
+    capacitor: {
+      hideSplashscreen: true
+    },
+    // Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
+    electron: {
+      // extendElectronMainConf (esbuildConf)
+      // extendElectronPreloadConf (esbuildConf)
+      inspectPort: 5858,
+      bundler: "packager",
+      // 'packager' or 'builder'
+      packager: {
+        // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
+        // OS X / Mac App Store
+        // appBundleId: '',
+        // appCategoryType: '',
+        // osxSign: '',
+        // protocol: 'myapp://path',
+        // Windows only
+        // win32metadata: { ... }
+      },
+      builder: {
+        // https://www.electron.build/configuration/configuration
+        appId: "salix-frontend"
+      }
+    },
+    // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
+    bex: {
+      contentScripts: ["my-content-script"]
+      // extendBexScriptsConf (esbuildConf) {}
+      // extendBexManifestJson (json) {}
+    }
+  };
+});
+export {
+  quasar_config_default as default
+};
diff --git a/src/boot/__tests__/axios.spec.js b/src/boot/__tests__/axios.spec.js
index 7dffaefc1..85d578517 100644
--- a/src/boot/__tests__/axios.spec.js
+++ b/src/boot/__tests__/axios.spec.js
@@ -9,6 +9,30 @@ vi.mock('src/composables/useSession', () => ({
     }),
 }));
 
+// Mock axios
+vi.mock('axios', () => ({
+    default: {
+        create: vi.fn(() => ({
+            interceptors: {
+                request: { use: vi.fn() },
+                response: { use: vi.fn() },
+            },
+        })),
+        interceptors: {
+            request: { use: vi.fn() },
+            response: { use: vi.fn() },
+        },
+        defaults: {
+            baseURL: '',
+        },
+    },
+}));
+
+vi.mock('src/router', () => ({
+    Router: {
+        push: vi.fn(),
+    },
+}));
 vi.mock('src/stores/useStateQueryStore', () => ({
     useStateQueryStore: () => ({
         add: () => vi.fn(),
@@ -29,7 +53,7 @@ describe('Axios boot', () => {
                         'Accept-Language': 'en-US',
                         Authorization: 'DEFAULT_TOKEN',
                     },
-                })
+                }),
             );
         });
     });
diff --git a/src/boot/quasar.defaults.js b/src/boot/quasar.defaults.js
index 9638e2057..e2b195b16 100644
--- a/src/boot/quasar.defaults.js
+++ b/src/boot/quasar.defaults.js
@@ -1,3 +1,4 @@
+/* eslint-disable eslint/export */
 export * from './defaults/qTable';
 export * from './defaults/qInput';
 export * from './defaults/qSelect';
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index c4d9a4149..1fec1e6c9 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -13,13 +13,12 @@ import VnConfirm from './ui/VnConfirm.vue';
 import { tMobile } from 'src/composables/tMobile';
 import { useArrayData } from 'src/composables/useArrayData';
 import { getDifferences, getUpdatedValues } from 'src/filters';
-
 const { push } = useRouter();
 const quasar = useQuasar();
 const state = useState();
 const stateStore = useStateStore();
 const { t } = useI18n();
-const { validate } = useValidator();
+const { validate, validations } = useValidator();
 const { notify } = useNotify();
 const route = useRoute();
 const myForm = ref(null);
@@ -119,7 +118,7 @@ const defaultButtons = computed(() => ({
         color: 'primary',
         icon: 'save',
         label: 'globals.save',
-        click: async () => await save(),
+        click: async (evt) => submitForm(evt),
         type: 'submit',
     },
     reset: {
@@ -132,6 +131,13 @@ const defaultButtons = computed(() => ({
     ...$props.defaultButtons,
 }));
 
+const submitForm = async (evt) => {
+    const isFormValid = await myForm.value.validate();
+    if (isFormValid) {
+        await save(evt);
+    }
+};
+
 onMounted(async () => {
     nextTick(() => (componentIsRendered.value = true));
 
@@ -227,10 +233,9 @@ async function save() {
         const method = $props.urlCreate ? 'post' : 'patch';
         const url =
             $props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
-        let response;
-
-        if ($props.saveFn) response = await $props.saveFn(body);
-        else response = await axios[method](url, body);
+        const response = await Promise.resolve(
+            $props.saveFn ? $props.saveFn(body) : axios[method](url, body),
+        );
 
         if ($props.urlCreate) notify('globals.dataCreated', 'positive');
 
@@ -307,11 +312,13 @@ async function onKeyup(evt) {
             selectionStart = selectionEnd = selectionStart + 1;
             return;
         }
-        await save();
+        await myForm.value.submit(evt);
     }
 }
 
 defineExpose({
+    submitForm,
+    myForm,
     save,
     isLoading,
     hasChanges,
@@ -325,7 +332,7 @@ defineExpose({
         <QForm
             ref="myForm"
             v-if="formData"
-            @submit.prevent
+            @submit.prevent="save"
             @keyup.prevent="onKeyup"
             @reset="reset"
             class="q-pa-md"
@@ -339,6 +346,7 @@ defineExpose({
                     name="form"
                     :data="formData"
                     :validate="validate"
+                    :validations="validations()"
                     :filter="filter"
                 />
                 <SkeletonForm v-else />
diff --git a/src/components/FormModelPopup.vue b/src/components/FormModelPopup.vue
index 85943e91e..34aec96d8 100644
--- a/src/components/FormModelPopup.vue
+++ b/src/components/FormModelPopup.vue
@@ -41,9 +41,12 @@ const onDataSaved = async (formData, requestResponse) => {
     emit('onDataSaved', formData, requestResponse);
 };
 
-const onClick = async (saveAndContinue) => {
+const onClick = async (saveAndContinue = showSaveAndContinueBtn) => {
+    await formModelRef.value.myForm.validate(true);
     isSaveAndContinue.value = saveAndContinue;
-    await formModelRef.value.save();
+    if (formModelRef.value) {
+        await formModelRef.value.submitForm();
+    }
 };
 
 defineExpose({
@@ -59,16 +62,23 @@ defineExpose({
         ref="formModelRef"
         :observe-form-changes="false"
         :default-actions="false"
+        @submit="onClick"
         v-bind="$attrs"
         @on-data-saved="onDataSaved"
+        :prevent-submit="false"
     >
-        <template #form="{ data, validate }">
+        <template #form="{ data, validate, validations }">
             <span ref="closeButton" class="close-icon" v-close-popup>
                 <QIcon name="close" size="sm" />
             </span>
             <h1 class="title">{{ title }}</h1>
             <p>{{ subtitle }}</p>
-            <slot name="form-inputs" :data="data" :validate="validate" />
+            <slot
+                name="form-inputs"
+                :data="data"
+                :validate="validate"
+                :validations="validations"
+            />
             <div class="q-mt-lg row justify-end">
                 <QBtn
                     :label="t('globals.cancel')"
@@ -87,12 +97,13 @@ defineExpose({
                     :flat="showSaveAndContinueBtn"
                     :label="t('globals.save')"
                     :title="t('globals.save')"
-                    @click="onClick(false)"
+                    :type="!showSaveAndContinueBtn ? 'submit' : 'button'"
                     color="primary"
                     class="q-ml-sm"
                     :disabled="isLoading"
                     :loading="isLoading"
                     data-cy="FormModelPopup_save"
+                    @click="showSaveAndContinueBtn ? onClick(false) : null"
                     z-max
                 />
                 <QBtn
@@ -100,12 +111,13 @@ defineExpose({
                     :label="t('globals.isSaveAndContinue')"
                     :title="t('globals.isSaveAndContinue')"
                     color="primary"
+                    :type="showSaveAndContinueBtn ? 'submit' : 'button'"
                     class="q-ml-sm"
                     :disabled="isLoading"
                     :loading="isLoading"
                     data-cy="FormModelPopup_isSaveAndContinue"
+                    @click="showSaveAndContinueBtn ? onClick(true) : null"
                     z-max
-                    @click="onClick(true)"
                 />
             </div>
         </template>
diff --git a/src/components/NavBar.vue b/src/components/NavBar.vue
index dbb6f1fe6..7329ddae2 100644
--- a/src/components/NavBar.vue
+++ b/src/components/NavBar.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref } from 'vue';
+import { onMounted, ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useState } from 'src/composables/useState';
 import { useStateStore } from 'stores/useStateStore';
@@ -18,6 +18,14 @@ const state = useState();
 const user = state.getUser();
 const appName = 'Lilium';
 const pinnedModulesRef = ref();
+const hostname = window.location.hostname;
+const env = ref();
+
+const getEnvironment = computed(() => {
+    env.value = hostname.split('-');
+    if (env.value.length <= 1) return;
+    return env.value[0];
+});
 
 onMounted(() => stateStore.setMounted());
 const refresh = () => window.location.reload();
@@ -49,6 +57,9 @@ const refresh = () => window.location.reload();
                         {{ t('globals.backToDashboard') }}
                     </QTooltip>
                 </QBtn>
+                <QBadge v-if="getEnvironment" color="primary" align="top">
+                    {{ getEnvironment }}
+                </QBadge>
             </RouterLink>
             <VnBreadcrumbs v-if="$q.screen.gt.sm" />
             <QSpinner
diff --git a/src/components/TicketProblems.vue b/src/components/TicketProblems.vue
index 59be95035..c15e31d80 100644
--- a/src/components/TicketProblems.vue
+++ b/src/components/TicketProblems.vue
@@ -17,17 +17,6 @@ defineProps({ row: { type: Object, required: true } });
                 </QTooltip>
             </QIcon>
         </router-link>
-        <QIcon
-            v-if="row?.reserved"
-            color="primary"
-            name="vn:reserva"
-            size="xs"
-            data-cy="ticketSaleReservedIcon"
-        >
-            <QTooltip>
-                {{ t('ticketSale.reserved') }}
-            </QTooltip>
-        </QIcon>
         <QIcon
             v-if="row?.isDeleted"
             color="primary"
diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue
index d0e245388..3ce62c5de 100644
--- a/src/components/VnTable/VnColumn.vue
+++ b/src/components/VnTable/VnColumn.vue
@@ -55,6 +55,8 @@ const $props = defineProps({
     },
 });
 
+const label = $props.showLabel && $props.column.label ? $props.column.label : '';
+
 const defaultSelect = {
     attrs: {
         row: $props.row,
@@ -62,7 +64,7 @@ const defaultSelect = {
         class: 'fit',
     },
     forceAttrs: {
-        label: $props.showLabel && $props.column.label,
+        label,
     },
 };
 
@@ -74,7 +76,7 @@ const defaultComponents = {
             class: 'fit',
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     number: {
@@ -84,7 +86,7 @@ const defaultComponents = {
             class: 'fit',
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     date: {
@@ -96,7 +98,7 @@ const defaultComponents = {
             class: 'fit',
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     time: {
@@ -105,7 +107,7 @@ const defaultComponents = {
             disable: !$props.isEditable,
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
         },
     },
     checkbox: {
@@ -125,7 +127,7 @@ const defaultComponents = {
             return defaultAttrs;
         },
         forceAttrs: {
-            label: $props.showLabel && $props.column.label,
+            label,
             autofocus: true,
         },
         events: {
diff --git a/src/components/VnTable/VnOrder.vue b/src/components/VnTable/VnOrder.vue
index 47ed9acf4..fe071a57f 100644
--- a/src/components/VnTable/VnOrder.vue
+++ b/src/components/VnTable/VnOrder.vue
@@ -70,7 +70,7 @@ function textAlignToFlex(textAlign) {
         :style="textAlignToFlex(align)"
     >
         <span :title="label">{{ label }}</span>
-        <div v-if="name && model?.index">
+        <div v-if="name && (model?.index || vertical)">
             <QChip
                 :label="!vertical ? model?.index : ''"
                 :icon="
@@ -83,14 +83,14 @@ function textAlignToFlex(textAlign) {
                 :size="vertical ? '' : 'sm'"
                 :class="[
                     model?.index ? 'color-vn-text' : 'bg-transparent',
-                    vertical ? 'q-px-none' : '',
+                    vertical ? 'q-mx-none q-py-lg' : '',
                 ]"
                 class="no-box-shadow"
                 :clickable="true"
                 style="min-width: 40px; max-height: 30px"
             >
                 <div
-                    class="column flex-center"
+                    class="column justify-center text-center"
                     v-if="vertical"
                     :style="!model?.index && 'color: #5d5d5d'"
                 >
diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index e214770d2..b8494a875 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -19,6 +19,7 @@ import { useQuasar, date } from 'quasar';
 import { useStateStore } from 'stores/useStateStore';
 import { useFilterParams } from 'src/composables/useFilterParams';
 import { dashIfEmpty, toDate } from 'src/filters';
+import { useTableHeight } from './filters/useTableHeight';
 
 import CrudModel from 'src/components/CrudModel.vue';
 import FormModelPopup from 'components/FormModelPopup.vue';
@@ -117,7 +118,7 @@ const $props = defineProps({
     },
     tableHeight: {
         type: String,
-        default: '90vh',
+        default: undefined,
     },
     footer: {
         type: Boolean,
@@ -166,6 +167,7 @@ const tableRef = ref();
 const params = ref(useFilterParams($attrs['data-key']).params);
 const orders = ref(useFilterParams($attrs['data-key']).orders);
 const app = inject('app');
+const tableHeight = useTableHeight();
 
 const editingRow = ref(null);
 const editingField = ref(null);
@@ -678,7 +680,7 @@ const rowCtrlClickFunction = computed(() => {
                 table-header-class="bg-header"
                 card-container-class="grid-three"
                 flat
-                :style="isTableMode && `max-height: ${tableHeight}`"
+                :style="isTableMode && `max-height: ${$props.tableHeight || tableHeight}`"
                 :virtual-scroll="isTableMode"
                 @virtual-scroll="handleScroll"
                 @row-click="(event, row) => handleRowClick(event, row)"
@@ -1042,7 +1044,7 @@ const rowCtrlClickFunction = computed(() => {
             :model="$attrs['data-key'] + 'Create'"
             @on-data-saved="(_, res) => createForm.onDataSaved(res)"
         >
-            <template #form-inputs="{ data }">
+            <template #form-inputs="{ data, validations }">
                 <slot name="alter-create" :data="data">
                     <div :style="createComplement?.containerStyle">
                         <div
@@ -1060,6 +1062,7 @@ const rowCtrlClickFunction = computed(() => {
                                 :key="column.name"
                                 :name="`column-create-${column.name}`"
                                 :data="data"
+                                :validations="validations"
                                 :column-name="column.name"
                                 :label="column.label"
                             >
diff --git a/src/components/VnTable/VnTableFilter.vue b/src/components/VnTable/VnTableFilter.vue
index 79b903e54..109e2b77e 100644
--- a/src/components/VnTable/VnTableFilter.vue
+++ b/src/components/VnTable/VnTableFilter.vue
@@ -26,7 +26,12 @@ function columnName(col) {
 }
 </script>
 <template>
-    <VnFilterPanel v-bind="$attrs" :search-button="true" :disable-submit-event="true">
+    <VnFilterPanel
+        v-bind="$attrs"
+        :search-button="true"
+        :disable-submit-event="true"
+        :search-url
+    >
         <template #body="{ params, orders, searchFn }">
             <div
                 class="container"
@@ -34,13 +39,20 @@ function columnName(col) {
                 :key="col.id"
             >
                 <div class="filter">
-                    <VnFilter
-                        ref="tableFilterRef"
-                        :column="col"
-                        :data-key="$attrs['data-key']"
-                        v-model="params[columnName(col)]"
-                        :search-url="searchUrl"
-                    />
+                    <slot
+                        :name="`filter-${col.name}`"
+                        :params="params"
+                        :column-name="columnName(col)"
+                        :search-fn
+                    >
+                        <VnFilter
+                            ref="tableFilterRef"
+                            :column="col"
+                            :data-key="$attrs['data-key']"
+                            v-model="params[columnName(col)]"
+                            :search-url="searchUrl"
+                        />
+                    </slot>
                 </div>
                 <div class="order">
                     <VnTableOrder
@@ -77,13 +89,13 @@ function columnName(col) {
     display: flex;
     justify-content: center;
     align-items: center;
-    height: 45px;
+    min-height: 45px;
     gap: 10px;
 }
 
 .filter {
     width: 70%;
-    height: 40px;
+    min-height: 40px;
     text-align: center;
 }
 .order {
diff --git a/src/components/VnTable/__tests__/VnVisibleColumns.spec.js b/src/components/VnTable/__tests__/VnVisibleColumns.spec.js
index bf767688b..3e4e9ecc8 100644
--- a/src/components/VnTable/__tests__/VnVisibleColumns.spec.js
+++ b/src/components/VnTable/__tests__/VnVisibleColumns.spec.js
@@ -1,8 +1,7 @@
 import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest';
 import { createWrapper } from 'app/test/vitest/helper';
 import VnVisibleColumn from '../VnVisibleColumn.vue';
-import { axios } from 'app/test/vitest/helper';
-
+import { default as axios } from 'axios';
 describe('VnVisibleColumns', () => {
     let wrapper;
     let vm;
diff --git a/src/components/VnTable/filters/useTableHeight.js b/src/components/VnTable/filters/useTableHeight.js
new file mode 100644
index 000000000..2397ce16f
--- /dev/null
+++ b/src/components/VnTable/filters/useTableHeight.js
@@ -0,0 +1,18 @@
+import { onMounted, nextTick, ref } from 'vue';
+
+export function useTableHeight() {
+    const tableHeight = ref('90vh');
+
+    onMounted(async () => {
+        await nextTick();
+        let height = 100;
+        Array.from(document.querySelectorAll('[role="toolbar"]'))
+            .filter((element) => window.getComputedStyle(element).display !== 'none')
+            .forEach(() => {
+                height -= 10;
+            });
+        tableHeight.value = `${height}vh`;
+    });
+
+    return tableHeight;
+}
diff --git a/src/components/__tests__/CrudModel.spec.js b/src/components/__tests__/CrudModel.spec.js
index f6c93e0d5..c620d29ad 100644
--- a/src/components/__tests__/CrudModel.spec.js
+++ b/src/components/__tests__/CrudModel.spec.js
@@ -1,4 +1,6 @@
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
+
 import CrudModel from 'components/CrudModel.vue';
 import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest';
 
diff --git a/src/components/__tests__/EditTableCellValueForm.spec.js b/src/components/__tests__/EditTableCellValueForm.spec.js
index fa47d8f73..acba27519 100644
--- a/src/components/__tests__/EditTableCellValueForm.spec.js
+++ b/src/components/__tests__/EditTableCellValueForm.spec.js
@@ -1,4 +1,5 @@
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
 import EditForm from 'components/EditTableCellValueForm.vue';
 import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest';
 
diff --git a/src/components/__tests__/FilterItemForm.spec.js b/src/components/__tests__/FilterItemForm.spec.js
index 210d6bf02..fb8332c31 100644
--- a/src/components/__tests__/FilterItemForm.spec.js
+++ b/src/components/__tests__/FilterItemForm.spec.js
@@ -1,4 +1,6 @@
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
+
 import FilterItemForm from 'src/components/FilterItemForm.vue';
 import { vi, beforeAll, describe, expect, it } from 'vitest';
 
@@ -38,9 +40,9 @@ describe('FilterItemForm', () => {
                 { relation: 'producer', scope: { fields: ['name'] } },
                 { relation: 'ink', scope: { fields: ['name'] } },
             ],
-            where: {"name":{"like":"%bolas de madera%"}},
+            where: { name: { like: '%bolas de madera%' } },
         };
-        
+
         expect(axios.get).toHaveBeenCalledWith('Items/withName', {
             params: { filter: JSON.stringify(expectedFilter) },
         });
@@ -79,4 +81,4 @@ describe('FilterItemForm', () => {
         vm.selectItem({ id: 12345 });
         expect(wrapper.emitted('itemSelected')[0]).toEqual([12345]);
     });
-});
\ No newline at end of file
+});
diff --git a/src/components/__tests__/FormModel.spec.js b/src/components/__tests__/FormModel.spec.js
index 3dce04374..20e99b55b 100644
--- a/src/components/__tests__/FormModel.spec.js
+++ b/src/components/__tests__/FormModel.spec.js
@@ -1,5 +1,7 @@
 import { describe, expect, it, beforeAll, vi, afterAll } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
+
 import FormModel from 'src/components/FormModel.vue';
 
 describe('FormModel', () => {
diff --git a/src/components/__tests__/Leftmenu.spec.js b/src/components/__tests__/Leftmenu.spec.js
index 0bcc587ac..22b2b5fb7 100644
--- a/src/components/__tests__/Leftmenu.spec.js
+++ b/src/components/__tests__/Leftmenu.spec.js
@@ -1,6 +1,7 @@
-import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
-import Leftmenu from 'components/LeftMenu.vue';
+import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest';
+import { default as axios } from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
+import LeftMenu from 'components/LeftMenu.vue';
 import * as vueRouter from 'vue-router';
 import { useNavigationStore } from 'src/stores/useNavigationStore';
 
@@ -101,7 +102,7 @@ function mount(source = 'main') {
     vi.spyOn(axios, 'get').mockResolvedValue({
         data: [],
     });
-    const wrapper = createWrapper(Leftmenu, {
+    const wrapper = createWrapper(LeftMenu, {
         propsData: {
             source,
         },
@@ -164,7 +165,7 @@ describe('getRoutes', () => {
     });
 });
 
-describe('Leftmenu as card', () => {
+describe('LeftMenu as card', () => {
     beforeAll(() => {
         vm = mount('card').vm;
     });
@@ -173,7 +174,7 @@ describe('Leftmenu as card', () => {
         vm.getRoutes();
     });
 });
-describe('Leftmenu as main', () => {
+describe('LeftMenu as main', () => {
     beforeEach(() => {
         vm = mount().vm;
     });
diff --git a/src/components/common/SendEmailDialog.vue b/src/components/common/SendEmailDialog.vue
index 254eb9cf9..a8209bdf7 100644
--- a/src/components/common/SendEmailDialog.vue
+++ b/src/components/common/SendEmailDialog.vue
@@ -60,7 +60,7 @@ async function confirm() {
                     v-model="address"
                     is-outlined
                     autofocus
-                    data-cy="SendEmailNotifiactionDialogInput"
+                    data-cy="SendEmailNotificationDialogInput"
                 />
             </QCardSection>
             <QCardActions align="right">
diff --git a/src/components/common/SendSmsDialog.vue b/src/components/common/SendSmsDialog.vue
index 269a4ec9a..a953abd75 100644
--- a/src/components/common/SendSmsDialog.vue
+++ b/src/components/common/SendSmsDialog.vue
@@ -1,15 +1,15 @@
 <script setup>
-import {useDialogPluginComponent} from 'quasar';
-import {useI18n} from 'vue-i18n';
-import {computed, ref} from 'vue';
+import { useDialogPluginComponent } from 'quasar';
+import { useI18n } from 'vue-i18n';
+import { computed, ref } from 'vue';
 import VnInput from 'components/common/VnInput.vue';
 import axios from 'axios';
-import useNotify from "composables/useNotify";
+import useNotify from 'composables/useNotify';
 
 const MESSAGE_MAX_LENGTH = 160;
 
-const {t} = useI18n();
-const {notify} = useNotify();
+const { t } = useI18n();
+const { notify } = useNotify();
 const props = defineProps({
     title: {
         type: String,
@@ -34,7 +34,7 @@ const props = defineProps({
 });
 
 const emit = defineEmits([...useDialogPluginComponent.emits, 'sent']);
-const {dialogRef, onDialogHide} = useDialogPluginComponent();
+const { dialogRef, onDialogHide } = useDialogPluginComponent();
 
 const smsRules = [
     (val) => (val && val.length > 0) || t("The message can't be empty"),
@@ -43,10 +43,10 @@ const smsRules = [
         t("The message it's too long"),
 ];
 
-const message = ref('');
+const message = ref(t('routeDelay'));
 
 const charactersRemaining = computed(
-    () => MESSAGE_MAX_LENGTH - new Blob([message.value]).size
+    () => MESSAGE_MAX_LENGTH - new Blob([message.value]).size,
 );
 
 const charactersChipColor = computed(() => {
@@ -114,7 +114,7 @@ const onSubmit = async () => {
                                 <QTooltip>
                                     {{
                                         t(
-                                            'Special characters like accents counts as a multiple'
+                                            'Special characters like accents counts as a multiple',
                                         )
                                     }}
                                 </QTooltip>
@@ -144,7 +144,10 @@ const onSubmit = async () => {
     max-width: 450px;
 }
 </style>
+
 <i18n>
+en:
+    routeDelay: "Your order has been delayed in transit.\nDelivery will take place throughout the day.\nWe apologize for the inconvenience and appreciate your patience."
 es:
     Message: Mensaje
     Send: Enviar
@@ -153,4 +156,5 @@ es:
     The destination can't be empty: El destinatario no puede estar vacio
     The message can't be empty: El mensaje no puede estar vacio
     The message it's too long: El mensaje es demasiado largo
-</i18n>
+    routeDelay: "Retraso en ruta.\nInformamos que la ruta que lleva su pedido ha sufrido un retraso y la entrega se hará a lo largo del día.\nDisculpe las molestias."
+    </i18n>
diff --git a/src/components/common/VnAccountNumber.vue b/src/components/common/VnAccountNumber.vue
index 56add7329..8bff3e261 100644
--- a/src/components/common/VnAccountNumber.vue
+++ b/src/components/common/VnAccountNumber.vue
@@ -1,35 +1,14 @@
 <script setup>
-import { nextTick, ref } from 'vue';
 import VnInput from './VnInput.vue';
 import { useAccountShortToStandard } from 'src/composables/useAccountShortToStandard';
 
-const $props = defineProps({
-    insertable: {
-        type: Boolean,
-        default: false,
-    },
-});
-
-const emit = defineEmits(['update:modelValue', 'accountShortToStandard']);
 const model = defineModel({ prop: 'modelValue' });
-const inputRef = ref(false);
-
-function setCursorPosition(pos) {
-    const input = inputRef.value.vnInputRef.$el.querySelector('input');
-    input.focus();
-    input.setSelectionRange(pos, pos);
-}
-
-async function handleUpdateModel(val) {
-    model.value = val?.at(-1) === '.' ? useAccountShortToStandard(val) : val;
-    await nextTick(() => setCursorPosition(0));
-}
 </script>
 <template>
     <VnInput
         v-model="model"
         ref="inputRef"
-        :insertable
-        @update:model-value="handleUpdateModel"
+        @keydown.tab="model = useAccountShortToStandard($event.target.value) ?? model"
+        @input="model = $event.target.value.replace(/[^\d.]/g, '')"
     />
 </template>
diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 21cdc9df5..0b9cc2cce 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onBeforeMount, computed } from 'vue';
+import { onBeforeMount, computed, markRaw } from 'vue';
 import { useRoute, useRouter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router';
 import { useArrayData } from 'src/composables/useArrayData';
 import { useStateStore } from 'stores/useStateStore';
@@ -26,18 +26,14 @@ const route = useRoute();
 const stateStore = useStateStore();
 const router = useRouter();
 const entityId = computed(() => props.id || route?.params?.id);
-const arrayData = useArrayData(props.dataKey, {
-    url: props.url,
-    userFilter: props.filter,
-    oneRecord: true,
-});
+let arrayData = getArrayData(entityId.value, props.url);
 
 onBeforeRouteLeave(() => {
     stateStore.cardDescriptorChangeValue(null);
 });
 
 onBeforeMount(async () => {
-    stateStore.cardDescriptorChangeValue(props.descriptor);
+    stateStore.cardDescriptorChangeValue(markRaw(props.descriptor));
 
     const route = router.currentRoute.value;
     try {
@@ -61,16 +57,31 @@ onBeforeRouteUpdate(async (to, from) => {
 });
 
 async function fetch(id, append = false) {
-    const regex = /\/(\d+)/;
     if (props.idInWhere) arrayData.store.filter.where = { id };
-    else if (!regex.test(props.url)) arrayData.store.url = `${props.url}/${id}`;
-    else arrayData.store.url = props.url.replace(regex, `/${id}`);
+    else {
+        arrayData = getArrayData(id);
+    }
     await arrayData.fetch({ append, updateRouter: false });
     emit('onFetch', arrayData.store.data);
 }
 function hasRouteParam(params, valueToCheck = ':addressId') {
     return Object.values(params).includes(valueToCheck);
 }
+
+function formatUrl(id) {
+    const newId = id || entityId.value;
+    const regex = /\/(\d+)/;
+    if (!regex.test(props.url)) return `${props.url}/${newId}`;
+    return props.url.replace(regex, `/${newId}`);
+}
+
+function getArrayData(id, url) {
+    return useArrayData(props.dataKey, {
+        url: url ?? formatUrl(id),
+        userFilter: props.filter,
+        oneRecord: true,
+    });
+}
 </script>
 <template>
     <template v-if="visual">
diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue
index bee300f4e..de22e4857 100644
--- a/src/components/common/VnDms.vue
+++ b/src/components/common/VnDms.vue
@@ -35,6 +35,10 @@ const $props = defineProps({
         type: String,
         default: null,
     },
+    hasFile: {
+        type: Boolean,
+        default: false,
+    },
 });
 
 const warehouses = ref();
@@ -90,6 +94,7 @@ function defaultData() {
     if ($props.formInitialData) return (dms.value = $props.formInitialData);
     return addDefaultData({
         reference: route.params.id,
+        hasFile: $props.hasFile,
     });
 }
 
diff --git a/src/components/common/VnDmsInput.vue b/src/components/common/VnDmsInput.vue
index 25d625d5d..5a3ef351b 100644
--- a/src/components/common/VnDmsInput.vue
+++ b/src/components/common/VnDmsInput.vue
@@ -15,7 +15,7 @@ const editDownloadDisabled = ref(false);
 const $props = defineProps({
     defaultDmsCode: {
         type: String,
-        default: 'InvoiceIn',
+        default: 'invoiceIn',
     },
     disable: {
         type: Boolean,
diff --git a/src/components/common/VnDropdown.vue b/src/components/common/VnDropdown.vue
new file mode 100644
index 000000000..1b3f2237b
--- /dev/null
+++ b/src/components/common/VnDropdown.vue
@@ -0,0 +1,53 @@
+<script setup>
+import { ref } from 'vue';
+import VnSelect from './VnSelect.vue';
+
+const stateBtnDropdownRef = ref();
+
+const emit = defineEmits(['changeState']);
+
+const $props = defineProps({
+    disable: {
+        type: Boolean,
+        default: null,
+    },
+    options: {
+        type: Array,
+        default: null,
+    },
+    optionLabel: {
+        type: String,
+        default: 'name',
+    },
+    optionValue: {
+        type: String,
+        default: 'id',
+    },
+});
+
+async function changeState(value) {
+    stateBtnDropdownRef.value?.hide();
+    emit('changeState', value);
+}
+</script>
+
+<template>
+    <QBtnDropdown
+        ref="stateBtnDropdownRef"
+        color="black"
+        text-color="white"
+        :label="$t('globals.changeState')"
+        :disable="$props.disable"
+    >
+        <VnSelect
+            :options="$props.options"
+            :option-label="$props.optionLabel"
+            :option-value="$props.optionValue"
+            hide-selected
+            hide-dropdown-icon
+            focus-on-mount
+            @update:model-value="changeState"
+        >
+        </VnSelect>
+    </QBtnDropdown>
+</template>
diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 804147539..e2f18866a 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { ref, onUnmounted, watch } from 'vue';
+import { ref, onMounted, onUnmounted, watch, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute, useRouter } from 'vue-router';
 import axios from 'axios';
@@ -11,11 +11,11 @@ import { useCapitalize } from 'src/composables/useCapitalize';
 import { useValidator } from 'src/composables/useValidator';
 import VnAvatar from '../ui/VnAvatar.vue';
 import VnLogValue from './VnLogValue.vue';
-import FetchData from '../FetchData.vue';
-import VnSelect from './VnSelect.vue';
 import VnUserLink from '../ui/VnUserLink.vue';
 import VnPaginate from '../ui/VnPaginate.vue';
+import VnLogFilter from 'src/components/common/VnLogFilter.vue';
 import RightMenu from './RightMenu.vue';
+import { useFilterParams } from 'src/composables/useFilterParams';
 
 const stateStore = useStateStore();
 const validationsStore = useValidator();
@@ -72,39 +72,8 @@ const filter = {
 };
 
 const paginate = ref();
-const actions = ref();
-const changeInput = ref();
-const searchInput = ref();
-const userRadio = ref();
-const userSelect = ref();
-const dateFrom = ref();
-const dateFromDialog = ref(false);
-const dateTo = ref();
-const dateToDialog = ref(false);
-const selectedFilters = ref({});
-const userTypes = [
-    { label: 'All', value: undefined },
-    { label: 'User', value: { neq: null } },
-    { label: 'System', value: null },
-];
-const checkboxOptions = ref({
-    insert: {
-        label: 'Creates',
-        selected: false,
-    },
-    update: {
-        label: 'Edits',
-        selected: false,
-    },
-    delete: {
-        label: 'Deletes',
-        selected: false,
-    },
-    select: {
-        label: 'Accesses',
-        selected: false,
-    },
-});
+const dataKey = computed(() => `${props.model}Log`);
+const userParams = ref(useFilterParams(dataKey.value).params);
 
 let validations = models;
 let pointRecord = ref(null);
@@ -246,131 +215,55 @@ async function setLogTree(data) {
 function filterByRecord(modelLog) {
     byRecord.value = true;
     const { id, model } = modelLog;
-
-    searchInput.value = id;
-    selectedFilters.value.changedModelId = id;
-    selectedFilters.value.changedModel = model;
-    applyFilter();
+    applyFilter({ changedModelId: id, changedModel: model });
 }
 
-async function applyFilter() {
-    filter.where = { and: [] };
-    if (
-        !selectedFilters.value.changedModel ||
-        (!selectedFilters.value.changedModelValue &&
-            !selectedFilters.value.changedModelId)
-    )
-        byRecord.value = false;
-
-    if (!byRecord.value) filter.where.and.push({ originFk: route.params.id });
-
-    if (Object.keys(selectedFilters.value).length) {
-        filter.where.and.push(selectedFilters.value);
-    }
-
-    paginate.value.fetch({ filter });
+async function applyFilter(params = {}) {
+    paginate.value.arrayData.resetPagination();
+    paginate.value.arrayData.applyFilter({
+        filter: {},
+        params: { originFk: route.params.id, ...params },
+    });
 }
 
-function setDate(type) {
-    let from = dateFrom.value
-        ? date.formatDate(dateFrom.value.split('-').reverse().join('-'), 'YYYY-MM-DD')
-        : undefined;
-    from = date.adjustDate(from, { hour: 0, minute: 0, second: 0, millisecond: 0 }, true);
-
-    let to = dateTo.value
-        ? date.formatDate(dateTo.value.split('-').reverse().join('-'), 'YYYY-MM-DD')
-        : date.formatDate(dateFrom.value.split('-').reverse().join('-'), 'YYYY-MM-DD');
-    to = date.adjustDate(
-        to,
-        { hour: 21, minute: 59, second: 59, millisecond: 999 },
-        true,
-    );
-
-    switch (type) {
-        case 'from':
-            return { between: [from, to] };
-        case 'to': {
-            if (dateFrom.value) {
+function exprBuilder(param, value) {
+    switch (param) {
+        case 'changedModelValue':
+            return { [param]: { like: `%${value}%` } };
+        case 'change':
+            if (value)
                 return {
-                    between: [from, to],
+                    or: [
+                        { oldJson: { like: `%${value}%` } },
+                        { newJson: { like: `%${value}%` } },
+                        { description: { like: `%${value}%` } },
+                    ],
                 };
-            }
-            return { lte: to };
-        }
+            break;
+        case 'action':
+            if (value?.length) return { [param]: { inq: value } };
+            break;
+        case 'from':
+            return { creationDate: { gte: value } };
+        case 'to':
+            return { creationDate: { lte: value } };
+        case 'userType':
+            if (value === 'User') return { userFk: { neq: null } };
+            if (value === 'System') return { userFk: null };
+            break;
+        default:
+            return { [param]: value };
     }
 }
 
-function selectFilter(type, dateType) {
-    const filter = {};
-    const actions = { inq: [] };
-    let reload = true;
-
-    if (type === 'search') {
-        if (/^\s*[0-9]+\s*$/.test(searchInput.value) || props.byRecord) {
-            selectedFilters.value.changedModelId = searchInput.value.trim();
-        } else if (!searchInput.value) {
-            selectedFilters.value.changedModelId = undefined;
-            selectedFilters.value.changedModelValue = undefined;
-        } else {
-            selectedFilters.value.changedModelValue = { like: `%${searchInput.value}%` };
-        }
-    }
-    if (type === 'action' && selectedFilters.value.changedModel === null) {
-        selectedFilters.value.changedModel = undefined;
-    }
-    if (type === 'userRadio') {
-        selectedFilters.value.userFk = userRadio.value;
-    }
-    if (type === 'change') {
-        if (changeInput.value)
-            selectedFilters.value.or = [
-                { oldJson: { like: `%${changeInput.value}%` } },
-                { newJson: { like: `%${changeInput.value}%` } },
-                { description: { like: `%${changeInput.value}%` } },
-            ];
-        else selectedFilters.value.or = undefined;
-    }
-    if (type === 'userSelect') {
-        selectedFilters.value.userFk =
-            userSelect.value !== null ? userSelect.value : undefined;
-    }
-    if (type === 'date') {
-        if (!dateFrom.value && !dateTo.value) {
-            selectedFilters.value.creationDate = undefined;
-        } else if (dateType === 'to') {
-            selectedFilters.value.creationDate = setDate('to');
-        } else if (dateType === 'from') {
-            selectedFilters.value.creationDate = setDate('from');
-        }
-    }
-
-    Object.keys(checkboxOptions.value).forEach((key) => {
-        if (checkboxOptions.value[key].selected) actions.inq.push(key);
-    });
-    selectedFilters.value.action = actions.inq.length ? actions : undefined;
-
-    Object.keys(selectedFilters.value).forEach((key) => {
-        if (selectedFilters.value[key]) filter[key] = selectedFilters.value[key];
-    });
-
-    if (reload) applyFilter(filter);
-}
-
 async function clearFilter() {
-    selectedFilters.value = {};
     byRecord.value = false;
-    userSelect.value = undefined;
-    searchInput.value = undefined;
-    changeInput.value = undefined;
-    dateFrom.value = undefined;
-    dateTo.value = undefined;
-    userRadio.value = undefined;
-    Object.keys(checkboxOptions.value).forEach(
-        (opt) => (checkboxOptions.value[opt].selected = false),
-    );
     await applyFilter();
 }
 
+onMounted(() => {
+    stateStore.rightDrawerChangeValue(true);
+});
 onUnmounted(() => {
     stateStore.rightDrawer = false;
 });
@@ -383,32 +276,18 @@ watch(
 );
 </script>
 <template>
-    <FetchData
-        :url="`${props.model}Logs/${route.params.id}/models`"
-        :filter="{ order: ['changedModel'] }"
-        @on-fetch="
-            (data) =>
-                (actions = data.map((item) => {
-                    const changedModel = item.changedModel;
-                    return {
-                        locale: useCapitalize(
-                            validations[changedModel]?.locale?.name ?? changedModel,
-                        ),
-                        value: changedModel,
-                    };
-                }))
-        "
-        auto-load
-    />
     <VnPaginate
         ref="paginate"
-        :data-key="`${model}Log`"
-        :url="`${model}Logs`"
+        :data-key
+        :url="dataKey + 's'"
         :user-filter="filter"
         :skeleton="false"
         auto-load
         @on-fetch="setLogTree"
+        @on-change="setLogTree"
         search-url="logs"
+        :exprBuilder
+        :order="['creationDate DESC', 'id DESC']"
     >
         <template #body>
             <div
@@ -467,6 +346,7 @@ watch(
                                             backgroundColor: useColor(modelLog.model),
                                         }"
                                         :title="`${modelLog.model} #${modelLog.id}`"
+                                        data-cy="vnLog-model-chip"
                                     >
                                         {{ t(modelLog.modelI18n) }}
                                     </QChip>
@@ -561,9 +441,7 @@ watch(
                                                                         }}:
                                                                     </span>
                                                                     <VnLogValue
-                                                                        :value="
-                                                                            value.val.val
-                                                                        "
+                                                                        :value="value.val"
                                                                         :name="value.name"
                                                                     />
                                                                 </QItem>
@@ -582,6 +460,7 @@ watch(
                                                             }`,
                                                         )
                                                     "
+                                                    data-cy="vnLog-action-icon"
                                                 />
                                             </div>
                                         </QItem>
@@ -616,7 +495,7 @@ watch(
                                                         {{ prop.nameI18n }}:
                                                     </span>
                                                     <VnLogValue
-                                                        :value="prop.val.val"
+                                                        :value="prop.val"
                                                         :name="prop.name"
                                                     />
                                                     <span
@@ -647,7 +526,7 @@ watch(
                                                     </span>
                                                     <span v-if="log.action == 'update'">
                                                         <VnLogValue
-                                                            :value="prop.old.val"
+                                                            :value="prop.old"
                                                             :name="prop.name"
                                                         />
                                                         <span
@@ -658,7 +537,7 @@ watch(
                                                         </span>
                                                         →
                                                         <VnLogValue
-                                                            :value="prop.val.val"
+                                                            :value="prop.val"
                                                             :name="prop.name"
                                                         />
                                                         <span
@@ -670,7 +549,7 @@ watch(
                                                     </span>
                                                     <span v-else="prop.old.val">
                                                         <VnLogValue
-                                                            :value="prop.val.val"
+                                                            :value="prop.val"
                                                             :name="prop.name"
                                                         />
                                                         <span
@@ -699,181 +578,12 @@ watch(
     </VnPaginate>
     <RightMenu>
         <template #right-panel>
-            <QList dense>
-                <QSeparator />
-                <QItem class="q-mt-sm">
-                    <QInput
-                        :label="t('globals.search')"
-                        v-model="searchInput"
-                        class="full-width"
-                        clearable
-                        filled
-                        clear-icon="close"
-                        @keyup.enter="() => selectFilter('search')"
-                        @focusout="() => selectFilter('search')"
-                        @clear="() => selectFilter('search')"
-                    >
-                        <template #append>
-                            <QIcon name="info" class="cursor-pointer">
-                                <QTooltip>{{ t('tooltips.search') }}</QTooltip>
-                            </QIcon>
-                        </template>
-                    </QInput>
-                </QItem>
-                <QItem>
-                    <VnSelect
-                        class="full-width"
-                        :label="t('globals.entity')"
-                        v-model="selectedFilters.changedModel"
-                        option-label="locale"
-                        option-value="value"
-                        filled
-                        :options="actions"
-                        @update:model-value="selectFilter('action')"
-                        hide-selected
-                    />
-                </QItem>
-                <QItem class="q-mt-sm">
-                    <QOptionGroup
-                        size="sm"
-                        v-model="userRadio"
-                        :options="userTypes"
-                        color="primary"
-                        @update:model-value="selectFilter('userRadio')"
-                        right-label
-                    >
-                        <template #label="{ label }">
-                            {{ t(`Users.${label}`) }}
-                        </template>
-                    </QOptionGroup>
-                </QItem>
-                <QItem class="q-mt-sm">
-                    <QItemSection v-if="userRadio !== null">
-                        <VnSelect
-                            class="full-width"
-                            :label="t('globals.user')"
-                            v-model="userSelect"
-                            filled
-                            :url="`${model}Logs/${route.params.id}/editors`"
-                            :fields="['id', 'nickname', 'name', 'image']"
-                            sort-by="nickname"
-                            @update:model-value="selectFilter('userSelect')"
-                            hide-selected
-                        >
-                            <template #option="{ opt, itemProps }">
-                                <QItem
-                                    v-bind="itemProps"
-                                    class="q-pa-xs row items-center"
-                                >
-                                    <QItemSection class="col-3 items-center">
-                                        <VnAvatar :worker-id="opt.id" />
-                                    </QItemSection>
-                                    <QItemSection class="col-9 justify-center">
-                                        <span>{{ opt.name }}</span>
-                                        <span class="text-grey">{{ opt.nickname }}</span>
-                                    </QItemSection>
-                                </QItem>
-                            </template>
-                        </VnSelect>
-                    </QItemSection>
-                </QItem>
-                <QItem class="q-mt-sm">
-                    <QInput
-                        :label="t('globals.changes')"
-                        v-model="changeInput"
-                        class="full-width"
-                        filled
-                        clearable
-                        clear-icon="close"
-                        @keyup.enter="selectFilter('change')"
-                        @focusout="selectFilter('change')"
-                        @clear="selectFilter('change')"
-                    >
-                        <template #append>
-                            <QIcon name="info" class="cursor-pointer">
-                                <QTooltip max-width="250px">{{
-                                    t('tooltips.changes')
-                                }}</QTooltip>
-                            </QIcon>
-                        </template>
-                    </QInput>
-                </QItem>
-                <QItem
-                    :class="index == 'create' ? 'q-mt-md' : 'q-mt-xs'"
-                    v-for="(checkboxOption, index) in checkboxOptions"
-                    :key="index"
-                >
-                    <QCheckbox
-                        size="sm"
-                        v-model="checkboxOption.selected"
-                        :label="t(`actions.${checkboxOption.label}`)"
-                        @update:model-value="selectFilter"
-                    />
-                </QItem>
-                <QItem class="q-mt-sm">
-                    <QInput
-                        class="full-width"
-                        :label="t('globals.date')"
-                        @click="dateFromDialog = true"
-                        @focus="(evt) => evt.target.blur()"
-                        @clear="selectFilter('date', 'to')"
-                        v-model="dateFrom"
-                        clearable
-                        filled
-                        clear-icon="close"
-                    />
-                </QItem>
-                <QItem class="q-mt-sm">
-                    <QInput
-                        class="full-width"
-                        :label="t('globals.to')"
-                        @click="dateToDialog = true"
-                        @focus="(evt) => evt.target.blur()"
-                        @clear="selectFilter('date', 'from')"
-                        v-model="dateTo"
-                        clearable
-                        filled
-                        clear-icon="close"
-                    />
-                </QItem>
-            </QList>
+            <VnLogFilter :data-key />
         </template>
     </RightMenu>
-    <QDialog v-model="dateFromDialog">
-        <QDate
-            :years-in-month-view="false"
-            v-model="dateFrom"
-            dense
-            flat
-            minimal
-            filled
-            @update:model-value="
-                (value) => {
-                    dateFromDialog = false;
-                    dateFrom = date.formatDate(value, 'DD-MM-YYYY');
-                    selectFilter('date', 'from');
-                }
-            "
-        />
-    </QDialog>
-    <QDialog v-model="dateToDialog">
-        <QDate
-            v-model="dateTo"
-            dense
-            flat
-            minimal
-            @update:model-value="
-                (value) => {
-                    dateToDialog = false;
-                    dateTo = date.formatDate(value, 'DD-MM-YYYY');
-                    selectFilter('date', 'to');
-                }
-            "
-        />
-    </QDialog>
     <QPageSticky position="bottom-right" :offset="[25, 25]">
         <QBtn
-            v-if="Object.values(selectedFilters).some((filter) => filter !== undefined)"
+            v-if="Object.keys(userParams).some((filter) => filter !== 'originFk')"
             color="primary"
             icon="filter_alt_off"
             size="md"
diff --git a/src/components/common/VnLogFilter.vue b/src/components/common/VnLogFilter.vue
index b5941239c..c7be68e9e 100644
--- a/src/components/common/VnLogFilter.vue
+++ b/src/components/common/VnLogFilter.vue
@@ -1,77 +1,249 @@
 <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 VnTableFilter from '../VnTable/VnTableFilter.vue';
+import VnSelect from './VnSelect.vue';
+import { useRoute } from 'vue-router';
+import VnInput from './VnInput.vue';
+import { ref, computed, watch } from 'vue';
+import VnInputDate from './VnInputDate.vue';
+import { useFilterParams } from 'src/composables/useFilterParams';
+import FetchData from '../FetchData.vue';
+import { useValidator } from 'src/composables/useValidator';
+import { useCapitalize } from 'src/composables/useCapitalize';
+import VnAvatar from '../ui/VnAvatar.vue';
 
-const { t } = useI18n();
-const props = defineProps({
+const $props = defineProps({
     dataKey: {
         type: String,
-        required: true,
+        default: null,
     },
 });
 
-const workers = ref();
+const { t } = useI18n();
+const route = useRoute();
+const validationsStore = useValidator();
+const { models } = validationsStore;
+const entities = ref([]);
+const editors = ref([]);
+const userParams = ref(useFilterParams($props.dataKey).params);
+let validations = models;
+const userTypes = [
+    { value: 'All', label: t(`Users.All`) },
+    { value: 'User', label: t(`Users.User`) },
+    { value: 'System', label: t(`Users.System`) },
+];
+const checkboxOptions = ref([
+    { name: 'insert', label: 'Creates', selected: false },
+    { name: 'update', label: 'Edits', selected: false },
+    { name: 'delete', label: 'Deletes', selected: false },
+    { name: 'select', label: 'Accesses', selected: false },
+]);
+const columns = computed(() => [
+    { name: 'changedModelValue' },
+    { name: 'changedModel' },
+    { name: 'userType', orderBy: false },
+    { name: 'userFk' },
+    { name: 'change', orderBy: false },
+    { name: 'action' },
+    { name: 'from', orderBy: 'creationDate' },
+    { name: 'to', orderBy: 'creationDate' },
+]);
+
+const userParamsWatcher = watch(
+    () => userParams.value,
+    (params) => {
+        if (params.action) {
+            params.action.forEach((option) => {
+                checkboxOptions.value.find((o) => o.name === option).selected = true;
+            });
+            userParamsWatcher();
+        }
+    },
+);
+
+function getActions() {
+    const actions = checkboxOptions.value
+        .filter((option) => option.selected)
+        ?.map((o) => o.name);
+    return actions.length ? actions : null;
+}
 </script>
 
 <template>
     <FetchData
-        url="Workers/activeWithInheritedRole"
-        :filter="{ where: { role: 'salesPerson' } }"
-        @on-fetch="(data) => (workers = data)"
+        :url="`${dataKey}s/${route.params.id}/models`"
+        :filter="{ order: ['changedModel'] }"
+        @on-fetch="
+            (data) =>
+                (entities = data.map((item) => {
+                    const changedModel = item.changedModel;
+                    return {
+                        locale: useCapitalize(
+                            validations[changedModel]?.locale?.name ?? changedModel,
+                        ),
+                        value: changedModel,
+                    };
+                }))
+        "
         auto-load
     />
-    <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>
+    <FetchData
+        :url="`${dataKey}s/${route.params.id}/editors`"
+        :filter="{ fields: ['id', 'nickname', 'name', 'image'] }"
+        sort-by="nickname"
+        @on-fetch="(data) => (editors = data)"
+        auto-load
+    />
+    <VnTableFilter
+        v-if="dataKey"
+        :data-key
+        :columns="columns"
+        :redirect="false"
+        :hiddenTags="['originFk', 'creationDate']"
+        search-url="logs"
+        :showTagChips="false"
+    >
+        <template #filter-changedModelValue="{ params, columnName, searchFn }">
+            <VnInput
+                :label="t('globals.search')"
+                v-model="params[columnName]"
+                @keyup.enter="searchFn"
+                @blur="searchFn"
+                @remove="searchFn"
+                :info="t('tooltips.search')"
+                dense
+                filled
+                data-cy="vnLog-search"
+            />
+        </template>
+        <template #filter-changedModel="{ params, columnName, searchFn }">
+            <VnSelect
+                :label="t('globals.entity')"
+                v-model="params[columnName]"
+                option-label="locale"
+                option-value="value"
+                :options="entities"
+                @update:model-value="() => searchFn()"
+                dense
+                filled
+                data-cy="vnLog-entity"
+            />
+        </template>
+        <template #filter-userType="{ params, columnName, searchFn }">
+            <QOptionGroup
+                class="text-left"
+                size="sm"
+                v-model="params[columnName]"
+                :options="userTypes"
+                color="primary"
+                @update:model-value="
+                    () => {
+                        params.userFk = null;
+                        searchFn();
+                    }
+                "
+            />
+        </template>
+        <template #filter-userFk="{ params, columnName, searchFn }">
+            <VnSelect
+                :label="t('globals.user')"
+                v-model="params[columnName]"
+                :options="editors"
+                @update:modelValue="() => searchFn()"
+                :disable="params.userType === 'System'"
+                dense
+                filled
+            >
+                <template #option="{ opt, itemProps }">
+                    <QItem v-bind="itemProps" class="q-pa-xs row items-center">
+                        <QItemSection class="col-3 items-center">
+                            <VnAvatar :worker-id="opt.id" />
+                        </QItemSection>
+                        <QItemSection class="col-9 justify-center">
+                            <span>{{ opt.name }}</span>
+                            <span class="text-grey">{{ opt.nickname }}</span>
+                        </QItemSection>
+                    </QItem>
+                </template>
+            </VnSelect>
+        </template>
+        <template #filter-change="{ params, columnName, searchFn }">
+            <VnInput
+                :label="t('globals.changes')"
+                v-model="params[columnName]"
+                @keyup.enter="searchFn"
+                @blur="searchFn"
+                @remove="searchFn"
+                :info="t('tooltips.changes')"
+                dense
+                filled
+            />
+        </template>
+        <template #filter-action="{ searchFn }">
+            <div class="column">
+                <QCheckbox
+                    v-for="checkboxOption in checkboxOptions"
+                    :key="checkboxOption"
+                    size="sm"
+                    v-model="checkboxOption.selected"
+                    :label="t(`actions.${checkboxOption.label}`)"
+                    @update:model-value="
+                        () => searchFn(undefined, 'action', getActions())
+                    "
+                    data-cy="vnLog-checkbox"
+                />
             </div>
         </template>
-        <template #body="{ params, searchFn }">
-            <QDate
-                v-model="params.created"
-                @update:model-value="searchFn()"
+        <template #filter-from="{ params, columnName, searchFn }">
+            <VnInputDate
+                :label="t('globals.from')"
+                v-model="params[columnName]"
                 dense
-                flat
-                minimal
-            >
-            </QDate>
-            <QSeparator />
-            <QItem>
-                <QItemSection v-if="!workers">
-                    <QSkeleton type="QInput" class="full-width" />
-                </QItemSection>
-                <QItemSection v-if="workers">
-                    <QSelect
-                        :label="t('User')"
-                        v-model="params.userFk"
-                        @update:model-value="searchFn()"
-                        :options="workers"
-                        option-value="id"
-                        option-label="name"
-                        emit-value
-                        map-options
-                        use-input
-                        :input-debounce="0"
-                    />
-                </QItemSection>
-            </QItem>
+                filled
+                @update:modelValue="() => searchFn()"
+            />
         </template>
-    </VnFilterPanel>
+        <template #filter-to="{ params, columnName, searchFn }">
+            <VnInputDate
+                :label="t('globals.to')"
+                v-model="params[columnName]"
+                dense
+                filled
+                @update:modelValue="() => searchFn()"
+            />
+        </template>
+    </VnTableFilter>
 </template>
-
 <i18n>
-en:
-    params:
-        search: Contains
-        userFk: User
-        created: Created
 es:
+    tooltips:
+        search: Buscar por identificador o concepto
+        changes: Buscar por cambios. Los atributos deben buscarse por su nombre interno, para obtenerlo situar el cursor sobre el atributo.
+    actions:
+        Creates: Crea
+        Edits: Modifica
+        Deletes: Elimina
+        Accesses: Accede
+    Users:
+        User: Usuario
+        All: Todo
+        System: Sistema
     params:
-        search: Contiene
-        userFk: Usuario
-        created: Creada
-    User: Usuario
+        changedModel: Entity
+
+en:
+    tooltips:
+        search: Search by identifier or concept
+        changes: Search by changes. Attributes must be searched by their internal name, to get it place the cursor over the attribute.
+    actions:
+        Creates: Creates
+        Edits: Edits
+        Deletes: Deletes
+        Accesses: Accesses
+    Users:
+        User: User
+        All: All
+        System: System
+    params:
+        changedModel: Entidad
 </i18n>
diff --git a/src/components/common/VnLogValue.vue b/src/components/common/VnLogValue.vue
index df0be4011..3f1617ce7 100644
--- a/src/components/common/VnLogValue.vue
+++ b/src/components/common/VnLogValue.vue
@@ -5,18 +5,24 @@ import { computed } from 'vue';
 const descriptorStore = useDescriptorStore();
 
 const $props = defineProps({
-    name: { type: [String], default: undefined },
+    value: { type: Object, default: () => {} },
+    name: { type: String, default: undefined },
 });
 
 const descriptor = computed(() => descriptorStore.has($props.name));
 </script>
 <template>
-    <VnJsonValue v-bind="$attrs" />
-    <QIcon
-        name="launch"
-        class="link"
-        v-if="$attrs.value && descriptor"
-        :data-cy="'iconLaunch-' + $props.name"
-    />
-    <component :is="descriptor" :id="$attrs.value" v-if="$attrs.value && descriptor" />
+    <VnJsonValue :value="value.val" />
+    <span
+        v-if="(value.id || typeof value.val == 'number') && descriptor"
+        style="margin-left: 2px"
+    >
+        <QIcon
+            name="launch"
+            class="link"
+            :data-cy="'iconLaunch-' + $props.name"
+            style="padding-bottom: 2px"
+        />
+        <component :is="descriptor" :id="value.id ?? value.val" />
+    </span>
 </template>
diff --git a/src/components/common/VnSection.vue b/src/components/common/VnSection.vue
index 4bd17124f..34eb14601 100644
--- a/src/components/common/VnSection.vue
+++ b/src/components/common/VnSection.vue
@@ -40,10 +40,6 @@ const $props = defineProps({
         type: Boolean,
         default: true,
     },
-    keepData: {
-        type: Boolean,
-        default: true,
-    },
 });
 
 const route = useRoute();
@@ -61,7 +57,6 @@ onBeforeMount(() => {
     if ($props.dataKey)
         arrayData = useArrayData($props.dataKey, {
             searchUrl: 'table',
-            keepData: $props.keepData,
             ...$props.arrayDataProps,
             navigate: $props.redirect,
         });
diff --git a/src/components/common/__tests__/VnChangePassword.spec.js b/src/components/common/__tests__/VnChangePassword.spec.js
index f5a967bb5..b610ce44d 100644
--- a/src/components/common/__tests__/VnChangePassword.spec.js
+++ b/src/components/common/__tests__/VnChangePassword.spec.js
@@ -1,4 +1,5 @@
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import VnChangePassword from 'src/components/common/VnChangePassword.vue';
 import { vi, beforeEach, afterEach, beforeAll, describe, expect, it } from 'vitest';
 import { Notify } from 'quasar';
diff --git a/src/components/common/__tests__/VnDms.spec.js b/src/components/common/__tests__/VnDms.spec.js
index 03028aee7..66d946db3 100644
--- a/src/components/common/__tests__/VnDms.spec.js
+++ b/src/components/common/__tests__/VnDms.spec.js
@@ -1,4 +1,5 @@
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
 import { vi, afterEach, beforeEach, beforeAll, describe, expect, it } from 'vitest';
 import VnDms from 'src/components/common/VnDms.vue';
 
@@ -40,7 +41,10 @@ describe('VnDms', () => {
         companyFk: 2,
         dmsTypeFk: 3,
         description: 'This is a test description',
-        files: { name: 'example.txt', content: new Blob(['file content'], { type: 'text/plain' })},
+        files: {
+            name: 'example.txt',
+            content: new Blob(['file content'], { type: 'text/plain' }),
+        },
     };
 
     const expectedBody = {
@@ -59,7 +63,7 @@ describe('VnDms', () => {
                 url: '/test',
                 formInitialData: { id: 1, reference: 'test' },
                 model: 'Worker',
-            }
+            },
         });
         wrapper = wrapper.wrapper;
         vm = wrapper.vm;
@@ -98,7 +102,7 @@ describe('VnDms', () => {
             expect(vm.getUrl()).toBe('/test');
         });
 
-        it('should returns url dms/"props.formInitialData.id"/updateFile when prop url is null', async () => {            
+        it('should returns url dms/"props.formInitialData.id"/updateFile when prop url is null', async () => {
             await wrapper.setProps({ url: null });
             expect(vm.getUrl()).toBe('dms/1/updateFile');
         });
@@ -113,7 +117,9 @@ describe('VnDms', () => {
     describe('save', () => {
         it('should save data correctly', async () => {
             await vm.save();
-            expect(postMock).toHaveBeenCalledWith(vm.getUrl(), expect.any(FormData), { params: expectedBody });
+            expect(postMock).toHaveBeenCalledWith(vm.getUrl(), expect.any(FormData), {
+                params: expectedBody,
+            });
             expect(wrapper.emitted('onDataSaved')).toBeTruthy();
         });
     });
@@ -127,8 +133,8 @@ describe('VnDms', () => {
                 warehouseFk: 2,
                 companyFk: 3,
                 dmsTypeFk: 2,
-                description: 'This is a test description'
-            }
+                description: 'This is a test description',
+            };
             await wrapper.setProps({ formInitialData: testData });
             vm.defaultData();
 
@@ -137,10 +143,10 @@ describe('VnDms', () => {
 
         it('should add reference with "route.params.id" to dms if formInitialData is null', async () => {
             await wrapper.setProps({ formInitialData: null });
-            vm.route.params.id= '111';
+            vm.route.params.id = '111';
             vm.defaultData();
 
             expect(vm.dms.reference).toBe('111');
         });
     });
-});
\ No newline at end of file
+});
diff --git a/src/components/common/__tests__/VnDmsList.spec.js b/src/components/common/__tests__/VnDmsList.spec.js
index 22101239e..ee62f6971 100644
--- a/src/components/common/__tests__/VnDmsList.spec.js
+++ b/src/components/common/__tests__/VnDmsList.spec.js
@@ -1,4 +1,6 @@
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
+
 import VnDmsList from 'src/components/common/VnDmsList.vue';
 import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest';
 
diff --git a/src/components/common/__tests__/VnLog.spec.js b/src/components/common/__tests__/VnLog.spec.js
index 53d2732a0..fcb516cc5 100644
--- a/src/components/common/__tests__/VnLog.spec.js
+++ b/src/components/common/__tests__/VnLog.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import VnLog from 'src/components/common/VnLog.vue';
 
 describe('VnLog', () => {
@@ -108,27 +109,4 @@ describe('VnLog', () => {
         expect(vm.logTree[0].originFk).toEqual(1);
         expect(vm.logTree[0].logs[0].user.name).toEqual('salesPerson');
     });
-
-    it('should correctly set the selectedFilters when filtering', () => {
-        vm.searchInput = '1';
-        vm.userSelect = '21';
-        vm.checkboxOptions.insert.selected = true;
-        vm.checkboxOptions.update.selected = true;
-
-        vm.selectFilter('search');
-        vm.selectFilter('userSelect');
-
-        expect(vm.selectedFilters.changedModelId).toEqual('1');
-        expect(vm.selectedFilters.userFk).toEqual('21');
-        expect(vm.selectedFilters.action).toEqual({ inq: ['insert', 'update'] });
-    });
-
-    it('should correctly set the date from', () => {
-        vm.dateFrom = '18-09-2023';
-        vm.selectFilter('date', 'from');
-        expect(vm.selectedFilters.creationDate.between).toEqual([
-            new Date('2023-09-18T00:00:00.000Z'),
-            new Date('2023-09-18T21:59:59.999Z'),
-        ]);
-    });
 });
diff --git a/src/components/common/__tests__/VnLogFilter.spec.js b/src/components/common/__tests__/VnLogFilter.spec.js
new file mode 100644
index 000000000..a28fa85b1
--- /dev/null
+++ b/src/components/common/__tests__/VnLogFilter.spec.js
@@ -0,0 +1,28 @@
+import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+import VnLogFilter from 'src/components/common/VnLogFilter.vue';
+
+describe('VnLogFilter', () => {
+    let vm;
+    beforeAll(async () => {
+        vm = createWrapper(VnLogFilter, {
+            props: {
+                dataKey: 'ClaimLog',
+            },
+        }).vm;
+    });
+
+    afterEach(() => {
+        vi.clearAllMocks();
+    });
+
+    it('should getActions selected', async () => {
+        vm.checkboxOptions.find((o) => o.name == 'insert').selected = true;
+        vm.checkboxOptions.find((o) => o.name == 'update').selected = true;
+
+        const actions = vm.getActions();
+
+        expect(actions.length).toEqual(2);
+        expect(actions).toEqual(['insert', 'update']);
+    });
+});
diff --git a/src/components/common/__tests__/VnNotes.spec.js b/src/components/common/__tests__/VnNotes.spec.js
index 2603bf03c..e0514cc7b 100644
--- a/src/components/common/__tests__/VnNotes.spec.js
+++ b/src/components/common/__tests__/VnNotes.spec.js
@@ -1,16 +1,7 @@
-import {
-    describe,
-    it,
-    expect,
-    vi,
-    beforeAll,
-    afterEach,
-    beforeEach,
-    afterAll,
-} from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { describe, it, expect, vi, afterEach, beforeEach, afterAll } from 'vitest';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
 import VnNotes from 'src/components/ui/VnNotes.vue';
-import vnDate from 'src/boot/vnDate';
 
 describe('VnNotes', () => {
     let vm;
@@ -18,6 +9,7 @@ describe('VnNotes', () => {
     let spyFetch;
     let postMock;
     let patchMock;
+    let deleteMock;
     let expectedInsertBody;
     let expectedUpdateBody;
     const defaultOptions = {
@@ -57,6 +49,7 @@ describe('VnNotes', () => {
     beforeEach(() => {
         postMock = vi.spyOn(axios, 'post');
         patchMock = vi.spyOn(axios, 'patch');
+        deleteMock = vi.spyOn(axios, 'delete');
     });
 
     afterEach(() => {
@@ -153,4 +146,16 @@ describe('VnNotes', () => {
             );
         });
     });
+
+    describe('delete', () => {
+        it('Should call axios.delete with url and vnPaginateRef.fetch', async () => {
+            generateWrapper();
+            createSpyFetch();
+
+            await vm.deleteNote({ id: 1 });
+
+            expect(deleteMock).toHaveBeenCalledWith(`${vm.$props.url}/1`);
+            expect(spyFetch).toHaveBeenCalled();
+        });
+    });
 });
diff --git a/src/components/ui/CardSummary.vue b/src/components/ui/CardSummary.vue
index 2ec6bea78..a6c23be2e 100644
--- a/src/components/ui/CardSummary.vue
+++ b/src/components/ui/CardSummary.vue
@@ -159,6 +159,7 @@ async function fetch() {
                 display: flex;
                 flex-direction: row;
                 margin-top: 2px;
+                align-items: start;
                 .label {
                     color: var(--vn-label-color);
                     width: 9em;
@@ -169,9 +170,15 @@ async function fetch() {
                     flex-grow: 0;
                     flex-shrink: 0;
                 }
+                &.ellipsis > .value {
+                    text-overflow: ellipsis;
+                    white-space: pre;
+                }
                 .value {
                     color: var(--vn-text-color);
                     overflow: hidden;
+                    white-space: nowrap;
+                    text-overflow: ellipsis;
                 }
             }
             .header {
@@ -203,27 +210,21 @@ async function fetch() {
 }
 
 .vn-card-group {
-    display: flex;
-    flex-direction: column;
+    display: grid;
+    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+    gap: 16px;
 }
 
 .vn-card-content {
     display: flex;
     flex-direction: column;
+    overflow: hidden;
+    white-space: nowrap;
     text-overflow: ellipsis;
     > div {
         max-height: 70px;
     }
 }
-
-@media (min-width: 1010px) {
-    .vn-card-group {
-        flex-direction: row;
-    }
-    .vn-card-content {
-        flex: 1;
-    }
-}
 </style>
 <style lang="scss" scoped>
 .summaryHeader .vn-label-value {
diff --git a/src/components/ui/VnDescriptor.vue b/src/components/ui/VnDescriptor.vue
index 47da98d74..994233eb0 100644
--- a/src/components/ui/VnDescriptor.vue
+++ b/src/components/ui/VnDescriptor.vue
@@ -30,7 +30,7 @@ const $props = defineProps({
         default: null,
     },
     toModule: {
-        type: String,
+        type: Object,
         default: null,
     },
 });
@@ -252,6 +252,10 @@ const toModule = computed(() => {
                 content: ':';
             }
         }
+        &.ellipsis > .value {
+            text-overflow: ellipsis;
+            white-space: pre;
+        }
         .value {
             color: var(--vn-text-color);
             font-size: 14px;
diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue
index 85cc8cde2..dc9e4e776 100644
--- a/src/components/ui/VnFilterPanel.vue
+++ b/src/components/ui/VnFilterPanel.vue
@@ -61,6 +61,10 @@ const $props = defineProps({
         type: Object,
         default: null,
     },
+    showTagChips: {
+        type: Boolean,
+        default: true,
+    },
 });
 
 const emit = defineEmits([
@@ -88,13 +92,14 @@ const userOrders = ref(useFilterParams($props.dataKey).orders);
 defineExpose({ search, params: userParams, remove });
 
 const isLoading = ref(false);
-async function search(evt) {
+async function search(evt, name, value) {
     try {
         if (evt && $props.disableSubmitEvent) return;
 
         store.filter.where = {};
         isLoading.value = true;
         const filter = { ...userParams.value, ...$props.modelValue };
+        if (name) filter[name] = value;
         store.userParamsChanged = true;
         await arrayData.addFilter({
             params: filter,
@@ -214,7 +219,7 @@ const getLocale = (label) => {
         </QTooltip>
     </QBtn>
     <QForm @submit="search" id="filterPanelForm" @keyup.enter="search()">
-        <QList dense>
+        <QList dense v-if="showTagChips">
             <QItem class="q-mt-xs">
                 <QItemSection top>
                     <QItemLabel header lines="1" class="text-uppercase q-py-xs q-px-none">
diff --git a/src/components/ui/VnLinkMail.vue b/src/components/ui/VnLinkMail.vue
index a54f463f5..6c5129a9b 100644
--- a/src/components/ui/VnLinkMail.vue
+++ b/src/components/ui/VnLinkMail.vue
@@ -1,8 +1,11 @@
 <script setup>
+import { dashIfEmpty } from 'src/filters';
+
 defineProps({ email: { type: [String], default: null } });
 </script>
 <template>
     <QBtn
+        class="q-pr-xs"
         v-if="email"
         flat
         round
@@ -13,4 +16,5 @@ defineProps({ email: { type: [String], default: null } });
         :href="`mailto:${email}`"
         @click.stop
     />
+    <span>{{ dashIfEmpty(email) }}</span>
 </template>
diff --git a/src/components/ui/VnLinkPhone.vue b/src/components/ui/VnLinkPhone.vue
index a9e9bc0fc..e34a70011 100644
--- a/src/components/ui/VnLinkPhone.vue
+++ b/src/components/ui/VnLinkPhone.vue
@@ -1,7 +1,7 @@
 <script setup>
 import { ref, reactive, useAttrs, onBeforeMount, capitalize } from 'vue';
 import axios from 'axios';
-import { parsePhone } from 'src/filters';
+import { dashIfEmpty, parsePhone } from 'src/filters';
 import useOpenURL from 'src/composables/useOpenURL';
 
 const props = defineProps({
@@ -12,49 +12,65 @@ const props = defineProps({
 
 const phone = ref(props.phoneNumber);
 const config = reactive({
-    sip: { icon: 'phone', href: `sip:${props.phoneNumber}` },
     'say-simple': {
         icon: 'vn:saysimple',
         url: null,
         channel: props.channel,
     },
+    sip: { icon: 'phone', href: `sip:${props.phoneNumber}` },
 });
-const type = Object.keys(config).find((key) => key in useAttrs()) || 'sip';
+
+const attrs = useAttrs();
+const types = Object.keys(config)
+    .filter((key) => key in attrs)
+    .sort();
+const activeTypes = types.length ? types : ['sip'];
 
 onBeforeMount(async () => {
     if (!phone.value) return;
-    let { channel } = config[type];
 
-    if (type === 'say-simple') {
-        const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne'))
-            .data;
-        if (!channel) channel = defaultChannel;
+    for (const type of activeTypes) {
+        if (type === 'say-simple') {
+            let { channel } = config[type];
+            const { url, defaultChannel } = (await axios.get('SaySimpleConfigs/findOne'))
+                .data;
+            if (!channel) channel = defaultChannel;
 
-        phone.value = await parsePhone(props.phoneNumber, props.country?.toLowerCase());
-        config[
-            type
-        ].url = `${url}?customerIdentity=%2B${phone.value}&channelId=${channel}`;
+            phone.value = await parsePhone(
+                props.phoneNumber,
+                props.country?.toLowerCase(),
+            );
+            config[type].url =
+                `${url}?customerIdentity=%2B${phone.value}&channelId=${channel}`;
+        }
     }
 });
 
-function handleClick() {
+function handleClick(type) {
     if (config[type].url) useOpenURL(config[type].url);
     else if (config[type].href) window.location.href = config[type].href;
 }
 </script>
+
 <template>
-    <QBtn
-        v-if="phone"
-        flat
-        round
-        :icon="config[type].icon"
-        size="sm"
-        color="primary"
-        padding="none"
-        @click.stop="handleClick"
-    >
-        <QTooltip>
-            {{ capitalize(type).replace('-', '') }}
-        </QTooltip>
-    </QBtn>
+    <div class="flex items-center gap-2">
+        <template v-for="type in activeTypes">
+            <QBtn
+                :key="type"
+                v-if="phone"
+                flat
+                round
+                :icon="config[type].icon"
+                size="sm"
+                color="primary"
+                padding="none"
+                @click.stop="() => handleClick(type)"
+            >
+                <QTooltip>
+                    {{ capitalize(type).replace('-', '') }}
+                </QTooltip>
+            </QBtn></template
+        >
+        <span>{{ dashIfEmpty(phone) }}</span>
+    </div>
 </template>
diff --git a/src/components/ui/VnLv.vue b/src/components/ui/VnLv.vue
index ee3791291..aa7342742 100644
--- a/src/components/ui/VnLv.vue
+++ b/src/components/ui/VnLv.vue
@@ -43,7 +43,7 @@ const val = computed(() => $props.value);
                     <span style="color: var(--vn-label-color)">{{ label }}</span>
                 </slot>
             </div>
-            <div class="value">
+            <div class="value" v-if="value || $slots.value">
                 <slot name="value">
                     <span :title="value" style="text-overflow: ellipsis">
                         {{ dash ? dashIfEmpty(value) : value }}
diff --git a/src/components/ui/VnMoreOptions.vue b/src/components/ui/VnMoreOptions.vue
index 984e2b64f..bc81233d5 100644
--- a/src/components/ui/VnMoreOptions.vue
+++ b/src/components/ui/VnMoreOptions.vue
@@ -9,7 +9,7 @@
         data-cy="descriptor-more-opts"
     >
         <QTooltip>
-            {{ $t('components.cardDescriptor.moreOptions') }}
+            {{ $t('components.vnDescriptor.moreOptions') }}
         </QTooltip>
         <QMenu ref="menuRef" data-cy="descriptor-more-opts-menu">
             <QList data-cy="descriptor-more-opts_list">
diff --git a/src/components/ui/VnNotes.vue b/src/components/ui/VnNotes.vue
index b7e6ccbec..9cedbccfa 100644
--- a/src/components/ui/VnNotes.vue
+++ b/src/components/ui/VnNotes.vue
@@ -18,10 +18,10 @@ import VnInput from 'components/common/VnInput.vue';
 
 const emit = defineEmits(['onFetch']);
 
-const $attrs = useAttrs();
-
-const isRequired = computed(() => {
-    return Object.keys($attrs).includes('required');
+const originalAttrs = useAttrs();
+const $attrs = computed(() => {
+    const { required, deletable, ...rest } = originalAttrs;
+    return rest;
 });
 
 const $props = defineProps({
@@ -53,6 +53,11 @@ function handleClick(e) {
     else insert();
 }
 
+async function deleteNote(e) {
+    await axios.delete(`${$props.url}/${e.id}`);
+    await vnPaginateRef.value.fetch();
+}
+
 async function insert() {
     if (!newNote.text || ($props.selectType && !newNote.observationTypeFk)) return;
 
@@ -157,7 +162,7 @@ const handleObservationTypes = (data) => {
                     v-model="newNote.observationTypeFk"
                     option-label="description"
                     style="flex: 0.15"
-                    :required="isRequired"
+                    :required="'required' in originalAttrs"
                     @keyup.enter.stop="insert"
                 />
                 <VnInput
@@ -165,11 +170,10 @@ const handleObservationTypes = (data) => {
                     type="textarea"
                     :label="$props.justInput && newNote.text ? '' : t('Add note here...')"
                     filled
-                    size="lg"
                     autogrow
                     autofocus
                     @keyup.enter.stop="handleClick"
-                    :required="isRequired"
+                    :required="'required' in originalAttrs"
                     clearable
                 >
                     <template #append>
@@ -239,6 +243,21 @@ const handleObservationTypes = (data) => {
                                 </QBadge>
                             </div>
                             <span v-text="toDateHourMin(note.created)" />
+                            <div>
+                                <QIcon
+                                    v-if="'deletable' in originalAttrs"
+                                    name="delete"
+                                    size="sm"
+                                    class="cursor-pointer"
+                                    color="primary"
+                                    @click="deleteNote(note)"
+                                    data-cy="notesRemoveNoteBtn"
+                                >
+                                    <QTooltip>
+                                        {{ t('ticketNotes.removeNote') }}
+                                    </QTooltip>
+                                </QIcon>
+                            </div>
                         </div>
                     </QCardSection>
                     <QCardSection class="q-pa-xs q-my-none q-py-none">
diff --git a/src/components/ui/VnPaginate.vue b/src/components/ui/VnPaginate.vue
index b067381f6..8fbfb067f 100644
--- a/src/components/ui/VnPaginate.vue
+++ b/src/components/ui/VnPaginate.vue
@@ -115,7 +115,7 @@ onMounted(async () => {
 });
 
 onBeforeUnmount(() => {
-    if (!store.keepData) arrayData.reset(['data']);
+    arrayData.reset(['data']);
     arrayData.resetPagination();
 });
 
@@ -215,6 +215,7 @@ defineExpose({
     paginate,
     userParams: arrayData.store.userParams,
     currentFilter: arrayData.store.currentFilter,
+    arrayData,
 });
 </script>
 
diff --git a/src/components/ui/__tests__/CardSummary.spec.js b/src/components/ui/__tests__/CardSummary.spec.js
index 2f7f90882..ff6f60697 100644
--- a/src/components/ui/__tests__/CardSummary.spec.js
+++ b/src/components/ui/__tests__/CardSummary.spec.js
@@ -1,5 +1,7 @@
 import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
+
 import CardSummary from 'src/components/ui/CardSummary.vue';
 import * as vueRouter from 'vue-router';
 
diff --git a/src/components/ui/__tests__/Paginate.spec.js b/src/components/ui/__tests__/Paginate.spec.js
index a67dfcdc6..968643b67 100644
--- a/src/components/ui/__tests__/Paginate.spec.js
+++ b/src/components/ui/__tests__/Paginate.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import VnPaginate from 'src/components/ui/VnPaginate.vue';
 
 describe('VnPaginate', () => {
diff --git a/src/components/ui/__tests__/VnLinkPhone.spec.js b/src/components/ui/__tests__/VnLinkPhone.spec.js
index a34ef90a5..3c92adf95 100644
--- a/src/components/ui/__tests__/VnLinkPhone.spec.js
+++ b/src/components/ui/__tests__/VnLinkPhone.spec.js
@@ -1,5 +1,5 @@
 import { describe, it, expect, beforeAll, vi } from 'vitest';
-import { axios } from 'app/test/vitest/helper';
+import axios from 'axios';
 import parsePhone from 'src/filters/parsePhone';
 
 describe('parsePhone filter', () => {
diff --git a/src/components/ui/__tests__/VnSms.spec.js b/src/components/ui/__tests__/VnSms.spec.js
index e0f8c1868..4f4fd7d49 100644
--- a/src/components/ui/__tests__/VnSms.spec.js
+++ b/src/components/ui/__tests__/VnSms.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import VnSms from 'src/components/ui/VnSms.vue';
 
 describe('VnSms', () => {
diff --git a/src/composables/__tests__/downloadFile.spec.js b/src/composables/__tests__/downloadFile.spec.js
index f83a973b0..0cd38043f 100644
--- a/src/composables/__tests__/downloadFile.spec.js
+++ b/src/composables/__tests__/downloadFile.spec.js
@@ -1,5 +1,5 @@
 import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest';
-import { axios } from 'app/test/vitest/helper';
+import axios from 'axios';
 import { downloadFile } from 'src/composables/downloadFile';
 import { useSession } from 'src/composables/useSession';
 const session = useSession();
diff --git a/src/composables/__tests__/useAcl.spec.js b/src/composables/__tests__/useAcl.spec.js
index 6cb29984c..86cd58fa0 100644
--- a/src/composables/__tests__/useAcl.spec.js
+++ b/src/composables/__tests__/useAcl.spec.js
@@ -1,5 +1,7 @@
 import { vi, describe, expect, it, beforeAll, afterAll } from 'vitest';
-import { axios, flushPromises } from 'app/test/vitest/helper';
+import axios from 'axios';
+
+import { flushPromises } from '@vue/test-utils';
 import { useAcl } from 'src/composables/useAcl';
 
 describe('useAcl', () => {
diff --git a/src/composables/__tests__/useArrayData.spec.js b/src/composables/__tests__/useArrayData.spec.js
index a610ba9eb..a3fbbdd5d 100644
--- a/src/composables/__tests__/useArrayData.spec.js
+++ b/src/composables/__tests__/useArrayData.spec.js
@@ -1,15 +1,39 @@
 import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest';
-import { axios, flushPromises } from 'app/test/vitest/helper';
+import { default as axios } from 'axios';
 import { useArrayData } from 'composables/useArrayData';
 import { useRouter } from 'vue-router';
 import * as vueRouter from 'vue-router';
+import { setActivePinia, createPinia } from 'pinia';
 
 describe('useArrayData', () => {
     const filter = '{"limit":20,"skip":0}';
     const params = { supplierFk: 2 };
+
     beforeEach(() => {
-        vi.spyOn(useRouter(), 'replace');
-        vi.spyOn(useRouter(), 'push');
+        setActivePinia(createPinia());
+
+        // Mock route
+        vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
+            path: 'mockSection/list',
+            matched: [],
+            query: {},
+            params: {},
+            meta: { moduleName: 'mockName' },
+        });
+
+        // Mock router
+        vi.spyOn(vueRouter, 'useRouter').mockReturnValue({
+            push: vi.fn(),
+            replace: vi.fn(),
+            currentRoute: {
+                value: {
+                    path: 'mockSection/list',
+                    params: { id: 1 },
+                    meta: { moduleName: 'mockName' },
+                    matched: [{ path: 'mockName/:id' }],
+                },
+            },
+        });
     });
 
     afterEach(() => {
@@ -17,103 +41,69 @@ describe('useArrayData', () => {
     });
 
     it('should fetch and replace url with new params', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] });
+        vi.spyOn(axios, 'get').mockResolvedValueOnce({ data: [] });
 
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl' });
+        const arrayData = useArrayData('ArrayData', {
+            url: 'mockUrl',
+            searchUrl: 'params',
+        });
 
         arrayData.store.userParams = params;
-        arrayData.fetch({});
+        await arrayData.fetch({});
 
-        await flushPromises();
         const routerReplace = useRouter().replace.mock.calls[0][0];
 
-        expect(axios.get.mock.calls[0][1].params).toEqual({
-            filter,
-            supplierFk: 2,
+        expect(axios.get).toHaveBeenCalledWith('mockUrl', {
+            signal: expect.any(Object),
+            params: {
+                filter,
+                supplierFk: 2,
+            },
         });
-        expect(routerReplace.path).toEqual('mockSection/list');
+
+        expect(routerReplace.path).toBe('mockSection/list');
         expect(JSON.parse(routerReplace.query.params)).toEqual(
             expect.objectContaining(params),
         );
     });
 
-    it('should get data and send new URL without keeping parameters, if there is only one record', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }] });
+    it('should redirect to detail when single record is returned with navigation', async () => {
+        vi.spyOn(axios, 'get').mockResolvedValueOnce({
+            data: [{ id: 1 }],
+        });
 
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });
+        const arrayData = useArrayData('ArrayData', {
+            url: 'mockUrl',
+            navigate: {},
+        });
 
         arrayData.store.userParams = params;
-        arrayData.fetch({});
+        await arrayData.fetch({});
 
-        await flushPromises();
         const routerPush = useRouter().push.mock.calls[0][0];
 
-        expect(axios.get.mock.calls[0][1].params).toEqual({
-            filter,
-            supplierFk: 2,
-        });
-        expect(routerPush.path).toEqual('mockName/1');
+        expect(routerPush.path).toBe('mockName/1');
         expect(routerPush.query).toBeUndefined();
     });
 
-    it('should get data and send new URL keeping parameters, if you have more than one record', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [{ id: 1 }, { id: 2 }] });
-
-        vi.spyOn(vueRouter, 'useRoute').mockReturnValue({
-            matched: [],
-            query: {},
-            params: {},
-            meta: { moduleName: 'mockName' },
-            path: 'mockName/1',
-        });
-        vi.spyOn(vueRouter, 'useRouter').mockReturnValue({
-            push: vi.fn(),
-            replace: vi.fn(),
-            currentRoute: {
-                value: {
-                    params: {
-                        id: 1,
-                    },
-                    meta: { moduleName: 'mockName' },
-                    matched: [{ path: 'mockName/:id' }],
-                },
-            },
-        });
-
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', navigate: {} });
-
-        arrayData.store.userParams = params;
-        arrayData.fetch({});
-
-        await flushPromises();
-        const routerPush = useRouter().push.mock.calls[0][0];
-
-        expect(axios.get.mock.calls[0][1].params).toEqual({
-            filter,
-            supplierFk: 2,
-        });
-        expect(routerPush.path).toEqual('mockName/');
-        expect(routerPush.query.params).toBeDefined();
-    });
-
-    it('should return one record', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({
+    it('should return one record when oneRecord is true', async () => {
+        vi.spyOn(axios, 'get').mockResolvedValueOnce({
             data: [
                 { id: 1, name: 'Entity 1' },
                 { id: 2, name: 'Entity 2' },
             ],
         });
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true });
+
+        const arrayData = useArrayData('ArrayData', {
+            url: 'mockUrl',
+            oneRecord: true,
+        });
+
         await arrayData.fetch({});
 
-        expect(arrayData.store.data).toEqual({ id: 1, name: 'Entity 1' });
-    });
-
-    it('should handle empty data gracefully if has to return one record', async () => {
-        vi.spyOn(axios, 'get').mockReturnValueOnce({ data: [] });
-        const arrayData = useArrayData('ArrayData', { url: 'mockUrl', oneRecord: true });
-        await arrayData.fetch({});
-
-        expect(arrayData.store.data).toBeUndefined();
+        expect(arrayData.store.data).toEqual({
+            id: 1,
+            name: 'Entity 1',
+        });
     });
 });
diff --git a/src/composables/__tests__/useRole.spec.js b/src/composables/__tests__/useRole.spec.js
index d0bca5342..017301a1b 100644
--- a/src/composables/__tests__/useRole.spec.js
+++ b/src/composables/__tests__/useRole.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it } from 'vitest';
-import { axios, flushPromises } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { flushPromises } from '@vue/test-utils';
 import { useRole } from 'composables/useRole';
 const role = useRole();
 
@@ -23,18 +24,19 @@ describe('useRole', () => {
                 name: `T'Challa`,
                 nickname: 'Black Panther',
                 lang: 'en',
+                worker: { department: { departmentFk: 155 } },
             };
             const expectedUser = {
                 id: 999,
                 name: `T'Challa`,
                 nickname: 'Black Panther',
                 lang: 'en',
+                departmentFk: 155,
             };
             const expectedRoles = ['salesPerson', 'admin'];
-            vi.spyOn(axios, 'get')
-            .mockResolvedValueOnce({
+            vi.spyOn(axios, 'get').mockResolvedValueOnce({
                 data: { roles: rolesData, user: fetchedUser },
-            })
+            });
 
             vi.spyOn(role.state, 'setUser');
             vi.spyOn(role.state, 'setRoles');
diff --git a/src/composables/__tests__/useSession.spec.js b/src/composables/__tests__/useSession.spec.js
index 789b149ec..e86847b70 100644
--- a/src/composables/__tests__/useSession.spec.js
+++ b/src/composables/__tests__/useSession.spec.js
@@ -1,5 +1,5 @@
 import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest';
-import { axios } from 'app/test/vitest/helper';
+import axios from 'axios';
 import { useSession } from 'composables/useSession';
 import { useState } from 'composables/useState';
 
@@ -75,6 +75,7 @@ describe('session', () => {
                 userConfig: {
                     darkMode: false,
                 },
+                worker: { department: { departmentFk: 155 } },
             };
             const rolesData = [
                 {
@@ -143,7 +144,7 @@ describe('session', () => {
                 await session.destroy(); // this clears token and user for any other test
             });
         },
-        {}
+        {},
     );
 
     describe('RenewToken', () => {
@@ -175,7 +176,7 @@ describe('session', () => {
             await session.checkValidity();
             expect(sessionStorage.getItem('token')).toEqual(expectedToken);
             expect(sessionStorage.getItem('tokenMultimedia')).toEqual(
-                expectedTokenMultimedia
+                expectedTokenMultimedia,
             );
         });
         it('Should renewToken', async () => {
@@ -204,7 +205,7 @@ describe('session', () => {
             await session.checkValidity();
             expect(sessionStorage.getItem('token')).not.toEqual(expectedToken);
             expect(sessionStorage.getItem('tokenMultimedia')).not.toEqual(
-                expectedTokenMultimedia
+                expectedTokenMultimedia,
             );
         });
     });
diff --git a/src/composables/__tests__/useTokenConfig.spec.js b/src/composables/__tests__/useTokenConfig.spec.js
index a25a4abb1..92664e65a 100644
--- a/src/composables/__tests__/useTokenConfig.spec.js
+++ b/src/composables/__tests__/useTokenConfig.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it } from 'vitest';
-import { axios, flushPromises } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { flushPromises } from '@vue/test-utils';
 import { useTokenConfig } from 'composables/useTokenConfig';
 const tokenConfig = useTokenConfig();
 
diff --git a/src/composables/useAcl.js b/src/composables/useAcl.js
index ede359186..52704fee9 100644
--- a/src/composables/useAcl.js
+++ b/src/composables/useAcl.js
@@ -30,9 +30,16 @@ export function useAcl() {
         return false;
     }
 
+    function hasAcl(model, prop, accessType) {
+        const modelAcl = state.getAcls().value[model];
+        const propAcl = modelAcl?.[prop] || modelAcl?.['*'];
+        return !!(propAcl?.[accessType] || propAcl?.['*']);
+    }
+
     return {
         fetch,
         hasAny,
         state,
+        hasAcl,
     };
 }
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
index d1c1b01b8..2e880a16d 100644
--- a/src/composables/useArrayData.js
+++ b/src/composables/useArrayData.js
@@ -5,12 +5,11 @@ import { useArrayDataStore } from 'stores/useArrayDataStore';
 import { buildFilter } from 'filters/filterPanel';
 import { isDialogOpened } from 'src/filters';
 
-const arrayDataStore = useArrayDataStore();
-
 export function useArrayData(key, userOptions) {
     key ??= useRoute().meta.moduleName;
 
     if (!key) throw new Error('ArrayData: A key is required to use this composable');
+    const arrayDataStore = useArrayDataStore(); // Move inside function
 
     if (!arrayDataStore.get(key)) arrayDataStore.set(key);
 
@@ -56,7 +55,6 @@ export function useArrayData(key, userOptions) {
             'searchUrl',
             'navigate',
             'mapKey',
-            'keepData',
             'oneRecord',
         ];
         if (typeof userOptions === 'object') {
@@ -108,7 +106,7 @@ export function useArrayData(key, userOptions) {
         store.hasMoreData = limit && response.data.length >= limit;
 
         if (!append && !isDialogOpened() && updateRouter) {
-            if (updateStateParams(response.data)?.redirect && !store.keepData) return;
+            if (updateStateParams(response.data)?.redirect) return;
         }
         store.isLoading = false;
         canceller = null;
@@ -189,7 +187,7 @@ export function useArrayData(key, userOptions) {
 
         store.order = order;
         resetPagination();
-        fetch({});
+        await fetch({});
         index++;
 
         return { index, order };
diff --git a/src/composables/useFilterParams.js b/src/composables/useFilterParams.js
index 07dcdf99b..7c3f3bdeb 100644
--- a/src/composables/useFilterParams.js
+++ b/src/composables/useFilterParams.js
@@ -14,7 +14,7 @@ export function useFilterParams(key) {
     watch(
         () => arrayData.value.store?.currentFilter,
         (val, oldValue) => (val || oldValue) && setUserParams(val),
-        { immediate: true, deep: true }
+        { immediate: true, deep: true },
     );
 
     function parseOrder(urlOrders) {
@@ -54,7 +54,7 @@ export function useFilterParams(key) {
                     Object.assign(params, item);
                 });
                 delete params[key];
-            } else if (value && typeof value === 'object') {
+            } else if (value && typeof value === 'object' && !Array.isArray(value)) {
                 const param = Object.values(value)[0];
                 if (typeof param == 'string') params[key] = param.replaceAll('%', '');
             }
diff --git a/src/composables/useRole.js b/src/composables/useRole.js
index ff54b409c..e4e4f52c7 100644
--- a/src/composables/useRole.js
+++ b/src/composables/useRole.js
@@ -13,6 +13,7 @@ export function useRole() {
             name: data.user.name,
             nickname: data.user.nickname,
             lang: data.user.lang || 'es',
+            departmentFk: data.user?.worker?.department?.departmentFk,
         };
         state.setUser(userData);
         state.setRoles(roles);
diff --git a/src/composables/useSession.js b/src/composables/useSession.js
index e69819a68..36b31ab0a 100644
--- a/src/composables/useSession.js
+++ b/src/composables/useSession.js
@@ -60,7 +60,7 @@ export function useSession() {
                 const { data: isValidToken } = await axios.get('VnUsers/validateToken');
                 if (isValidToken)
                     destroyTokenPromises = Object.entries(tokens).map(([key, url]) =>
-                        destroyToken(url, storage, key)
+                        destroyToken(url, storage, key),
                     );
             }
         } finally {
diff --git a/src/composables/useValidator.js b/src/composables/useValidator.js
index 7a7032608..ae6c47d91 100644
--- a/src/composables/useValidator.js
+++ b/src/composables/useValidator.js
@@ -78,7 +78,8 @@ export function useValidator() {
                 if (min >= 0)
                     if (Math.floor(value) < min) return t('inputMin', { value: min });
             },
-            custom: (value) => validation.bindedFunction(value) || 'Invalid value',
+            custom: (value) =>
+                eval(`(${validation.bindedFunction})`)(value) || 'Invalid value',
         };
     };
 
diff --git a/src/css/app.scss b/src/css/app.scss
index b299973d1..dd5dbe247 100644
--- a/src/css/app.scss
+++ b/src/css/app.scss
@@ -340,3 +340,6 @@ input::-webkit-inner-spin-button {
 .containerShrinked {
     width: 70%;
 }
+.q-item__section--main ~ .q-item__section--side {
+    padding-inline: 0;
+}
diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml
index c62305f95..7bcf90793 100644
--- a/src/i18n/locale/en.yml
+++ b/src/i18n/locale/en.yml
@@ -370,6 +370,11 @@ globals:
         countryCodeFk: Country
         companyFk: Company
         nickname: Alias
+        changedModel: Entity
+        changedModelValue: Search
+        changedModelId: Entity id
+        userFk: User
+        action: Action
     model: Model
     fuel: Fuel
     active: Active
@@ -842,6 +847,7 @@ travel:
         availabledHour: Availabled hour
         thermographs: Thermographs
         hb: HB
+        roundedCc: Rounded CC
     basicData:
         daysInForward: Automatic movement (Raid)
         isRaid: Raid
@@ -884,7 +890,7 @@ components:
         openCard: View
         openSummary: Summary
         viewSummary: Summary
-    cardDescriptor:
+    vnDescriptor:
         mainList: Main list
         summary: Summary
         moreOptions: More options
diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml
index 86d15e985..b2512193d 100644
--- a/src/i18n/locale/es.yml
+++ b/src/i18n/locale/es.yml
@@ -371,6 +371,11 @@ globals:
         countryCodeFk: PaĂ­s
         companyFk: Empresa
         nickname: Alias
+        changedModel: Entidad
+        changedModelValue: Buscar
+        changedModelId: Id de entidad
+        userFk: Usuario
+        action: AcciĂłn
 errors:
     statusUnauthorized: Acceso denegado
     statusInternalServerError: Ha ocurrido un error interno del servidor
@@ -925,6 +930,7 @@ travel:
         availabled: F. Disponible
         availabledHour: Hora Disponible
         hb: HB
+        roundedCc: CC redondeado
     basicData:
         daysInForward: Desplazamiento automatico (redada)
         isRaid: Redada
@@ -968,7 +974,7 @@ components:
         openCard: Ficha
         openSummary: Detalles
         viewSummary: Vista previa
-    cardDescriptor:
+    vnDescriptor:
         mainList: Listado principal
         summary: Resumen
         moreOptions: Más opciones
diff --git a/src/pages/Account/Card/AccountDescriptorMenu.vue b/src/pages/Account/Card/AccountDescriptorMenu.vue
index eafd62df6..f3eabb531 100644
--- a/src/pages/Account/Card/AccountDescriptorMenu.vue
+++ b/src/pages/Account/Card/AccountDescriptorMenu.vue
@@ -100,12 +100,8 @@ const onChangePass = (oldPass) => {
 };
 
 onMounted(() => {
-    hasitManagementAccess.value = useAcl().hasAny([
-        { model: 'VnUser', props: 'higherPrivileges', accessType: 'WRITE' },
-    ]);
-    hasSysadminAccess.value = useAcl().hasAny([
-        { model: 'VnUser', props: 'adminUser', accessType: 'WRITE' },
-    ]);
+    hasitManagementAccess.value = useAcl().hasAcl('VnUser', 'higherPrivileges', 'WRITE');
+    hasSysadminAccess.value = useAcl().hasAcl('VnUser', 'adminUser', 'WRITE');
 });
 </script>
 <template>
@@ -227,7 +223,7 @@ onMounted(() => {
         <QItemSection>{{ t('account.card.actions.deactivateUser.name') }}</QItemSection>
     </QItem>
     <QItem
-        v-if="useAcl().hasAny([{ model: 'VnRole', props: '*', accessType: 'WRITE' }])"
+        v-if="useAcl().hasAcl('VnRole', '*', 'WRITE')"
         v-ripple
         clickable
         @click="showSyncDialog = true"
diff --git a/src/pages/Account/Card/AccountDescriptorProxy.vue b/src/pages/Account/Card/AccountDescriptorProxy.vue
index de3220fea..6a4b3e267 100644
--- a/src/pages/Account/Card/AccountDescriptorProxy.vue
+++ b/src/pages/Account/Card/AccountDescriptorProxy.vue
@@ -6,7 +6,7 @@ import AccountSummary from './AccountSummary.vue';
     <QPopupProxy style="max-width: 10px">
         <AccountDescriptor
             v-if="$attrs.id"
-            v-bind="$attrs.id"
+            v-bind="$attrs"
             :summary="AccountSummary"
             :proxy-render="true"
         />
diff --git a/src/pages/Claim/Card/ClaimSummary.vue b/src/pages/Claim/Card/ClaimSummary.vue
index 5d06d5627..67d57004f 100644
--- a/src/pages/Claim/Card/ClaimSummary.vue
+++ b/src/pages/Claim/Card/ClaimSummary.vue
@@ -21,6 +21,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 import DepartmentDescriptorProxy from 'src/pages/Worker/Department/Card/DepartmentDescriptorProxy.vue';
 import ClaimDescriptorMenu from './ClaimDescriptorMenu.vue';
+import VnDropdown from 'src/components/common/VnDropdown.vue';
 
 const route = useRoute();
 const router = useRouter();
@@ -36,7 +37,7 @@ const $props = defineProps({
 });
 
 const entityId = computed(() => $props.id || route.params.id);
-const ClaimStates = ref([]);
+const claimStates = ref([]);
 const claimDmsRef = ref();
 const claimDms = ref([]);
 const multimediaDialog = ref();
@@ -173,7 +174,9 @@ function openDialog(dmsId) {
 }
 
 async function changeState(value) {
-    await axios.patch(`Claims/updateClaim/${entityId.value}`, { claimStateFk: value });
+    await axios.patch(`Claims/updateClaim/${entityId.value}`, {
+        claimStateFk: value,
+    });
     router.go(route.fullPath);
 }
 
@@ -183,13 +186,18 @@ function claimUrl(section) {
 </script>
 
 <template>
+    <FetchData
+        url="ClaimStates"
+        :filter="{ fields: ['id', 'description'] }"
+        @on-fetch="(data) => (claimStates = data)"
+        auto-load
+    />
     <FetchData
         url="ClaimDms"
         :filter="claimDmsFilter"
         @on-fetch="(data) => setClaimDms(data)"
         ref="claimDmsRef"
     />
-    <FetchData url="ClaimStates" @on-fetch="(data) => (ClaimStates = data)" auto-load />
     <CardSummary
         ref="summary"
         :url="`Claims/${entityId}/getSummary`"
@@ -201,34 +209,11 @@ function claimUrl(section) {
             {{ claim.id }} - {{ claim.client.name }} ({{ claim.client.id }})
         </template>
         <template #header-right>
-            <QBtnDropdown
-                side
-                top
-                color="black"
-                text-color="white"
-                :label="t('globals.changeState')"
-            >
-                <QList>
-                    <QVirtualScroll
-                        class="max-container-height"
-                        :items="ClaimStates"
-                        separator
-                        v-slot="{ item, index }"
-                    >
-                        <QItem
-                            :key="index"
-                            dense
-                            clickable
-                            v-close-popup
-                            @click="changeState(item.id)"
-                        >
-                            <QItemSection>
-                                <QItemLabel>{{ item.description }}</QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </QVirtualScroll>
-                </QList>
-            </QBtnDropdown>
+            <VnDropdown
+                :options="claimStates"
+                option-label="description"
+                @change-state="changeState"
+            />
         </template>
         <template #menu="{ entity }">
             <ClaimDescriptorMenu :claim="entity.claim" />
diff --git a/src/pages/Claim/Card/ClaimSummaryAction.vue b/src/pages/Claim/Card/ClaimSummaryAction.vue
index 577ac2a65..be3b9e896 100644
--- a/src/pages/Claim/Card/ClaimSummaryAction.vue
+++ b/src/pages/Claim/Card/ClaimSummaryAction.vue
@@ -88,13 +88,13 @@ const columns = [
         auto-load
     >
         <template #column-itemFk="{ row }">
-            <span class="link">
+            <span class="link" @click.stop>
                 {{ row.itemFk }}
                 <ItemDescriptorProxy :id="row.itemFk" />
             </span>
         </template>
         <template #column-ticketFk="{ row }">
-            <span class="link">
+            <span class="link" @click.stop>
                 {{ row.ticketFk }}
                 <TicketDescriptorProxy :id="row.ticketFk" />
             </span>
diff --git a/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js b/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js
index b208f1704..2142f41f2 100644
--- a/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js
+++ b/src/pages/Claim/Card/__tests__/ClaimDescriptorMenu.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import ClaimDescriptorMenu from 'pages/Claim/Card/ClaimDescriptorMenu.vue';
 
 describe('ClaimDescriptorMenu', () => {
diff --git a/src/pages/Claim/Card/__tests__/ClaimLines.spec.js b/src/pages/Claim/Card/__tests__/ClaimLines.spec.js
index 2f2c0e298..d975fb514 100644
--- a/src/pages/Claim/Card/__tests__/ClaimLines.spec.js
+++ b/src/pages/Claim/Card/__tests__/ClaimLines.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import ClaimLines from '/src/pages/Claim/Card/ClaimLines.vue';
 
 describe('ClaimLines', () => {
diff --git a/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js b/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js
index d93c96132..2a5176d0a 100644
--- a/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js
+++ b/src/pages/Claim/Card/__tests__/ClaimLinesImport.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, beforeEach, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import ClaimLinesImport from 'pages/Claim/Card/ClaimLinesImport.vue';
 
 describe('ClaimLinesImport', () => {
diff --git a/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js b/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js
index c38852af1..b14338b5c 100644
--- a/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js
+++ b/src/pages/Claim/Card/__tests__/ClaimPhoto.spec.js
@@ -1,7 +1,7 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import ClaimPhoto from 'pages/Claim/Card/ClaimPhoto.vue';
-
 describe('ClaimPhoto', () => {
     let vm;
 
@@ -61,7 +61,7 @@ describe('ClaimPhoto', () => {
                         title: 'This file will be deleted',
                         icon: 'delete',
                         data: { index: 1 },
-                        promise: vm.deleteDms
+                        promise: vm.deleteDms,
                     },
                 })
             );
diff --git a/src/pages/Claim/ClaimFilter.vue b/src/pages/Claim/ClaimFilter.vue
index 51460f7e4..45eb89382 100644
--- a/src/pages/Claim/ClaimFilter.vue
+++ b/src/pages/Claim/ClaimFilter.vue
@@ -115,6 +115,7 @@ const props = defineProps({
 <i18n>
 en:
     params:
+        departmentFk: Department
         search: Contains
         clientFk: Customer
         clientName: Customer
@@ -127,6 +128,7 @@ en:
         zoneFk: Zone
 es:
     params:
+        departmentFk: Departamento
         search: Contiene
         clientFk: Cliente
         clientName: Cliente
diff --git a/src/pages/Claim/ClaimList.vue b/src/pages/Claim/ClaimList.vue
index 06996c2c1..e0d9928f9 100644
--- a/src/pages/Claim/ClaimList.vue
+++ b/src/pages/Claim/ClaimList.vue
@@ -134,7 +134,7 @@ const columns = computed(() => [
 
 const STATE_COLOR = {
     pending: 'bg-warning',
-    managed: 'bg-info',
+    loses: 'bg-negative',
     resolved: 'bg-positive',
 };
 </script>
diff --git a/src/pages/Customer/Card/CustomerBalance.vue b/src/pages/Customer/Card/CustomerBalance.vue
index 11db92eab..4855fadc0 100644
--- a/src/pages/Customer/Card/CustomerBalance.vue
+++ b/src/pages/Customer/Card/CustomerBalance.vue
@@ -20,11 +20,12 @@ import VnFilter from 'components/VnTable/VnFilter.vue';
 
 import CustomerNewPayment from 'src/pages/Customer/components/CustomerNewPayment.vue';
 import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
+import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
 
 const { openConfirmationModal } = useVnConfirm();
 const { sendEmail, openReport } = usePrintService();
 const { t } = useI18n();
-const { hasAny } = useAcl();
+const { hasAcl } = useAcl();
 
 const quasar = useQuasar();
 const route = useRoute();
@@ -89,15 +90,7 @@ const columns = computed(() => [
     {
         align: 'left',
         label: t('Employee'),
-        columnField: {
-            component: 'userLink',
-            attrs: ({ row }) => {
-                return {
-                    workerId: row.workerFk,
-                    name: row.userName,
-                };
-            },
-        },
+        name: 'workerFk',
         cardVisible: true,
     },
     {
@@ -131,7 +124,6 @@ const columns = computed(() => [
         align: 'left',
         name: 'balance',
         label: t('Balance'),
-        format: ({ balance }) => toCurrency(balance),
         cardVisible: true,
     },
     {
@@ -146,12 +138,14 @@ const columns = computed(() => [
         actions: [
             {
                 title: t('globals.downloadPdf'),
+                isPrimary: true,
                 icon: 'cloud_download',
                 show: (row) => row.isInvoice,
                 action: (row) => showBalancePdf(row),
             },
             {
                 title: t('Send compensation'),
+                isPrimary: true,
                 icon: 'outgoing_mail',
                 show: (row) => !!row.isCompensation,
                 action: ({ id }) =>
@@ -256,6 +250,12 @@ const showBalancePdf = ({ id }) => {
         <template #column-balance="{ rowIndex }">
             {{ toCurrency(balances[rowIndex]?.balance) }}
         </template>
+        <template #column-workerFk="{ row }">
+            <span class="link" @click.stop>
+                {{ row.userName }}
+                <WorkerDescriptorProxy :id="row.workerFk" />
+            </span>
+        </template>
         <template #column-description="{ row }">
             <span class="link" v-if="row.isInvoice" @click.stop>
                 {{ t('bill', { ref: row.description }) }}
@@ -276,9 +276,7 @@ const showBalancePdf = ({ id }) => {
             >
                 <VnInput
                     v-model="scope.value"
-                    :disable="
-                        !hasAny([{ model: 'Receipt', props: '*', accessType: 'WRITE' }])
-                    "
+                    :disable="!hasAcl('Receipt', '*', 'WRITE')"
                     @keypress.enter="scope.set"
                     autofocus
                 />
diff --git a/src/pages/Customer/Card/CustomerFiscalData.vue b/src/pages/Customer/Card/CustomerFiscalData.vue
index 93909eb9c..baa728868 100644
--- a/src/pages/Customer/Card/CustomerFiscalData.vue
+++ b/src/pages/Customer/Card/CustomerFiscalData.vue
@@ -79,7 +79,7 @@ async function acceptPropagate({ isEqualizated }) {
         observe-form-changes
         @on-data-saved="checkEtChanges"
     >
-        <template #form="{ data, validate }">
+        <template #form="{ data, validate, validations }">
             <VnRow>
                 <VnInput
                     :label="t('Social name')"
@@ -112,6 +112,7 @@ async function acceptPropagate({ isEqualizated }) {
                     v-model="data.sageTaxTypeFk"
                     data-cy="sageTaxTypeFk"
                     :required="data.isTaxDataChecked"
+                    :rules="[(val) => validations.required(data.isTaxDataChecked, val)]"
                 />
                 <VnSelect
                     :label="t('Sage transaction type')"
@@ -122,6 +123,9 @@ async function acceptPropagate({ isEqualizated }) {
                     data-cy="sageTransactionTypeFk"
                     v-model="data.sageTransactionTypeFk"
                     :required="data.isTaxDataChecked"
+                    :rules="[
+                        (val) => validations.required(data.sageTransactionTypeFk, val),
+                    ]"
                 >
                     <template #option="scope">
                         <QItem v-bind="scope.itemProps">
diff --git a/src/pages/Customer/Card/CustomerSummary.vue b/src/pages/Customer/Card/CustomerSummary.vue
index a9179d924..af7231d6f 100644
--- a/src/pages/Customer/Card/CustomerSummary.vue
+++ b/src/pages/Customer/Card/CustomerSummary.vue
@@ -84,29 +84,31 @@ const sumRisk = ({ clientRisks }) => {
                 <VnLv :label="t('customer.summary.customerId')" :value="entity.id" />
                 <VnLv :label="t('globals.name')" :value="entity.name" />
                 <VnLv :label="t('customer.summary.contact')" :value="entity.contact" />
-                <VnLv :value="entity.phone">
-                    <template #label>
-                        {{ t('customer.extendedList.tableVisibleColumns.phone') }}
+                <VnLv :label="t('customer.extendedList.tableVisibleColumns.phone')">
+                    <template #value>
                         <VnLinkPhone :phone-number="entity.phone" />
                     </template>
                 </VnLv>
-                <VnLv :value="entity.mobile">
-                    <template #label>
-                        {{ t('customer.summary.mobile') }}
-                        <VnLinkPhone :phone-number="entity.mobile" />
+                <VnLv :label="t('customer.summary.mobile')">
+                    <template #value>
                         <VnLinkPhone
+                            sip
                             say-simple
                             :phone-number="entity.mobile"
                             :channel="entity.country?.saySimpleCountry?.channel"
-                            class="q-ml-xs"
                         />
                     </template>
                 </VnLv>
-                <VnLv :value="entity.email" copy
-                    ><template #label>
-                        {{ t('globals.params.email') }}
-                        <VnLinkMail email="entity.email"></VnLinkMail> </template
-                ></VnLv>
+                <VnLv
+                    :label="t('globals.params.email')"
+                    :value="entity.email"
+                    class="ellipsis"
+                    copy
+                >
+                    <template #value>
+                        <VnLinkMail :email="entity.email" />
+                    </template>
+                </VnLv>
                 <VnLv :label="t('globals.department')">
                     <template #value>
                         <span class="link" v-text="entity.department?.name" />
diff --git a/src/pages/Customer/CustomerFilter.vue b/src/pages/Customer/CustomerFilter.vue
index 55a7f565e..c30b11528 100644
--- a/src/pages/Customer/CustomerFilter.vue
+++ b/src/pages/Customer/CustomerFilter.vue
@@ -72,6 +72,7 @@ const exprBuilder = (param, value) => {
                         option-value="id"
                         option-label="name"
                         url="Departments"
+                        no-one="true"
                     />
                 </QItemSection>
             </QItem>
@@ -154,6 +155,7 @@ en:
         city: City
         phone: Phone
         email: Email
+        departmentFk: Department
         isToBeMailed: Mailed
         isEqualizated: Equailized
         businessTypeFk: Business type
@@ -166,6 +168,7 @@ en:
         postcode: Postcode
 es:
     params:
+        departmentFk: Departamento
         search: Contiene
         fi: NIF
         isActive: Activo
diff --git a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue
index 64e3baeb5..f7d4163d1 100644
--- a/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue
+++ b/src/pages/Customer/Defaulter/CustomerDefaulterFilter.vue
@@ -192,8 +192,10 @@ en:
         date: L. O. Date
         credit: Credit I.
         defaulterSinced: From
+        departmentFk: Department
 es:
     params:
+        departmentFk: Departamento
         clientFk: Cliente
         countryFk: PaĂ­s
         paymentMethod: F. Pago
diff --git a/src/pages/Customer/Notifications/CustomerNotifications.vue b/src/pages/Customer/Notifications/CustomerNotifications.vue
index b30ed6f76..cbbd6d205 100644
--- a/src/pages/Customer/Notifications/CustomerNotifications.vue
+++ b/src/pages/Customer/Notifications/CustomerNotifications.vue
@@ -127,6 +127,7 @@ es:
     Identifier: Identificador
     Social name: RazĂłn social
     Phone: Teléfono
+    Postcode: CĂłdigo postal
     City: PoblaciĂłn
     Email: Email
     Campaign consumption: Consumo campaña
diff --git a/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js b/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js
index 466a544b4..a9c845cec 100644
--- a/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js
+++ b/src/pages/Customer/Payments/__tests__/CustomerPayments.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import CustomerPayments from 'src/pages/Customer/Payments/CustomerPayments.vue';
 
 describe('CustomerPayments', () => {
diff --git a/src/pages/Customer/components/CustomerAddressEdit.vue b/src/pages/Customer/components/CustomerAddressEdit.vue
index f852c160a..bc76f5985 100644
--- a/src/pages/Customer/components/CustomerAddressEdit.vue
+++ b/src/pages/Customer/components/CustomerAddressEdit.vue
@@ -93,10 +93,26 @@ const updateAddressTicket = async () => {
 };
 
 const updateObservations = async (payload) => {
-    await axios.post('AddressObservations/crud', payload);
+    await axios.post('AddressObservations/crud', cleanPayload(payload));
     notes.value = [];
     deletes.value = [];
 };
+
+function cleanPayload(payload) {
+    ['creates', 'deletes', 'updates'].forEach((prop) => {
+        if (prop === 'creates' || prop === 'updates') {
+            payload[prop] = payload[prop].filter(
+                (item) => item.description !== '' && item.observationTypeFk !== '',
+            );
+        } else {
+            payload[prop] = payload[prop].filter(
+                (item) => item !== null && item !== undefined,
+            );
+        }
+    });
+    return payload;
+}
+
 async function updateAll({ data, payload }) {
     await updateObservations(payload);
     await updateAddress(data);
diff --git a/src/pages/Customer/components/CustomerNewPayment.vue b/src/pages/Customer/components/CustomerNewPayment.vue
index ac80fdaa4..fb3804d55 100644
--- a/src/pages/Customer/components/CustomerNewPayment.vue
+++ b/src/pages/Customer/components/CustomerNewPayment.vue
@@ -3,18 +3,20 @@ import { onBeforeMount, reactive, ref } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 import axios from 'axios';
-import { getClientRisk } from '../composables/getClientRisk';
 import { useDialogPluginComponent } from 'quasar';
-import FormModelPopup from 'components/FormModelPopup.vue';
+
+import { getClientRisk } from '../composables/getClientRisk';
 import { usePrintService } from 'composables/usePrintService';
 import useNotify from 'src/composables/useNotify.js';
+
+import FormModelPopup from 'components/FormModelPopup.vue';
 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';
+import VnAccountNumber from 'src/components/common/VnAccountNumber.vue';
 
 const { t } = useI18n();
 const route = useRoute();
@@ -48,7 +50,7 @@ const maxAmount = ref();
 const accountingType = ref({});
 const isCash = ref(false);
 const formModelRef = ref(false);
-
+const amountToReturn = ref();
 const filterBanks = {
     fields: ['id', 'bank', 'accountingTypeFk'],
     include: { relation: 'accountingType' },
@@ -90,7 +92,7 @@ function setPaymentType(data, accounting) {
     let descriptions = [];
     if (accountingType.value.receiptDescription)
         descriptions.push(accountingType.value.receiptDescription);
-    if (data.description) descriptions.push(data.description);
+    if (data.description > 0) descriptions.push(data.description);
     data.description = descriptions.join(', ');
 }
 
@@ -100,7 +102,7 @@ const calculateFromAmount = (event) => {
 };
 
 const calculateFromDeliveredAmount = (event) => {
-    initialData.amountToReturn = parseFloat(event) - initialData.amountPaid;
+    amountToReturn.value = event - initialData.amountPaid;
 };
 
 function onBeforeSave(data) {
@@ -121,17 +123,16 @@ async function onDataSaved(formData, { id }) {
                 recipient: formData.email,
             });
 
-        if (viewReceipt.value) openReport(`Receipts/${id}/receipt-pdf`);
+        if (viewReceipt.value) openReport(`Receipts/${id}/receipt-pdf`, {}, '_blank');
     } finally {
         if ($props.promise) $props.promise();
         if (closeButton.value) closeButton.value.click();
     }
 }
 
-async function accountShortToStandard({ target: { value } }) {
+async function getSupplierClientReferences(value) {
     if (!value) return (initialData.description = '');
-    initialData.compensationAccount = value.replace('.', '0'.repeat(11 - value.length));
-    const params = { bankAccount: initialData.compensationAccount };
+    const params = { bankAccount: value };
     const { data } = await axios(`Clients/getClientOrSupplierReference`, { params });
     if (!data.clientId) {
         initialData.description = t('Supplier Compensation Reference', {
@@ -241,17 +242,16 @@ async function getAmountPaid() {
                         @update:model-value="getAmountPaid()"
                     />
                 </VnRow>
-
-                <div v-if="data.bankFk?.accountingType?.code == 'compensation'">
+                <div v-if="accountingType.code == 'compensation'">
                     <div class="text-h6">
                         {{ t('Compensation') }}
                     </div>
                     <VnRow>
-                        <VnInputNumber
+                        <VnAccountNumber
                             :label="t('Compensation account')"
                             clearable
                             v-model="data.compensationAccount"
-                            @blur="accountShortToStandard"
+                            @blur="getSupplierClientReferences(data.compensationAccount)"
                         />
                     </VnRow>
                 </div>
@@ -261,8 +261,7 @@ async function getAmountPaid() {
                     clearable
                     v-model="data.description"
                 />
-
-                <div v-if="data.bankFk?.accountingType?.code == 'cash'">
+                <div v-if="accountingType.code == 'cash'">
                     <div class="text-h6">{{ t('Cash') }}</div>
                     <VnRow>
                         <VnInputNumber
@@ -274,7 +273,7 @@ async function getAmountPaid() {
                         <VnInputNumber
                             :label="t('Amount to return')"
                             disable
-                            v-model="data.amountToReturn"
+                            v-model="amountToReturn"
                         />
                     </VnRow>
                     <VnRow>
diff --git a/src/pages/Customer/components/CustomerSummaryTable.vue b/src/pages/Customer/components/CustomerSummaryTable.vue
index 09c7e714c..feb137065 100644
--- a/src/pages/Customer/components/CustomerSummaryTable.vue
+++ b/src/pages/Customer/components/CustomerSummaryTable.vue
@@ -191,7 +191,7 @@ const getItemPackagingType = (ticketSales) => {
         :without-header="true"
         auto-load
         :row-click="rowClick"
-        order="shipped DESC, id"
+        order="shipped DESC, id DESC"
         :disable-option="{ card: true, table: true }"
         class="full-width"
         :disable-infinite-scroll="true"
diff --git a/src/pages/Entry/Card/EntryBuys.vue b/src/pages/Entry/Card/EntryBuys.vue
index a93b0801b..baa4d96b7 100644
--- a/src/pages/Entry/Card/EntryBuys.vue
+++ b/src/pages/Entry/Card/EntryBuys.vue
@@ -648,7 +648,7 @@ onMounted(() => {
         :url="`Entries/${entityId}/getBuyList`"
         search-url="EntryBuys"
         save-url="Buys/crud"
-        :filter="filter"
+        :filter="editableMode ? filter : {}"
         :disable-option="{ card: true }"
         v-model:selected="selectedRows"
         @on-fetch="() => footerFetchDataRef.fetch()"
@@ -787,7 +787,7 @@ onMounted(() => {
             <span data-cy="footer-amount">{{ footer?.amount }} / </span>
             <span style="color: var(--q-positive)">{{ footer?.checkedAmount }}</span>
         </template>
-        <template #column-create-itemFk="{ data }">
+        <template #column-create-itemFk="{ data, validations }">
             <VnSelect
                 url="Items/search"
                 v-model="data.itemFk"
@@ -801,7 +801,8 @@ onMounted(() => {
                         await setBuyUltimate(value, data);
                     }
                 "
-                :required="true"
+                required
+                :rules="[(val) => validations.required(true, val)]"
                 data-cy="itemFk-create-popup"
                 sort-by="nickname DESC"
             >
diff --git a/src/pages/Entry/Card/EntryCard.vue b/src/pages/Entry/Card/EntryCard.vue
index 50f8b8e55..e9d07889f 100644
--- a/src/pages/Entry/Card/EntryCard.vue
+++ b/src/pages/Entry/Card/EntryCard.vue
@@ -8,6 +8,6 @@ import filter from './EntryFilter.js';
         data-key="Entry"
         url="Entries"
         :descriptor="EntryDescriptor"
-        :filter="filter"
+        :filter="{ ...filter, where: { id: $route.params.id } }"
     />
 </template>
diff --git a/src/pages/Entry/Card/EntryDescriptor.vue b/src/pages/Entry/Card/EntryDescriptor.vue
index 202f94997..2f9cfe0ff 100644
--- a/src/pages/Entry/Card/EntryDescriptor.vue
+++ b/src/pages/Entry/Card/EntryDescriptor.vue
@@ -147,7 +147,7 @@ async function deleteEntry() {
 <template>
     <EntityDescriptor
         :url="`Entries/${entityId}`"
-        :user-filter="entryFilter"
+        :filter="entryFilter"
         title="supplier.nickname"
         data-key="Entry"
         width="lg-width"
diff --git a/src/pages/Entry/Card/EntrySummary.vue b/src/pages/Entry/Card/EntrySummary.vue
index 37a28968c..d5ebcde18 100644
--- a/src/pages/Entry/Card/EntrySummary.vue
+++ b/src/pages/Entry/Card/EntrySummary.vue
@@ -70,8 +70,8 @@ onMounted(async () => {
                     :url="`#/entry/${entityId}/basic-data`"
                     :text="t('globals.summary.basicData')"
                 />
-                <div class="card-group">
-                    <div class="card-content">
+                <div class="vn-card-group">
+                    <div class="vn-card-content">
                         <VnLv
                             :label="t('entry.summary.commission')"
                             :value="entry?.commission"
@@ -93,7 +93,7 @@ onMounted(async () => {
                             :value="entry?.invoiceNumber"
                         />
                     </div>
-                    <div class="card-content">
+                    <div class="vn-card-content">
                         <VnCheckbox
                             :label="t('entry.list.tableVisibleColumns.isOrdered')"
                             v-model="entry.isOrdered"
@@ -130,8 +130,8 @@ onMounted(async () => {
                     :url="`#/travel/${entry.travel.id}/summary`"
                     :text="t('Travel')"
                 />
-                <div class="card-group">
-                    <div class="card-content">
+                <div class="vn-card-group">
+                    <div class="vn-card-content">
                         <VnLv :label="t('entry.summary.travelReference')">
                             <template #value>
                                 <span class="link">
@@ -161,7 +161,7 @@ onMounted(async () => {
                             :value="entry.travel.warehouseIn?.name"
                         />
                     </div>
-                    <div class="card-content">
+                    <div class="vn-card-content">
                         <VnLv :label="t('travel.awbFk')" :value="entry.travel.awbFk" />
                         <VnCheckbox
                             :label="t('entry.summary.travelDelivered')"
@@ -193,31 +193,6 @@ onMounted(async () => {
         </template>
     </CardSummary>
 </template>
-<style lang="scss" scoped>
-.card-group {
-    display: flex;
-    flex-direction: column;
-}
-
-.card-content {
-    display: flex;
-    flex-direction: column;
-    text-overflow: ellipsis;
-    > div {
-        max-height: 24px;
-    }
-}
-
-@media (min-width: 1010px) {
-    .card-group {
-        flex-direction: row;
-    }
-    .card-content {
-        flex: 1;
-        margin-right: 16px;
-    }
-}
-</style>
 <i18n>
 es:
     Travel: EnvĂ­o
diff --git a/src/pages/Entry/EntryList.vue b/src/pages/Entry/EntryList.vue
index 5ebad3144..e42380fa3 100644
--- a/src/pages/Entry/EntryList.vue
+++ b/src/pages/Entry/EntryList.vue
@@ -248,7 +248,6 @@ function getBadgeAttrs(row) {
 
     let timeDiff = today - timeTicket;
 
-    if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
     if (timeDiff < 0) return { color: 'warning', 'text-color': 'black' };
     switch (row.entryTypeCode) {
         case 'regularization':
@@ -274,6 +273,7 @@ function getBadgeAttrs(row) {
         default:
             break;
     }
+    if (timeDiff > 0) return { color: 'info', 'text-color': 'black' };
     return { color: 'transparent' };
 }
 
diff --git a/src/pages/Entry/EntryStockBought.vue b/src/pages/Entry/EntryStockBought.vue
index 6168f0737..9e97e2ad5 100644
--- a/src/pages/Entry/EntryStockBought.vue
+++ b/src/pages/Entry/EntryStockBought.vue
@@ -116,6 +116,7 @@ const filter = computed(() => ({
             hour: 0,
             minute: 0,
             second: 0,
+            milliseconds: 0,
         }),
         m3: { neq: null },
     },
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
index e8df27511..c5d79b045 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDescriptor.vue
@@ -22,7 +22,7 @@ const routes = reactive({
     getSupplier: (id) => {
         return { name: 'SupplierCard', params: { id } };
     },
-    getTickets: (id) => {
+    getInvoices: (id) => {
         return {
             name: 'InvoiceInList',
             query: {
@@ -131,11 +131,11 @@ async function setInvoiceCorrection(id) {
                 </QBtn>
                 <QBtn
                     size="md"
-                    icon="vn:ticket"
+                    icon="vn:invoice-in"
                     color="primary"
-                    :to="routes.getTickets(entity.supplierFk)"
+                    :to="routes.getInvoices(entity.supplierFk)"
                 >
-                    <QTooltip>{{ t('globals.ticketList') }}</QTooltip>
+                    <QTooltip>{{ t('invoiceIn.descriptor.invoices') }}</QTooltip>
                 </QBtn>
                 <QBtn
                     v-if="
diff --git a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
index 20cc1cc71..59bebcae2 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInDueDay.vue
@@ -25,7 +25,8 @@ const invoiceInFormRef = ref();
 const invoiceId = +route.params.id;
 const filter = { where: { invoiceInFk: invoiceId } };
 const areRows = ref(false);
-const totals = ref();
+const totalTaxableBase = ref();
+const noMatch = computed(() => totalAmount.value != totalTaxableBase.value);
 const columns = computed(() => [
     {
         name: 'duedate',
@@ -74,9 +75,12 @@ async function insert() {
     notify(t('globals.dataSaved'), 'positive');
 }
 
-onBeforeMount(async () => {
-    totals.value = (await axios.get(`InvoiceIns/${invoiceId}/getTotals`)).data;
-});
+async function setTaxableBase() {
+    const { data } = await axios.get(`InvoiceIns/${invoiceId}/getTotals`);
+    totalTaxableBase.value = data.totalTaxableBase;
+}
+
+onBeforeMount(async () => await setTaxableBase());
 </script>
 <template>
     <CrudModel
@@ -89,13 +93,14 @@ onBeforeMount(async () => {
         :data-required="{ invoiceInFk: invoiceId }"
         v-model:selected="rowsSelected"
         @on-fetch="(data) => (areRows = !!data.length)"
+        @save-changes="setTaxableBase"
     >
         <template #body="{ rows }">
             <QTable
                 v-model:selected="rowsSelected"
                 selection="multiple"
-                :columns="columns"
-                :rows="rows"
+                :columns
+                :rows
                 row-key="$index"
                 :grid="$q.screen.lt.sm"
             >
@@ -151,7 +156,18 @@ onBeforeMount(async () => {
                         <QTd />
                         <QTd />
                         <QTd>
-                            {{ toCurrency(totalAmount) }}
+                            <QChip
+                                dense
+                                :color="noMatch ? 'negative' : 'transparent'"
+                                class="q-pa-xs"
+                                :title="
+                                    noMatch
+                                        ? t('invoiceIn.noMatch', { totalTaxableBase })
+                                        : ''
+                                "
+                            >
+                                {{ toCurrency(totalAmount) }}
+                            </QChip>
                         </QTd>
                         <QTd>
                             <template v-if="isNotEuro(invoiceIn.currency.code)">
@@ -237,7 +253,7 @@ onBeforeMount(async () => {
                     if (!areRows) insert();
                     else
                         invoiceInFormRef.insert({
-                            amount: (totals.totalTaxableBase - totalAmount).toFixed(2),
+                            amount: (totalTaxableBase - totalAmount).toFixed(2),
                             invoiceInFk: invoiceId,
                         });
                 }
@@ -249,6 +265,10 @@ onBeforeMount(async () => {
 .bg {
     background-color: var(--vn-light-gray);
 }
+
+.q-chip {
+    color: var(--vn-text-color);
+}
 </style>
 <i18n>
     es:
diff --git a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
index dad1da8d6..74936f00a 100644
--- a/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
+++ b/src/pages/InvoiceIn/Card/InvoiceInSummary.vue
@@ -304,7 +304,10 @@ const getLink = (param) => `#/invoice-in/${entityId.value}/${param}`;
                                     :color="amountsNotMatch ? 'negative' : 'transparent'"
                                     :title="
                                         amountsNotMatch
-                                            ? t('invoiceIn.summary.noMatch')
+                                            ? t('invoiceIn.noMatch', {
+                                                  totalTaxableBase:
+                                                      entity.totals.totalTaxableBase,
+                                              })
                                             : t('invoiceIn.summary.dueTotal')
                                     "
                                 >
diff --git a/src/pages/InvoiceIn/InvoiceInList.vue b/src/pages/InvoiceIn/InvoiceInList.vue
index 9b62fdf6a..10ddcbf05 100644
--- a/src/pages/InvoiceIn/InvoiceInList.vue
+++ b/src/pages/InvoiceIn/InvoiceInList.vue
@@ -156,7 +156,7 @@ const cols = computed(() => [
                 :create="{
                     urlCreate: 'InvoiceIns',
                     title: t('globals.createInvoiceIn'),
-                    onDataSaved: ({ id }) => tableRef.redirect(id),
+                    onDataSaved: ({ id }) => tableRef.redirect(`${id}/basic-data`),
                     formInitialData: { companyFk: user.companyFk, issued: Date.vnNew() },
                 }"
                 redirect="invoice-in"
diff --git a/src/pages/InvoiceIn/InvoiceInToBook.vue b/src/pages/InvoiceIn/InvoiceInToBook.vue
index 23175f2e7..28f54f040 100644
--- a/src/pages/InvoiceIn/InvoiceInToBook.vue
+++ b/src/pages/InvoiceIn/InvoiceInToBook.vue
@@ -56,8 +56,9 @@ async function checkToBook(id) {
             componentProps: {
                 title: t('Are you sure you want to book this invoice?'),
                 message: messages.reduce((acc, msg) => `${acc}<p>${msg}</p>`, ''),
+                promise: () => toBook(id),
             },
-        }).onOk(() => toBook(id));
+        });
 }
 
 async function toBook(id) {
diff --git a/src/pages/InvoiceIn/locale/en.yml b/src/pages/InvoiceIn/locale/en.yml
index 7e3603f0f..a7a8d2469 100644
--- a/src/pages/InvoiceIn/locale/en.yml
+++ b/src/pages/InvoiceIn/locale/en.yml
@@ -15,6 +15,7 @@ invoiceIn:
         amount: Amount
     descriptor:
         ticketList: Ticket list
+        invoices: Supplier invoices
     descriptorMenu:
         book: Book
         unbook: Unbook
@@ -58,7 +59,6 @@ invoiceIn:
         bank: Bank
         foreignValue: Foreign value
         dueTotal: Due day
-        noMatch: Do not match
         code: Code
         net: Net
         stems: Stems
@@ -69,3 +69,4 @@ invoiceIn:
         isBooked: Is booked
         account: Ledger account
         correctingFk: Rectificative
+    noMatch: No match with the vat({totalTaxableBase})
diff --git a/src/pages/InvoiceIn/locale/es.yml b/src/pages/InvoiceIn/locale/es.yml
index e6ac9273c..c593f5a08 100644
--- a/src/pages/InvoiceIn/locale/es.yml
+++ b/src/pages/InvoiceIn/locale/es.yml
@@ -14,7 +14,7 @@ invoiceIn:
         awb: AWB
         amount: Importe
     descriptor:
-        ticketList: Listado de tickets
+        invoices: Facturas de proveedor
     descriptorMenu:
         book: Contabilizar
         unbook: Descontabilizar
@@ -67,3 +67,4 @@ invoiceIn:
         isBooked: Contabilizada
         account: Cuenta contable
         correctingFk: Rectificativa
+    noMatch: No cuadra con el iva({totalTaxableBase})
diff --git a/src/pages/Item/Card/ItemDescriptorProxy.vue b/src/pages/Item/Card/ItemDescriptorProxy.vue
index f686e8221..6e1f6d71f 100644
--- a/src/pages/Item/Card/ItemDescriptorProxy.vue
+++ b/src/pages/Item/Card/ItemDescriptorProxy.vue
@@ -22,7 +22,7 @@ const $props = defineProps({
 });
 </script>
 <template>
-    <QPopupProxy style="max-width: 10px">
+    <QPopupProxy style="max-width: 10px" data-cy="ItemDescriptor">
         <ItemDescriptor
             v-if="$props.id"
             :id="$props.id"
diff --git a/src/pages/Item/ItemListFilter.vue b/src/pages/Item/ItemListFilter.vue
index f4500d5fa..ab9b91d06 100644
--- a/src/pages/Item/ItemListFilter.vue
+++ b/src/pages/Item/ItemListFilter.vue
@@ -7,7 +7,7 @@ import FetchData from 'components/FetchData.vue';
 import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
 import VnSelect from 'src/components/common/VnSelect.vue';
 import VnInput from 'src/components/common/VnInput.vue';
-import { QCheckbox } from 'quasar';
+import VnCheckbox from 'src/components/common/VnCheckbox.vue';
 
 import { useArrayData } from 'composables/useArrayData';
 import { useValidator } from 'src/composables/useValidator';
@@ -250,10 +250,9 @@ onMounted(async () => {
                 </QItemSection>
             </QItem>
             <!-- Tags filter -->
-            <QItem class="row items-center">
-                <QItemLabel>
-                    {{ t('params.tags') }}
-                </QItemLabel>
+            <QItemLabel header>
+                {{ t('params.tags') }}
+
                 <QIcon
                     name="add_circle"
                     class="fill-icon-on-hover q-ml-md"
@@ -261,7 +260,7 @@ onMounted(async () => {
                     color="primary"
                     @click="tagValues.push({})"
                 />
-            </QItem>
+            </QItemLabel>
             <QItem
                 v-for="(tag, index) in tagValues"
                 :key="index"
@@ -269,6 +268,7 @@ onMounted(async () => {
             >
                 <QItemSection class="col">
                     <VnSelect
+                        class="full-width"
                         :label="t('params.tag')"
                         v-model="tag.selectedTag"
                         :options="tagOptions"
@@ -316,25 +316,19 @@ onMounted(async () => {
                 />
             </QItem>
             <!-- Filter fields -->
-            <QItem class="row items-center">
-                <QItemLabel>
-                    {{ t('More fields') }}
-                </QItemLabel>
+            <QItemLabel header
+                >{{ t('More fields') }}
                 <QIcon
                     name="add_circle"
                     class="fill-icon-on-hover q-ml-md"
                     size="sm"
                     color="primary"
                     @click="fieldFiltersValues.push({})"
-                />
-            </QItem>
-            <QItem
-                v-for="(fieldFilter, index) in fieldFiltersValues"
-                :key="index"
-                class="row items-center"
-            >
+            /></QItemLabel>
+            <QItem v-for="(fieldFilter, index) in fieldFiltersValues" :key="index">
                 <QItemSection class="col">
                     <VnSelect
+                        class="full-width"
                         :label="t('params.tag')"
                         :model-value="fieldFilter.selectedField"
                         :options="moreFields"
@@ -355,7 +349,7 @@ onMounted(async () => {
                     />
                 </QItemSection>
                 <QItemSection class="col">
-                    <QCheckbox
+                    <VnCheckbox
                         v-if="fieldFilter.selectedField?.type === 'boolean'"
                         v-model="fieldFilter.value"
                         :label="t('params.value')"
@@ -370,13 +364,14 @@ onMounted(async () => {
                         @keydown.enter="applyFieldFilters(params, searchFn)"
                     />
                 </QItemSection>
-                <QIcon
-                    name="delete"
-                    class="fill-icon-on-hover q-ml-xs"
-                    size="sm"
-                    color="primary"
-                    @click="removeFieldFilter(index, params, searchFn)"
-                />
+                <QItemSection side
+                    ><QIcon
+                        name="delete"
+                        class="fill-icon-on-hover q-ml-xs"
+                        size="sm"
+                        color="primary"
+                        @click="removeFieldFilter(index, params, searchFn)"
+                /></QItemSection>
             </QItem>
             <QItem>
                 <QItemSection>
diff --git a/src/pages/Login/__tests__/Login.spec.js b/src/pages/Login/__tests__/Login.spec.js
index e90a8ee53..b25246f52 100644
--- a/src/pages/Login/__tests__/Login.spec.js
+++ b/src/pages/Login/__tests__/Login.spec.js
@@ -1,6 +1,7 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import { createWrapper } from 'app/test/vitest/helper';
 import Login from 'pages/Login/LoginMain.vue';
+import axios from 'axios';
 
 describe('Login', () => {
     let vm;
diff --git a/src/pages/Monitor/MonitorClients.vue b/src/pages/Monitor/MonitorClients.vue
index 278b0b26f..2ba5f4c0b 100644
--- a/src/pages/Monitor/MonitorClients.vue
+++ b/src/pages/Monitor/MonitorClients.vue
@@ -1,19 +1,22 @@
 <script setup>
 import { ref, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
-import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
+import DepartmentDescriptorProxy from '../Worker/Department/Card/DepartmentDescriptorProxy.vue';
 import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorProxy.vue';
 import { toDateFormat } from 'src/filters/date.js';
 import VnTable from 'src/components/VnTable/VnTable.vue';
 import VnInputDate from 'src/components/common/VnInputDate.vue';
 import VnRow from 'src/components/ui/VnRow.vue';
 import { dateRange } from 'src/filters';
+import useOpenURL from 'src/composables/useOpenURL';
+import { useState } from 'src/composables/useState';
 const { t } = useI18n();
 
 const dates = dateRange(Date.vnNew());
 const from = ref(dates[0]);
 const to = ref(dates[1]);
 
+const state = useState();
 const filter = computed(() => {
     const obj = {};
     const formatFrom = setHours(from.value, 'from');
@@ -23,16 +26,18 @@ const filter = computed(() => {
     if (!formatFrom && formatTo) stamp = { lte: formatTo };
     else if (formatFrom && !formatTo) stamp = { gte: formatFrom };
     else if (formatFrom && formatTo) stamp = { between: [formatFrom, formatTo] };
-
-    return Object.assign(obj, { where: { 'v.stamp': stamp } });
+    return Object.assign(obj, {
+        where: {
+            'v.stamp': stamp,
+            'c.departmentFk': state.getUser().value.departmentFk,
+        },
+    });
 });
 
 function exprBuilder(param, value) {
     switch (param) {
         case 'clientFk':
             return { [`c.id`]: value };
-        case 'departmentFk':
-            return { [`c.${param}`]: value };
     }
 }
 
@@ -65,9 +70,13 @@ const columns = computed(() => [
         align: 'left',
         name: 'departmentFk',
         label: t('customer.summary.team'),
-        component: 'select',
-        attrs: {
-            url: 'Departments',
+        columnFilter: {
+            component: 'select',
+            attrs: {
+                url: 'Departments',
+            },
+            alias: 'c',
+            inWhere: true,
         },
         columnField: {
             component: null,
@@ -94,6 +103,7 @@ const columns = computed(() => [
         columnClass: 'no-padding',
     },
 ]);
+const openTab = (id) => useOpenURL(`#/customer/${id}/summary`);
 </script>
 
 <template>
@@ -113,6 +123,8 @@ const columns = computed(() => [
         :disable-option="{ card: true }"
         dense
         class="q-px-none"
+        :row-click="({ id }) => openTab(id)"
+        :row-ctrl-click="(_, { id }) => openTab(id)"
     >
         <template #top-left>
             <VnRow>
@@ -121,12 +133,16 @@ const columns = computed(() => [
             </VnRow>
         </template>
         <template #column-departmentFk="{ row }">
-            <span class="link" :title="row.department" v-text="row.department" />
-            <WorkerDescriptorProxy :id="row.departmentFk" dense />
+            <span @click.stop.prevent class="link" :title="row.department">
+                {{ row.department }}
+                <DepartmentDescriptorProxy :id="row.departmentFk" dense
+            /></span>
         </template>
         <template #column-clientFk="{ row }">
-            <span class="link" :title="row.clientName" v-text="row.clientName" />
-            <CustomerDescriptorProxy :id="row.clientFk" />
+            <span @click.stop.prevent class="link" :title="row.clientName">
+                {{ row.clientName }}
+                <CustomerDescriptorProxy :id="row.clientFk" dense
+            /></span>
         </template>
     </VnTable>
 </template>
diff --git a/src/pages/Monitor/MonitorOrders.vue b/src/pages/Monitor/MonitorOrders.vue
index 2679f7224..bdfcf3837 100644
--- a/src/pages/Monitor/MonitorOrders.vue
+++ b/src/pages/Monitor/MonitorOrders.vue
@@ -9,6 +9,7 @@ import { toDateFormat, toDateTimeFormat } from 'src/filters/date.js';
 import { toCurrency } from 'src/filters';
 import { useVnConfirm } from 'composables/useVnConfirm';
 import axios from 'axios';
+import useOpenURL from 'src/composables/useOpenURL';
 
 const { t } = useI18n();
 const { openConfirmationModal } = useVnConfirm();
@@ -108,8 +109,7 @@ const removeOrders = async () => {
     await table.value.reload();
 };
 
-const openTab = (id) =>
-    window.open(`#/order/${id}/summary`, '_blank', 'noopener, noreferrer');
+const openTab = (id) => useOpenURL(`#/order/${id}/summary`);
 </script>
 <template>
     <VnTable
@@ -129,6 +129,7 @@ const openTab = (id) =>
         }"
         default-mode="table"
         :row-click="({ id }) => openTab(id)"
+        :row-ctrl-click="(_, { id }) => openTab(id)"
         v-model:selected="selectedRows"
         :disable-option="{ card: true }"
     >
@@ -177,16 +178,16 @@ const openTab = (id) =>
         </template>
 
         <template #column-clientFk="{ row }">
-            <QTd @click.stop>
-                <span class="link" v-text="row.clientName" :title="row.clientName" />
-                <CustomerDescriptorProxy :id="row.clientFk" />
-            </QTd>
+            <span class="link" @click.stop :title="row.clientName">
+                {{ row.clientName }}
+                <CustomerDescriptorProxy :id="row.clientFk" dense
+            /></span>
         </template>
         <template #column-departmentFk="{ row }">
-            <QTd @click.stop>
-                <span class="link" v-text="row.departmentName" />
-                <DepartmentDescriptorProxy :id="row.departmentFk" dense />
-            </QTd>
+            <span class="link" @click.stop :title="row.departmentName">
+                {{ row.departmentName }}
+                <DepartmentDescriptorProxy :id="row.departmentFk" dense
+            /></span>
         </template>
     </VnTable>
 </template>
diff --git a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
index 535906e17..1cadd4cb4 100644
--- a/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
+++ b/src/pages/Monitor/Ticket/MonitorTicketFilter.vue
@@ -194,19 +194,6 @@ const getLocale = (label) => {
                     />
                 </QItemSection>
             </QItem>
-            <QItem>
-                <QItemSection>
-                    <VnSelect
-                        dense
-                        filled
-                        :label="t('globals.params.departmentFk')"
-                        v-model="params.department"
-                        option-label="name"
-                        option-value="name"
-                        url="Departments"
-                    />
-                </QItemSection>
-            </QItem>
             <QItem>
                 <QItemSection>
                     <VnSelect
diff --git a/src/pages/Monitor/Ticket/MonitorTickets.vue b/src/pages/Monitor/Ticket/MonitorTickets.vue
index 03d751595..b46eb5bfa 100644
--- a/src/pages/Monitor/Ticket/MonitorTickets.vue
+++ b/src/pages/Monitor/Ticket/MonitorTickets.vue
@@ -449,21 +449,19 @@ const openTab = (id) => useOpenURL(`#/ticket/${id}/sale`);
             <span :title="row.province" v-text="row.province" />
         </template>
         <template #column-state="{ row }">
-            <div @click.stop.prevent>
-                <div v-if="row.refFk">
-                    <span class="link">{{ row.refFk }}</span>
-                    <InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
-                </div>
-                <QBadge
-                    v-else
-                    :color="stateColors[row.classColor] || 'transparent'"
-                    :text-color="stateColors[row.classColor] ? 'black' : 'white'"
-                    class="q-pa-sm"
-                    style="font-size: 14px"
-                >
-                    {{ row.state }}
-                </QBadge>
+            <div v-if="row.refFk" @click.stop.prevent>
+                <span class="link">{{ row.refFk }}</span>
+                <InvoiceOutDescriptorProxy :id="row.invoiceOutId" />
             </div>
+            <QBadge
+                v-else
+                :color="stateColors[row.classColor] || 'transparent'"
+                :text-color="stateColors[row.classColor] ? 'black' : 'white'"
+                class="q-pa-sm"
+                style="font-size: 14px"
+            >
+                {{ row.state }}
+            </QBadge>
         </template>
         <template #column-isFragile="{ row }">
             <QIcon v-if="row.isFragile" name="local_bar" color="primary" size="sm">
diff --git a/src/pages/Order/Card/OrderFilter.vue b/src/pages/Order/Card/OrderFilter.vue
index 609a1215a..5f91153ac 100644
--- a/src/pages/Order/Card/OrderFilter.vue
+++ b/src/pages/Order/Card/OrderFilter.vue
@@ -130,8 +130,10 @@ en:
     myTeam: My Team
     isConfirmed: Order Confirmed
     showEmpty: Show Empty
+    departmentFk: Department
 es:
     params:
+        departmentFk: Departamento
         search: BĂşsqueda
         clientFk: Cliente
         agencyModeFk: Agencia
diff --git a/src/pages/Route/Agency/Card/AgencyCard.vue b/src/pages/Route/Agency/Card/AgencyCard.vue
index c21298470..9fd3fe5e5 100644
--- a/src/pages/Route/Agency/Card/AgencyCard.vue
+++ b/src/pages/Route/Agency/Card/AgencyCard.vue
@@ -3,5 +3,5 @@ import AgencyDescriptor from 'pages/Route/Agency/Card/AgencyDescriptor.vue';
 import VnCard from 'src/components/common/VnCard.vue';
 </script>
 <template>
-    <VnCard data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" />
+    <VnCard data-key="Agency" url="Agencies" :descriptor="AgencyDescriptor" :filter="{ where: { id: $route.params.id } }" />
 </template>
diff --git a/src/pages/Route/Roadmap/RoadmapSummary.vue b/src/pages/Route/Roadmap/RoadmapSummary.vue
index 0c1c2b903..dcd02d98e 100644
--- a/src/pages/Route/Roadmap/RoadmapSummary.vue
+++ b/src/pages/Route/Roadmap/RoadmapSummary.vue
@@ -112,12 +112,9 @@ const filter = {
                         :label="t('Trailer Plate')"
                         :value="dashIfEmpty(entity?.trailerPlate)"
                     />
-                    <VnLv :label="t('Phone')" :value="dashIfEmpty(entity?.phone)">
+                    <VnLv :label="t('Phone')">
                         <template #value>
-                            <span>
-                                {{ dashIfEmpty(entity?.phone) }}
-                                <VnLinkPhone :phone-number="entity?.phone" />
-                            </span>
+                            <VnLinkPhone :phone-number="entity?.phone" />
                         </template>
                     </VnLv>
                     <VnLv
diff --git a/src/pages/Route/RouteExtendedList.vue b/src/pages/Route/RouteExtendedList.vue
index b905cfde8..c69492836 100644
--- a/src/pages/Route/RouteExtendedList.vue
+++ b/src/pages/Route/RouteExtendedList.vue
@@ -46,7 +46,6 @@ const columns = computed(() => [
         },
         isId: true,
         columnFilter: false,
-        width: '25px',
     },
     {
         name: 'workerFk',
@@ -142,7 +141,6 @@ const columns = computed(() => [
         label: 'm3',
         cardVisible: true,
         columnClass: 'shrink',
-        width: '50px',
     },
     {
         name: 'started',
@@ -150,7 +148,6 @@ const columns = computed(() => [
         component: 'time',
         columnFilter: false,
         format: ({ started }) => toHour(started),
-        width: '50px',
     },
     {
         name: 'finished',
@@ -158,7 +155,6 @@ const columns = computed(() => [
         component: 'time',
         columnFilter: false,
         format: ({ finished }) => toHour(finished),
-        width: '50px',
     },
     {
         align: 'right',
diff --git a/src/pages/Route/RouteList.vue b/src/pages/Route/RouteList.vue
index f3b9c438c..810157683 100644
--- a/src/pages/Route/RouteList.vue
+++ b/src/pages/Route/RouteList.vue
@@ -46,7 +46,6 @@ const columns = computed(() => [
             condition: () => true,
         },
         columnFilter: false,
-        width: '25px',
     },
     {
         align: 'left',
@@ -57,7 +56,6 @@ const columns = computed(() => [
         cardVisible: true,
         format: (row, dashIfEmpty) => dashIfEmpty(row.travelRef),
         columnFilter: false,
-        width: '100px',
     },
     {
         label: t('globals.agency'),
@@ -100,7 +98,6 @@ const columns = computed(() => [
         cardVisible: true,
         columnFilter: false,
         format: ({ started }) => toHour(started),
-        width: '50px',
     },
     {
         align: 'center',
@@ -109,7 +106,6 @@ const columns = computed(() => [
         cardVisible: true,
         columnFilter: false,
         format: ({ finished }) => toHour(finished),
-        width: '50px',
     },
     {
         align: 'left',
diff --git a/src/pages/Route/RouteRoadmap.vue b/src/pages/Route/RouteRoadmap.vue
index c981b86a5..bdb3d12c4 100644
--- a/src/pages/Route/RouteRoadmap.vue
+++ b/src/pages/Route/RouteRoadmap.vue
@@ -213,7 +213,7 @@ function exprBuilder(param, value) {
         }"
     >
         <template #advanced-menu>
-            <RoadmapFilter :dataKey />
+            <RoadmapFilter :data-key />
         </template>
         <template #body>
             <VnTable
diff --git a/src/pages/Route/Vehicle/Card/VehicleNotes.vue b/src/pages/Route/Vehicle/Card/VehicleNotes.vue
new file mode 100644
index 000000000..0afc3c3ed
--- /dev/null
+++ b/src/pages/Route/Vehicle/Card/VehicleNotes.vue
@@ -0,0 +1,35 @@
+<script setup>
+import { computed } from 'vue';
+import { useRoute } from 'vue-router';
+import { useState } from 'src/composables/useState';
+import VnNotes from 'src/components/ui/VnNotes.vue';
+
+const route = useRoute();
+const state = useState();
+const user = state.getUser();
+const vehicleId = computed(() => route.params.id);
+
+const noteFilter = computed(() => {
+    return {
+        order: 'created DESC',
+        where: { vehicleFk: vehicleId.value },
+    };
+});
+
+const body = {
+    vehicleFk: vehicleId.value,
+    workerFk: user.value.id,
+};
+</script>
+
+<template>
+    <VnNotes
+        url="vehicleObservations"
+        :add-note="true"
+        :filter="noteFilter"
+        :body="body"
+        style="overflow-y: auto"
+        required
+        deletable
+    />
+</template>
diff --git a/src/pages/Route/locale/en.yml b/src/pages/Route/locale/en.yml
index 283b61855..e7e2d691e 100644
--- a/src/pages/Route/locale/en.yml
+++ b/src/pages/Route/locale/en.yml
@@ -50,7 +50,7 @@ route:
         agencyAgreement: Agency agreement
         agencyModeName: Agency route
         isOwn: Own
-        isAnyVolumeallowed: Any volume allowed
+        isAnyVolumeAllowed: Any volume allowed
     Worker: Worker
     Agency: Agency
     Vehicle: Vehicle
diff --git a/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue b/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue
new file mode 100644
index 000000000..e78a2b238
--- /dev/null
+++ b/src/pages/Shelving/Parking/Card/ParkingDescriptorProxy.vue
@@ -0,0 +1,14 @@
+<script setup>
+import ParkingDescriptor from './ParkingDescriptor.vue';
+import ParkingSummary from './ParkingSummary.vue';
+</script>
+<template>
+    <QPopupProxy style="max-width: 10px">
+        <ParkingDescriptor
+            v-if="$attrs.id"
+            v-bind="$attrs.id"
+            :summary="ParkingSummary"
+            :proxy-render="true"
+        />
+    </QPopupProxy>
+</template>
diff --git a/src/pages/Supplier/Card/SupplierDescriptor.vue b/src/pages/Supplier/Card/SupplierDescriptor.vue
index 2863784ab..2511edf11 100644
--- a/src/pages/Supplier/Card/SupplierDescriptor.vue
+++ b/src/pages/Supplier/Card/SupplierDescriptor.vue
@@ -106,7 +106,7 @@ const getEntryQueryParams = (supplier) => {
                 <QBtn
                     :to="{
                         name: 'EntryList',
-                        query: { params: JSON.stringify(getEntryQueryParams(entity)) },
+                        query: { table: JSON.stringify(getEntryQueryParams(entity)) },
                     }"
                     size="md"
                     icon="vn:entry"
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
index 055c9a0ff..83c621b20 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicData.vue
@@ -91,7 +91,7 @@ const totalPrice = computed(() => {
 const totalNewPrice = computed(() => {
     return rows.value.reduce(
         (acc, item) => acc + item.component.newPrice * item.quantity,
-        0
+        0,
     );
 });
 
@@ -210,18 +210,18 @@ onMounted(async () => {
         flat
     >
         <template #body-cell-item="{ row }">
-            <QTd @click.stop class="link">
-                <QBtn flat>
+            <QTd align="center">
+                <span @click.stop class="link">
                     {{ row.itemFk }}
                     <ItemDescriptorProxy :id="row.itemFk" />
-                </QBtn>
+                </span>
             </QTd>
         </template>
         <template #body-cell-description="{ row }">
             <QTd style="min-width: 120px; max-width: 120px">
                 <div class="column q-pb-xs" style="min-width: 120px">
                     <span>{{ row.item.name }}</span>
-                    <FetchedTags :item="row.item" class="full-width" />
+                    <FetchedTags :item="row.item" class="full-width" :columns="6" />
                 </div>
             </QTd>
         </template>
diff --git a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
index 9d70fea38..61932468c 100644
--- a/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
+++ b/src/pages/Ticket/Card/BasicData/TicketBasicDataForm.vue
@@ -25,9 +25,7 @@ const { validate } = useValidator();
 const { notify } = useNotify();
 const router = useRouter();
 const { t } = useI18n();
-const canEditZone = useAcl().hasAny([
-    { model: 'Ticket', props: 'editZone', accessType: 'WRITE' },
-]);
+const canEditZone = useAcl().hasAcl('Ticket', 'editZone', 'WRITE');
 
 const agencyFetchRef = ref();
 const warehousesOptions = ref([]);
diff --git a/src/pages/Ticket/Card/TicketCreateTracking.vue b/src/pages/Ticket/Card/TicketCreateTracking.vue
deleted file mode 100644
index 5c1e916f2..000000000
--- a/src/pages/Ticket/Card/TicketCreateTracking.vue
+++ /dev/null
@@ -1,59 +0,0 @@
-<script setup>
-import { ref } from 'vue';
-import { useRoute } from 'vue-router';
-import { useI18n } from 'vue-i18n';
-
-import FormModelPopup from 'components/FormModelPopup.vue';
-import VnRow from 'components/ui/VnRow.vue';
-import VnSelect from 'src/components/common/VnSelect.vue';
-import FetchData from 'components/FetchData.vue';
-
-import { useState } from 'src/composables/useState';
-import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
-
-const emit = defineEmits(['onRequestCreated']);
-
-const route = useRoute();
-const { t } = useI18n();
-const state = useState();
-const user = state.getUser();
-const stateFetchDataRef = ref(null);
-const statesOptions = ref([]);
-
-const onStateFkChange = (formData) => (formData.userFk = user.value.id);
-</script>
-<template>
-    <FetchData
-        ref="stateFetchDataRef"
-        url="States"
-        auto-load
-        @on-fetch="(data) => (statesOptions = data)"
-    />
-    <FormModelPopup
-        :title="t('Create tracking')"
-        url-create="Tickets/state"
-        model="CreateTicketTracking"
-        :form-initial-data="{ ticketFk: route.params.id }"
-        @on-data-saved="() => emit('onRequestCreated')"
-    >
-        <template #form-inputs="{ data }">
-            <VnRow>
-                <VnSelect
-                    v-model="data.stateFk"
-                    :label="t('ticketList.state')"
-                    :options="statesOptions"
-                    @update:model-value="onStateFkChange(data)"
-                    hide-selected
-                    option-label="name"
-                    option-value="id"
-                />
-                <VnSelectWorker v-model="data.userFk" :fields="['id', 'name']" />
-            </VnRow>
-        </template>
-    </FormModelPopup>
-</template>
-
-<i18n>
-    es:
-        Create tracking: Crear estado
-</i18n>
diff --git a/src/pages/Ticket/Card/TicketSale.vue b/src/pages/Ticket/Card/TicketSale.vue
index 2fb305cc3..e721e2d1c 100644
--- a/src/pages/Ticket/Card/TicketSale.vue
+++ b/src/pages/Ticket/Card/TicketSale.vue
@@ -1,5 +1,5 @@
 <script setup>
-import { onMounted, ref, computed, watch } from 'vue';
+import { onMounted, ref, computed, watch, inject } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRouter, useRoute } from 'vue-router';
 import { useQuasar } from 'quasar';
@@ -25,7 +25,7 @@ import VnTable from 'src/components/VnTable/VnTable.vue';
 import VnConfirm from 'src/components/ui/VnConfirm.vue';
 import TicketProblems from 'src/components/TicketProblems.vue';
 import RightMenu from 'src/components/common/RightMenu.vue';
-
+const app = inject('app');
 const route = useRoute();
 const router = useRouter();
 const { t } = useI18n();
@@ -99,6 +99,7 @@ const columns = computed(() => [
         align: 'left',
         label: t('globals.quantity'),
         name: 'quantity',
+        class: 'shrink',
         format: (row) => toCurrency(row.quantity),
     },
     {
@@ -187,20 +188,26 @@ const getRowUpdateInputEvents = (sale) => {
 
 const resetChanges = async () => {
     arrayData.fetch({ append: false });
-    tableRef.value.reload();
+    tableRef.value.CrudModelRef.hasChanges = false;
+    await tableRef.value.reload();
+
     selectedRows.value = [];
 };
 const changeQuantity = async (sale) => {
     if (!sale.itemFk || sale.quantity == null || sale?.originalQuantity === sale.quantity)
         return;
     else sale.originalQuantity = sale.quantity;
-    if (!sale.id) return addSale(sale);
+    try {
+        if (!sale.id) await addSale(sale);
+    } catch (e) {
+        app.config.errorHandler(e);
+        return;
+    }
 
     if (await isSalePrepared(sale)) {
         await confirmUpdate(() => updateQuantity(sale));
     } else await updateQuantity(sale);
 };
-
 const updateQuantity = async (sale) => {
     try {
         let { quantity, id } = sale;
@@ -213,7 +220,7 @@ const updateQuantity = async (sale) => {
             (s) => s.id === sale.id,
         );
         sale.quantity = quantity;
-        throw e;
+        app.config.errorHandler(e);
     }
 };
 
@@ -222,24 +229,27 @@ const addSale = async (sale) => {
         barcode: sale.itemFk,
         quantity: sale.quantity,
     };
+    try {
+        const { data } = await axios.post(`tickets/${route.params.id}/addSale`, params);
 
-    const { data } = await axios.post(`tickets/${route.params.id}/addSale`, params);
+        if (!data) return;
 
-    if (!data) return;
+        const newSale = data;
+        sale.id = newSale.id;
+        sale.image = newSale.item.image;
+        sale.subName = newSale.item.subName;
+        sale.concept = newSale.concept;
+        sale.quantity = newSale.quantity;
+        sale.discount = newSale.discount;
+        sale.price = newSale.price;
+        sale.item = newSale.item;
 
-    const newSale = data;
-    sale.id = newSale.id;
-    sale.image = newSale.item.image;
-    sale.subName = newSale.item.subName;
-    sale.concept = newSale.concept;
-    sale.quantity = newSale.quantity;
-    sale.discount = newSale.discount;
-    sale.price = newSale.price;
-    sale.item = newSale.item;
-
-    notify('globals.dataSaved', 'positive');
-    sale.isNew = false;
-    resetChanges();
+        notify('globals.dataSaved', 'positive');
+        sale.isNew = false;
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 const changeConcept = async (sale) => {
     if (await isSalePrepared(sale)) {
@@ -248,10 +258,14 @@ const changeConcept = async (sale) => {
 };
 
 const updateConcept = async (sale) => {
-    const data = { newConcept: sale.concept };
-    await axios.post(`Sales/${sale.id}/updateConcept`, data);
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        const data = { newConcept: sale.concept };
+        await axios.post(`Sales/${sale.id}/updateConcept`, data);
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const DEFAULT_EDIT = {
@@ -262,18 +276,6 @@ const DEFAULT_EDIT = {
     oldQuantity: null,
 };
 const edit = ref({ ...DEFAULT_EDIT });
-const usesMana = ref(null);
-
-const getUsesMana = async () => {
-    const { data } = await axios.get('Sales/usesMana');
-    usesMana.value = data;
-};
-
-const getMana = async () => {
-    const { data } = await axios.get(`Tickets/${route.params.id}/getDepartmentMana`);
-    mana.value = data;
-    await getUsesMana();
-};
 
 const selectedValidSales = computed(() => {
     if (!sales.value) return;
@@ -310,11 +312,15 @@ const changePrice = async (sale) => {
     }
 };
 const updatePrice = async (sale, newPrice) => {
-    await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
-    sale.price = newPrice;
-    edit.value = { ...DEFAULT_EDIT };
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
+        sale.price = newPrice;
+        edit.value = { ...DEFAULT_EDIT };
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const changeDiscount = async (sale) => {
@@ -337,15 +343,20 @@ const updateDiscounts = async (sales, newDiscount) => {
 };
 
 const updateDiscount = async (sales, newDiscount = 0) => {
-    const salesIds = sales.map(({ id }) => id);
-    const params = {
-        salesIds,
-        newDiscount,
-        manaCode: manaCode.value,
-    };
-    await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        const salesIds = sales.map(({ id }) => id);
+        const params = {
+            salesIds,
+            newDiscount,
+            manaCode: manaCode.value,
+        };
+        await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+        return;
+    }
 };
 
 const getNewPrice = computed(() => {
@@ -367,30 +378,40 @@ const getNewPrice = computed(() => {
 });
 
 const newOrderFromTicket = async () => {
-    const { data } = await axios.post(`Orders/newFromTicket`, {
-        ticketFk: Number(route.params.id),
-    });
-    const routeData = router.resolve({ name: 'OrderCatalog', params: { id: data } });
-    window.open(routeData.href, '_blank');
+    try {
+        const { data } = await axios.post(`Orders/newFromTicket`, {
+            ticketFk: Number(route.params.id),
+        });
+        const routeData = router.resolve({ name: 'OrderCatalog', params: { id: data } });
+        window.open(routeData.href, '_blank');
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const goToLog = (saleId) => {
     router.push({
         name: 'TicketLog',
-        params: {
-            originId: route.params.id,
-            changedModel: 'Sale',
-            changedModelId: saleId,
+        query: {
+            logs: JSON.stringify({
+                originFk: route.params.id,
+                changedModel: 'Sale',
+                changedModelId: saleId,
+            }),
         },
     });
 };
 
 const changeTicketState = async (val) => {
-    stateBtnDropdownRef.value.hide();
-    const params = { ticketFk: route.params.id, code: val };
-    await axios.post('Tickets/state', params);
-    notify('globals.dataSaved', 'positive');
-    await resetChanges();
+    try {
+        stateBtnDropdownRef.value.hide();
+        const params = { ticketFk: route.params.id, code: val };
+        await axios.post('Tickets/state', params);
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const removeSelectedSales = () => {
@@ -410,10 +431,14 @@ const removeSales = async () => {
         .forEach((sale) => tableRef.value.CrudModelRef.formData.splice(sale.$index, 1));
 
     if (params.sales.length == 0) return;
-    await axios.post('Sales/deleteSales', params);
-    removeSelectedSales();
-    notify('globals.dataSaved', 'positive');
-    resetChanges();
+    try {
+        await axios.post('Sales/deleteSales', params);
+        removeSelectedSales();
+        notify('globals.dataSaved', 'positive');
+        resetChanges();
+    } catch (e) {
+        app.config.errorHandler(e);
+    }
 };
 
 const setTransferParams = async () => {
@@ -767,7 +792,7 @@ watch(
                     {{ row?.item?.subName.toUpperCase() }}
                 </div>
             </div>
-            <FetchedTags v-if="row.item" :item="row.item" :max-length="6" />
+            <FetchedTags v-if="row.item" :item="row.item" :columns="6" :max-length="6" />
             <QPopupProxy v-if="row.id && isTicketEditable">
                 <VnInput
                     v-model="row.concept"
diff --git a/src/pages/Ticket/Card/TicketSaleMoreActions.vue b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
index 773b0807f..37441b44f 100644
--- a/src/pages/Ticket/Card/TicketSaleMoreActions.vue
+++ b/src/pages/Ticket/Card/TicketSaleMoreActions.vue
@@ -55,13 +55,12 @@ const isClaimable = computed(() => {
     if (ticket.value) {
         const landedPlusWeek = new Date(ticket.value.landed);
         landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
-        const createAfterDeadline = acl.hasAny([
-            { model: 'Claim', props: 'createAfterDeadline', accessType: 'WRITE' },
-        ]);
+        const createAfterDeadline = acl.hasAcl('Claim', 'createAfterDeadline', 'WRITE');
         return landedPlusWeek >= Date.vnNew() || createAfterDeadline;
     }
     return false;
 });
+
 const sendSms = async (params) => {
     await axios.post(`Tickets/${ticket.value.id}/sendSms`, params);
     notify(t('SMS sent'), 'positive');
@@ -230,18 +229,6 @@ const createRefund = async (withWarehouse) => {
                     <QItemLabel>{{ t('Add claim') }}</QItemLabel>
                 </QItemSection>
             </QItem>
-            <QItem
-                v-if="isTicketEditable"
-                clickable
-                v-close-popup
-                v-ripple
-                @click="setReserved(true)"
-                data-cy="markAsReservedItem"
-            >
-                <QItemSection>
-                    <QItemLabel>{{ t('Mark as reserved') }}</QItemLabel>
-                </QItemSection>
-            </QItem>
             <QItem clickable v-ripple data-cy="ticketSaleRefundItem">
                 <QItemSection>
                     <QItemLabel>{{ t('Refund') }}</QItemLabel>
@@ -287,8 +274,6 @@ es:
     Recalculate price: Recalcular precio
     Update discount: Actualizar descuento
     Add claim: Crear reclamaciĂłn
-    Mark as reserved: Marcar como reservado
-    Unmark as reserved: Desmarcar como reservado
     Refund: Abono
     with warehouse: con almacén
     without warehouse: sin almacén
diff --git a/src/pages/Ticket/Card/TicketSummary.vue b/src/pages/Ticket/Card/TicketSummary.vue
index 3412b0106..119b867ed 100644
--- a/src/pages/Ticket/Card/TicketSummary.vue
+++ b/src/pages/Ticket/Card/TicketSummary.vue
@@ -21,6 +21,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import VnToSummary from 'src/components/ui/VnToSummary.vue';
 import TicketDescriptorMenu from './TicketDescriptorMenu.vue';
 import TicketProblems from 'src/components/TicketProblems.vue';
+import VnDropdown from 'src/components/common/VnDropdown.vue';
 
 const route = useRoute();
 const { notify } = useNotify();
@@ -40,7 +41,7 @@ const ticket = computed(() => summary.value?.entity);
 const editableStates = ref([]);
 const ticketUrl = ref();
 const grafanaUrl = 'https://grafana.verdnatura.es';
-const stateBtnDropdownRef = ref();
+
 const descriptorData = useArrayData('Ticket');
 
 onMounted(async () => {
@@ -67,7 +68,6 @@ function isEditable() {
 }
 
 async function changeState(value) {
-    stateBtnDropdownRef.value?.hide();
     const formData = {
         ticketFk: entityId.value,
         code: value,
@@ -113,25 +113,12 @@ onMounted(async () => {
             </div>
         </template>
         <template #header-right>
-            <div>
-                <QBtnDropdown
-                    ref="stateBtnDropdownRef"
-                    color="black"
-                    text-color="white"
-                    :label="t('globals.changeState')"
-                    :disable="!isEditable()"
-                >
-                    <VnSelect
-                        :options="editableStates"
-                        hide-selected
-                        option-label="name"
-                        option-value="code"
-                        hide-dropdown-icon
-                        focus-on-mount
-                        @update:model-value="changeState"
-                    />
-                </QBtnDropdown>
-            </div>
+            <VnDropdown
+                :disable="!isEditable()"
+                :options="editableStates"
+                option-value="code"
+                @change-state="changeState"
+            />
         </template>
         <template #menu="{ entity }">
             <TicketDescriptorMenu :ticket="entity" />
@@ -229,27 +216,23 @@ onMounted(async () => {
                             :value="toDate(entity.landed)"
                         />
                         <VnLv :label="t('globals.packages')" :value="entity.packages" />
-                        <VnLv :value="entity.address.phone">
-                            <template #label>
-                                {{ t('ticket.summary.consigneePhone') }}
+                        <VnLv :label="t('ticket.summary.consigneePhone')">
+                            <template #value>
                                 <VnLinkPhone :phone-number="entity.address.phone" />
                             </template>
                         </VnLv>
-                        <VnLv :value="entity.address.mobile">
-                            <template #label>
-                                {{ t('ticket.summary.consigneeMobile') }}
+                        <VnLv :label="t('ticket.summary.consigneeMobile')">
+                            <template #value>
                                 <VnLinkPhone :phone-number="entity.address.mobile" />
                             </template>
                         </VnLv>
-                        <VnLv :value="entity.client.phone">
-                            <template #label>
-                                {{ t('ticket.summary.clientPhone') }}
+                        <VnLv :label="t('ticket.summary.clientPhone')">
+                            <template #value>
                                 <VnLinkPhone :phone-number="entity.client.phone" />
                             </template>
                         </VnLv>
-                        <VnLv :value="entity.client.mobile">
-                            <template #label>
-                                {{ t('ticket.summary.clientMobile') }}
+                        <VnLv :label="t('ticket.summary.clientMobile')">
+                            <template #value>
                                 <VnLinkPhone :phone-number="entity.client.mobile" />
                             </template>
                         </VnLv>
diff --git a/src/pages/Ticket/Card/TicketTracking.vue b/src/pages/Ticket/Card/TicketTracking.vue
index 00610de44..06171366d 100644
--- a/src/pages/Ticket/Card/TicketTracking.vue
+++ b/src/pages/Ticket/Card/TicketTracking.vue
@@ -1,27 +1,23 @@
 <script setup>
-import { ref, computed, watch, reactive } from 'vue';
+import { ref, reactive, computed } from 'vue';
 import { useI18n } from 'vue-i18n';
 import { useRoute } from 'vue-router';
 
 import WorkerDescriptorProxy from 'src/pages/Worker/Card/WorkerDescriptorProxy.vue';
-import TicketCreateTracking from './TicketCreateTracking.vue';
-import VnPaginate from 'components/ui/VnPaginate.vue';
+import VnSelect from 'src/components/common/VnSelect.vue';
+import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
+import { useState } from 'src/composables/useState';
 
 import { toDateTimeFormat } from 'src/filters/date.js';
+import VnTable from 'src/components/VnTable/VnTable.vue';
+const state = useState();
+
+const user = state.getUser();
 
 const route = useRoute();
 const { t } = useI18n();
-const createTrackingDialogRef = ref(null);
-const paginateRef = ref(null);
-
-watch(
-    () => route.params.id,
-    async (val) => {
-        paginateFilter.where.ticketFk = val;
-        paginateRef.value.fetch();
-    },
-);
-
+const tableRef = ref(null);
+const onStateFkChange = (formData) => (formData.userFk = user.value.id);
 const paginateFilter = reactive({
     include: [
         {
@@ -56,75 +52,68 @@ const columns = computed(() => [
         name: 'state',
         field: 'state',
         align: 'left',
-        format: (val) => val.name,
+        format: (row) => row.state?.name,
     },
     {
         label: t('expedition.worker'),
         name: 'worker',
         align: 'left',
+        field: 'user',
     },
     {
         label: t('expedition.created'),
         name: 'created',
         field: 'created',
         align: 'left',
-        format: (val) => toDateTimeFormat(val),
+        format: ({ created }) => toDateTimeFormat(created),
     },
 ]);
-
-const openCreateModal = () => createTrackingDialogRef.value.show();
 </script>
 
 <template>
-    <QPage class="column items-center q-pa-md">
-        <VnPaginate
-            ref="paginateRef"
-            data-key="TicketTracking"
-            :user-filter="paginateFilter"
-            search-url="table"
-            url="TicketTrackings"
-            auto-load
-            order="created DESC"
-            :limit="0"
-        >
-            <template #body="{ rows }">
-                <QTable
-                    :rows="rows"
-                    :columns="columns"
-                    row-key="id"
-                    :pagination="{ rowsPerPage: 0 }"
-                    class="full-width q-mt-md"
-                    :no-data-label="t('globals.noResults')"
-                >
-                    <template #body-cell-worker="{ row }">
-                        <QTd>
-                            <QBtn flat class="link" @click.stop>
-                                {{ row.user?.name }}
-                                <WorkerDescriptorProxy :id="row.user?.worker?.id" />
-                            </QBtn>
-                        </QTd>
-                    </template>
-                </QTable>
-            </template>
-        </VnPaginate>
-        <QDialog
-            ref="createTrackingDialogRef"
-            transition-show="scale"
-            transition-hide="scale"
-        >
-            <TicketCreateTracking @on-request-created="paginateRef.fetch()" />
-        </QDialog>
-        <QPageSticky :offset="[20, 20]">
-            <QBtn
-                @click="openCreateModal()"
-                color="primary"
-                fab
-                icon="add"
-                v-shortcut="'+'"
+    <VnTable
+        ref="tableRef"
+        :right-search="false"
+        :column-search="false"
+        :disable-option="{ card: true, table: true }"
+        :search-url="false"
+        :columns="columns"
+        data-key="TicketTracking"
+        :user-filter="paginateFilter"
+        url="TicketTrackings"
+        auto-load
+        order="created DESC"
+        :limit="0"
+        :without-header="true"
+        :create="{
+            urlCreate: 'Tickets/state',
+            title: t('Create tracking'),
+            onDataSaved: () => tableRef.reload(),
+            formInitialData: {
+                ticketFk: route.params.id,
+            },
+        }"
+    >
+        <template #more-create-dialog="{ data }">
+            <VnSelect
+                url="States"
+                v-model="data.stateFk"
+                :label="t('ticketList.state')"
+                auto-load
+                @update:model-value="onStateFkChange(data)"
+                hide-selected
             />
-            <QTooltip class="text-no-wrap">
-                {{ t('tracking.addState') }}
-            </QTooltip>
-        </QPageSticky>
-    </QPage>
+            <VnSelectWorker v-model="data.userFk" :fields="['id', 'name']" />
+        </template>
+        <template #column-worker="{ row }">
+            <span class="link" @click.stop>
+                {{ row.user.name }}
+                <WorkerDescriptorProxy :id="row.user?.worker?.id" />
+            </span>
+        </template>
+    </VnTable>
 </template>
+<i18n>
+    es:
+        Create tracking: Crear estado
+</i18n>
diff --git a/src/pages/Ticket/Card/TicketVolume.vue b/src/pages/Ticket/Card/TicketVolume.vue
index db78094cf..690ae9063 100644
--- a/src/pages/Ticket/Card/TicketVolume.vue
+++ b/src/pages/Ticket/Card/TicketVolume.vue
@@ -134,7 +134,7 @@ onMounted(() => (stateStore.rightDrawer = true));
         auto-load
     >
         <template #column-itemFk="{ row }">
-            <span class="link">
+            <span class="link" @click.stop>
                 {{ row.itemFk }}
                 <ItemDescriptorProxy :id="row.itemFk" />
             </span>
diff --git a/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js b/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js
index 8fd62d8c2..a1dd7775d 100644
--- a/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js
+++ b/src/pages/Ticket/Card/__tests__/TicketBoxing.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import TicketBoxing from 'pages/Ticket/Card/TicketBoxing.vue';
 
 // #4836 - Investigate how to test q-drawer outside
@@ -21,7 +22,11 @@ describe('TicketBoxing', () => {
                 min: 1,
                 max: 2,
             };
-            const videoList = ['2022-01-01T01-01-00.mp4', '2022-02-02T02-02-00.mp4', '2022-03-03T03-03-00.mp4'];
+            const videoList = [
+                '2022-01-01T01-01-00.mp4',
+                '2022-02-02T02-02-00.mp4',
+                '2022-03-03T03-03-00.mp4',
+            ];
 
             vi.spyOn(axios, 'get').mockResolvedValue({ data: videoList });
             vi.spyOn(vm.quasar, 'notify');
@@ -44,7 +49,9 @@ describe('TicketBoxing', () => {
 
             await vm.getVideoList(expeditionId, timed);
 
-            expect(vm.quasar.notify).toHaveBeenCalledWith(expect.objectContaining({ type: 'negative' }));
+            expect(vm.quasar.notify).toHaveBeenCalledWith(
+                expect.objectContaining({ type: 'negative' })
+            );
         });
     });
 });
diff --git a/src/pages/Ticket/TicketFilter.vue b/src/pages/Ticket/TicketFilter.vue
index b763ef970..d84d1c082 100644
--- a/src/pages/Ticket/TicketFilter.vue
+++ b/src/pages/Ticket/TicketFilter.vue
@@ -22,16 +22,6 @@ const states = ref([]);
 const agencies = ref([]);
 const warehouses = ref([]);
 const groupedStates = ref([]);
-
-const getGroupedStates = (data) => {
-    for (const state of data) {
-        groupedStates.value.push({
-            id: state.id,
-            name: t(`${state.code}`),
-            code: state.code,
-        });
-    }
-};
 </script>
 
 <template>
@@ -39,12 +29,11 @@ const getGroupedStates = (data) => {
     <FetchData url="States" @on-fetch="(data) => (states = data)" auto-load />
     <FetchData
         url="AlertLevels"
-        @on-fetch="
-            (data) => {
-                getGroupedStates(data);
-            }
-        "
         auto-load
+        @on-fetch="
+            (data) =>
+                (groupedStates = data.map((x) => Object.assign(x, { code: t(x.code) })))
+        "
     />
     <FetchData
         url="AgencyModes"
@@ -126,12 +115,11 @@ const getGroupedStates = (data) => {
                 </QItemSection>
                 <QItemSection v-if="groupedStates">
                     <VnSelect
-                        :label="t('Grouped state')"
+                        :label="t('params.groupedStates')"
                         v-model="params.groupedStates"
                         @update:model-value="searchFn()"
                         :options="groupedStates"
-                        option-value="id"
-                        option-label="name"
+                        option-label="code"
                         emit-value
                         map-options
                         use-input
@@ -304,7 +292,7 @@ en:
     ON_PREPARATION: On preparation
     PACKED: Packed
     DELIVERED: Delivered
-    ON_PREVIOUS: ON_PREVIOUS
+    ON_PREVIOUS: On previous
 es:
     params:
         search: Contiene
@@ -349,7 +337,7 @@ es:
     ON_PREPARATION: En preparaciĂłn
     PACKED: Encajado
     DELIVERED: Servido
-    ON_PREVIOUS: ON_PREVIOUS
+    ON_PREVIOUS: En previa
     Collection: ColecciĂłn
     Nickname: Nombre mostrado
 </i18n>
diff --git a/src/pages/Ticket/TicketList.vue b/src/pages/Ticket/TicketList.vue
index 039d3ca9e..634b8e50a 100644
--- a/src/pages/Ticket/TicketList.vue
+++ b/src/pages/Ticket/TicketList.vue
@@ -113,7 +113,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'shipped',
+        name: 'shippedDate',
         cardVisible: true,
         label: t('ticketList.shipped'),
         columnFilter: {
@@ -123,7 +123,7 @@ const columns = computed(() => [
     },
     {
         align: 'left',
-        name: 'shipped',
+        name: 'shippedHour',
         component: 'time',
         columnFilter: false,
         label: t('ticketList.hour'),
diff --git a/src/pages/Ticket/__tests__/TicketAdvance.spec.js b/src/pages/Ticket/__tests__/TicketAdvance.spec.js
index ab1a47544..cfe5f86c5 100644
--- a/src/pages/Ticket/__tests__/TicketAdvance.spec.js
+++ b/src/pages/Ticket/__tests__/TicketAdvance.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach, beforeEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import TicketAdvance from 'pages/Ticket/TicketAdvance.vue';
 import { Notify } from 'quasar';
 import { nextTick } from 'vue';
diff --git a/src/pages/Ticket/locale/en.yml b/src/pages/Ticket/locale/en.yml
index 9eb8ce8cb..2e44df7aa 100644
--- a/src/pages/Ticket/locale/en.yml
+++ b/src/pages/Ticket/locale/en.yml
@@ -205,6 +205,7 @@ ticketList:
     toLines: Go to lines
     addressNickname: Address nickname
     ref: Reference
+    hour: Hour
     rounding: Rounding
     noVerifiedData: No verified data
     purchaseRequest: Purchase request
diff --git a/src/pages/Travel/Card/TravelCard.vue b/src/pages/Travel/Card/TravelCard.vue
index 479b47fb9..d452f5287 100644
--- a/src/pages/Travel/Card/TravelCard.vue
+++ b/src/pages/Travel/Card/TravelCard.vue
@@ -8,6 +8,6 @@ import filter from './TravelFilter.js';
         data-key="Travel"
         url="Travels"
         :descriptor="TravelDescriptor"
-        :filter="filter"
+        :filter="{ ...filter, where: { id: $route.params.id } }"
     />
 </template>
diff --git a/src/pages/Travel/Card/TravelDescriptor.vue b/src/pages/Travel/Card/TravelDescriptor.vue
index d4903f794..d57046bae 100644
--- a/src/pages/Travel/Card/TravelDescriptor.vue
+++ b/src/pages/Travel/Card/TravelDescriptor.vue
@@ -66,7 +66,7 @@ const setData = (entity) => (data.value = useCardDescription(entity.ref, entity.
                     :to="{
                         name: 'TravelList',
                         query: {
-                            params: JSON.stringify({
+                            table: JSON.stringify({
                                 agencyModeFk: entity.agencyModeFk,
                             }),
                         },
diff --git a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
index 14d824b86..f8828bffe 100644
--- a/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
+++ b/src/pages/Travel/Card/TravelDescriptorMenuItems.vue
@@ -37,7 +37,7 @@ const cloneTravelWithEntries = async () => {
     router.push({ name: 'TravelBasicData', params: { id: data.id } });
 };
 
-const canDelete = computed(() => useAcl().hasAny('Travel', '*', 'WRITE'));
+const canDelete = computed(() => useAcl().hasAcl('Travel', '*', 'WRITE'));
 
 const openDeleteEntryDialog = (id) => {
     quasar
diff --git a/src/pages/Travel/Card/TravelSummary.vue b/src/pages/Travel/Card/TravelSummary.vue
index af6db6304..22e2cff86 100644
--- a/src/pages/Travel/Card/TravelSummary.vue
+++ b/src/pages/Travel/Card/TravelSummary.vue
@@ -89,6 +89,13 @@ const entriesTableColumns = computed(() => {
             showValue: true,
         },
         { label: 'CC', field: 'cc', name: 'cc', align: 'left', showValue: true },
+        {
+            label: t('travel.summary.roundedCc'),
+            field: 'cc',
+            name: 'roundedCc',
+            align: 'left',
+            showValue: true,
+        },
         {
             label: 'Pallet',
             field: 'pallet',
@@ -191,13 +198,18 @@ const entriesTotals = computed(() => {
         freightValue: 0,
         packageValue: 0,
         cc: 0,
+        roundedCc: 0,
         pallet: 0,
         m3: 0,
     };
 
     entriesTableRows.value.forEach((row) => {
         for (const key in totals) {
-            totals[key] += row[key] || 0;
+            if (key === 'roundedCc') {
+                totals['roundedCc'] += Math.ceil(row['cc'] || 0);
+            } else {
+                totals[key] += row[key] || 0;
+            }
         }
     });
 
@@ -206,6 +218,7 @@ const entriesTotals = computed(() => {
         freight: toCurrency(totals.freightValue),
         packageValue: toCurrency(totals.packageValue),
         cc: totals.cc.toFixed(2),
+        roundedCc: totals.roundedCc,
         pallet: totals.pallet.toFixed(2),
         m3: totals.m3.toFixed(2),
     };
@@ -370,6 +383,11 @@ onMounted(async () => {
                             </QBtn>
                         </QTd>
                     </template>
+                    <template #body-cell-roundedCc="{ col, value }">
+                        <QTd>
+                            {{ Math.ceil(value) || 0 }}
+                        </QTd>
+                    </template>
                     <template #body-cell-observation="{ value }">
                         <QTd>
                             <QIcon name="insert_drive_file" color="primary" size="24px">
@@ -386,23 +404,24 @@ onMounted(async () => {
                         <QTd class="text-bold">{{ entriesTotals.freight }}</QTd>
                         <QTd class="text-bold">{{ entriesTotals.packageValue }}</QTd>
                         <QTd class="text-bold">{{ entriesTotals.cc }}</QTd>
+                        <QTd class="text-bold">{{ entriesTotals.roundedCc }}</QTd>
                         <QTd class="text-bold">{{ entriesTotals.pallet }}</QTd>
                         <QTd class="text-bold">{{ entriesTotals.m3 }}</QTd>
                     </template>
                 </QTable>
             </QCard>
-
             <QCard class="full-width" v-if="thermographs.length > 0">
-                <RouterLink
-                    class="header header-link"
-                    :to="{
-                        name: 'TravelThermographsIndex',
-                        params: { id: travel.id },
-                    }"
-                >
-                    {{ t('travel.summary.thermographs') }}
-                    <QIcon name="open_in_new" />
-                </RouterLink>
+                <FetchData
+                    url="Warehouses"
+                    :filter="{ fields: ['id', 'name'] }"
+                    order="name"
+                    @on-fetch="(data) => (warehouses = data)"
+                    auto-load
+                />
+                <VnTitle
+                    :url="getLink('thermographs')"
+                    :text="t('travel.summary.thermographs')"
+                />
                 <QTable
                     :rows="thermographs"
                     :columns="thermographsTableColumns"
diff --git a/src/pages/Travel/ExtraCommunity.vue b/src/pages/Travel/ExtraCommunity.vue
index ac46caa44..849eeee5b 100644
--- a/src/pages/Travel/ExtraCommunity.vue
+++ b/src/pages/Travel/ExtraCommunity.vue
@@ -18,7 +18,6 @@ import { usePrintService } from 'composables/usePrintService';
 import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
 import axios from 'axios';
 import RightMenu from 'src/components/common/RightMenu.vue';
-import VnPopup from 'src/components/common/VnPopup.vue';
 
 const stateStore = useStateStore();
 const { t } = useI18n();
@@ -141,7 +140,6 @@ const columns = computed(() => [
         label: 'id',
         field: 'id',
         name: 'id',
-        align: 'center',
         showValue: true,
         sortable: true,
     },
@@ -165,7 +163,7 @@ const columns = computed(() => [
         label: t('globals.amount'),
         name: 'invoiceAmount',
         field: 'entries',
-        align: 'left',
+        align: 'right',
         showValue: true,
         sortable: true,
         format: (value) =>
@@ -184,13 +182,12 @@ const columns = computed(() => [
         align: 'left',
         showValue: false,
         sortable: true,
-        style: 'min-width: 170px;',
     },
     {
         label: t('globals.packages'),
         field: 'stickers',
         name: 'stickers',
-        align: 'left',
+        align: 'right',
         showValue: true,
         sortable: true,
     },
@@ -198,7 +195,7 @@ const columns = computed(() => [
         label: '%',
         field: '',
         name: 'percentage',
-        align: 'center',
+        align: 'right',
         showValue: false,
         sortable: true,
     },
@@ -214,7 +211,7 @@ const columns = computed(() => [
         label: t('extraCommunity.physicKg'),
         field: 'loadedKg',
         name: 'loadedKg',
-        align: 'left',
+        align: 'right',
         showValue: true,
         sortable: true,
     },
@@ -222,7 +219,7 @@ const columns = computed(() => [
         label: 'KG Vol.',
         field: 'volumeKg',
         name: 'volumeKg',
-        align: 'left',
+        align: 'right',
         showValue: true,
         sortable: true,
     },
@@ -277,7 +274,6 @@ async function getData() {
 const onStoreDataChange = () => {
     const newData = JSON.parse(JSON.stringify(arrayData.store.data)) || [];
     rows.value = newData;
-    // el objetivo de esto es guardar una copia de los valores iniciales de todas las rows para corroborar si la data cambio antes de guardar los cambios
     originalRowDataCopy.value = JSON.parse(JSON.stringify(newData));
 };
 
@@ -300,20 +296,17 @@ const openReportPdf = () => {
 };
 
 const saveFieldValue = async (val, field, index) => {
-    // Evitar la solicitud de guardado si el valor no ha cambiado
     if (originalRowDataCopy.value[index][field] == val) return;
 
     const id = rows.value[index].id;
     const params = { [field]: val };
     await axios.patch(`Travels/${id}`, params);
-    // Actualizar la copia de los datos originales con el nuevo valor
     originalRowDataCopy.value[index][field] = val;
 
     await arrayData.fetch({ append: false });
 };
 
 const stopEventPropagation = (event, col) => {
-    // Detener la propagaciĂłn del evento de los siguientes elementos para evitar el click sobre la row que dispararĂ­a  la funciĂłn navigateToTravelId
     if (!['ref', 'id', 'cargoSupplierNickname', 'kg'].includes(col.name)) return;
     event.preventDefault();
     event.stopPropagation();
@@ -335,14 +328,12 @@ onMounted(async () => {
     await getData();
 });
 
-// Handler del evento @dragstart (inicio del drag) y guarda informaciĂłn inicial
 const handleDragStart = (event, rowIndex, entryIndex) => {
     draggedRowIndex.value = rowIndex;
     entryRowIndex.value = entryIndex;
     event.dataTransfer.effectAllowed = 'move';
 };
 
-// Handler del evento @dragenter (cuando haces drag sobre une elemento y lo arrastras sobre un posible target de drop) y actualiza el targetIndex
 const handleDragEnter = (_, targetIndex) => {
     targetRowIndex.value = targetIndex;
 };
@@ -356,11 +347,8 @@ const saveRowDrop = async (targetRowIndex) => {
 const moveRow = async (draggedRowIndex, targetRowIndex, entryIndex) => {
     try {
         if (draggedRowIndex === targetRowIndex) return;
-        // Remover entry de la row original
         draggedEntry.value = rows.value[draggedRowIndex].entries.splice(entryIndex, 1)[0];
-        //Si la row de destino por alguna razĂłn no tiene la propiedad entry la creamos
         if (!rows.value[targetRowIndex].entries) rows.value[targetRowIndex].entries = [];
-        // Añadir entry a la row de destino
         rows.value[targetRowIndex].entries.push(draggedEntry.value);
 
         await saveRowDrop(targetRowIndex);
@@ -370,13 +358,11 @@ const moveRow = async (draggedRowIndex, targetRowIndex, entryIndex) => {
     }
 };
 
-// Handler de cuando haces un drop tanto dentro como fuera de la tabla para limpiar acciones y data
 const handleDragEnd = () => {
     stopScroll();
     cleanDragAndDropData();
 };
 
-// Handler del evento @drop (cuando soltas el elemento draggeado sobre un target)
 const handleDrop = () => {
     if (
         !draggedRowIndex.value &&
@@ -399,7 +385,6 @@ const cleanDragAndDropData = () => {
 const scrollInterval = ref(null);
 
 const startScroll = (direction) => {
-    // Iniciar el scroll en la direcciĂłn especificada
     if (!scrollInterval.value) {
         scrollInterval.value = requestAnimationFrame(() => scroll(direction));
     }
@@ -413,14 +398,12 @@ const stopScroll = () => {
 };
 
 const scroll = (direction) => {
-    // Controlar el desplazamiento en la direcciĂłn especificada
     const yOffset = direction === 'up' ? -2 : 2;
     window.scrollBy(0, yOffset);
 
     const windowHeight = window.innerHeight;
     const documentHeight = document.body.offsetHeight;
 
-    // Verificar si se alcanzaron los lĂ­mites de la ventana para detener el desplazamiento
     if (
         (direction === 'up' && window.scrollY > 0) ||
         (direction === 'down' && windowHeight + window.scrollY < documentHeight)
@@ -431,13 +414,10 @@ const scroll = (direction) => {
     }
 };
 
-// Handler del scroll mientras se hace el drag de una row
 const handleDragScroll = (event) => {
-    // Obtener la posiciĂłn y dimensiones del cursor
     const y = event.clientY;
     const windowHeight = window.innerHeight;
 
-    // Verificar si el cursor está cerca del borde superior o inferior de la ventana
     const nearTop = y < 150;
     const nearBottom = y > windowHeight - 100;
 
@@ -547,7 +527,7 @@ watch(route, () => {
                                         ? `${props.row.percentageKg}%`
                                         : '-'
                                 "
-                                class="text-left q-py-xs q-px-sm"
+                                class="text-right q-py-xs q-px-sm"
                                 :color="getColor(props.row.percentageKg)"
                             />
                             <span
@@ -566,7 +546,6 @@ watch(route, () => {
                                 ]"
                                 v-text="col.value"
                             />
-                            <!-- Main Row Descriptors -->
                             <TravelDescriptorProxy
                                 v-if="col.name === 'id'"
                                 :id="props.row.id"
@@ -597,58 +576,46 @@ watch(route, () => {
                             index === props.row.entries.length - 1,
                     }"
                 >
-                    <QTd>
+                    <QTd class="text-right">
                         <QBtn dense flat class="link">{{ entry.id }} </QBtn>
                         <EntryDescriptorProxy :id="entry.id" />
                     </QTd>
-                    <QTd>
-                        <QBtn flat class="link" dense>{{ entry.supplierName }}</QBtn>
-                        <SupplierDescriptorProxy :id="entry.supplierFk" />
+                    <QTd :colspan="2">
+                        <div style="display: flex">
+                            <span class="link">
+                                {{ entry.supplierName }}
+                                <SupplierDescriptorProxy :id="entry.supplierFk" />
+                            </span>
+                            <QIcon
+                                v-if="entry.isCustomInspectionRequired"
+                                name="warning"
+                                color="negative"
+                                size="md"
+                                :title="t('extraCommunity.requiresInspection')"
+                            />
+                        </div>
                     </QTd>
-                    <QTd>
-                        <QIcon
-                            v-if="entry.isCustomInspectionRequired"
-                            name="warning"
-                            color="negative"
-                            size="md"
-                            :title="t('extraCommunity.requiresInspection')"
-                        >
-                        </QIcon>
-                    </QTd>
-                    <QTd>
+                    <QTd class="text-right">
                         <span>{{ toCurrency(entry.invoiceAmount) }}</span>
                     </QTd>
                     <QTd>
                         <span>{{ entry.reference }}</span>
                     </QTd>
-                    <QTd>
+                    <QTd class="text-right">
                         <span>{{ entry.stickers }}</span>
                     </QTd>
                     <QTd />
                     <QTd></QTd>
-                    <QTd>
+                    <QTd class="text-right">
                         <span>{{ entry.loadedkg }}</span>
                     </QTd>
-                    <QTd>
+                    <QTd class="text-right">
                         <span>{{ entry.volumeKg }}</span>
                     </QTd>
-                    <QTd />
-                    <QTd />
-                    <QTd />
-                    <QTd />
-                    <QTd>
-                        <QBtn
-                            v-if="entry.evaNotes"
-                            icon="comment"
-                            size="md"
-                            flat
-                            color="primary"
-                        >
-                            <VnPopup
-                                :title="t('globals.observations')"
-                                :content="entry.evaNotes"
-                            />
-                        </QBtn>
+                    <QTd :colspan="5" class="text-right">
+                        <span>
+                            {{ entry.evaNotes }}
+                        </span>
                     </QTd>
                 </QTr>
             </template>
@@ -662,18 +629,21 @@ watch(route, () => {
 }
 
 :deep(.q-table) {
+    table-layout: auto;
+    width: 100%;
     border-collapse: collapse;
+    overflow: hidden;
+    text-overflow: ellipsis;
 
-    th {
-        padding: 0;
-    }
     tbody tr td {
         &:nth-child(1) {
             max-width: 65px;
         }
-        &:nth-child(4) {
-            padding: 0;
-        }
+        padding: 0 5px 0;
+    }
+    thead > tr > th {
+        padding: 3px;
+        color: var(--vn-label-color);
     }
 }
 
diff --git a/src/pages/Travel/TravelFilter.vue b/src/pages/Travel/TravelFilter.vue
index a26cc0ec0..5498fd269 100644
--- a/src/pages/Travel/TravelFilter.vue
+++ b/src/pages/Travel/TravelFilter.vue
@@ -80,7 +80,7 @@ defineExpose({ states });
                 />
                 <VnSelect
                     :label="t('travel.warehouseOut')"
-                    v-model="params.warehouseOut"
+                    v-model="params.warehouseOutFk"
                     @update:model-value="searchFn()"
                     url="warehouses"
                     :use-like="false"
@@ -128,6 +128,7 @@ en:
         ref: Reference
         agency: Agency
         warehouseInFk: Warehouse In
+        warehouseOutFk: Warehouse Out
         shipped: Shipped
         shipmentHour: Shipment Hour
         warehouseOut: Warehouse Out
@@ -141,6 +142,7 @@ es:
         ref: Referencia
         agency: Agencia
         warehouseInFk: Alm.Entrada
+        warehouseOutFk: Alm.Salida
         shipped: F.EnvĂ­o
         shipmentHour: Hora de envĂ­o
         warehouseOut: Alm.Salida
diff --git a/src/pages/Wagon/__tests__/WagonCreate.spec.js b/src/pages/Wagon/__tests__/WagonCreate.spec.js
index f195c183f..9be19e027 100644
--- a/src/pages/Wagon/__tests__/WagonCreate.spec.js
+++ b/src/pages/Wagon/__tests__/WagonCreate.spec.js
@@ -1,5 +1,6 @@
 import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
-import { createWrapper, axios } from 'app/test/vitest/helper';
+import axios from 'axios';
+import { createWrapper } from 'app/test/vitest/helper';
 import WagonCreate from 'pages/Wagon/WagonCreate.vue';
 
 describe('WagonCreate', () => {
diff --git a/src/pages/Worker/Card/WorkerCalendar.vue b/src/pages/Worker/Card/WorkerCalendar.vue
index df4616011..05ebb4687 100644
--- a/src/pages/Worker/Card/WorkerCalendar.vue
+++ b/src/pages/Worker/Card/WorkerCalendar.vue
@@ -18,9 +18,7 @@ const router = useRouter();
 const route = useRoute();
 const { t } = useI18n();
 const acl = useAcl();
-const canSeeNotes = computed(() =>
-    acl.hasAny([{ model: 'Worker', props: '__get__business', accessType: 'READ' }]),
-);
+const canSeeNotes = computed(() => acl.hasAcl('Worker', '__get__business', 'READ'));
 const workerIsFreelance = ref();
 const WorkerFreelanceRef = ref();
 const workerCalendarFilterRef = ref(null);
diff --git a/src/pages/Worker/Card/WorkerCalendarFilter.vue b/src/pages/Worker/Card/WorkerCalendarFilter.vue
index f0e2d758a..32edaa6e9 100644
--- a/src/pages/Worker/Card/WorkerCalendarFilter.vue
+++ b/src/pages/Worker/Card/WorkerCalendarFilter.vue
@@ -166,50 +166,44 @@ const yearList = ref(generateYears());
             }}
         </QCardSection>
     </div>
-    <QList dense class="list q-gutter-y-sm q-my-lg">
-        <QItem>
-            <QItemSection>
-                <VnSelect
-                    :label="t('Year')"
-                    v-model="selectedYear"
-                    :options="yearList"
-                    dense
-                    filled
-                    use-input
-                    :is-clearable="false"
-                />
-            </QItemSection>
-            <QItemSection>
-                <VnSelect
-                    :label="t('Contract')"
-                    v-model="selectedBusinessFk"
-                    :options="contractList"
-                    option-value="businessFk"
-                    option-label="businessFk"
-                    dense
-                    filled
-                    use-input
-                    :is-clearable="false"
-                >
-                    <template #option="scope">
-                        <QItem v-bind="scope.itemProps">
-                            <QItemSection>
-                                <QItemLabel># {{ scope.opt?.businessFk }}</QItemLabel>
-                                <QItemLabel caption>
-                                    {{ toDateFormat(scope.opt?.started) }} -
-                                    {{
-                                        scope.opt?.ended
-                                            ? toDateFormat(scope.opt?.ended)
-                                            : 'Indef.'
-                                    }}
-                                </QItemLabel>
-                            </QItemSection>
-                        </QItem>
-                    </template>
-                </VnSelect>
-            </QItemSection>
-        </QItem>
-    </QList>
+    <div dense class="column q-gutter-y-sm q-px-md">
+        <VnSelect
+            :label="t('Year')"
+            v-model="selectedYear"
+            :options="yearList"
+            dense
+            filled
+            use-input
+            :is-clearable="false"
+        />
+        <VnSelect
+            :label="t('Contract')"
+            v-model="selectedBusinessFk"
+            :options="contractList"
+            option-value="businessFk"
+            option-label="businessFk"
+            dense
+            filled
+            use-input
+            :is-clearable="false"
+        >
+            <template #option="scope">
+                <QItem v-bind="scope.itemProps">
+                    <QItemSection>
+                        <QItemLabel># {{ scope.opt?.businessFk }}</QItemLabel>
+                        <QItemLabel caption>
+                            {{ toDateFormat(scope.opt?.started) }} -
+                            {{
+                                scope.opt?.ended
+                                    ? toDateFormat(scope.opt?.ended)
+                                    : 'Indef.'
+                            }}
+                        </QItemLabel>
+                    </QItemSection>
+                </QItem>
+            </template>
+        </VnSelect>
+    </div>
     <QList dense class="list q-gutter-y-xs q-my-md">
         <QItem v-for="type in absenceTypeList" :key="type.id">
             <WorkerEventLabel
diff --git a/src/pages/Worker/Card/WorkerDescriptor.vue b/src/pages/Worker/Card/WorkerDescriptor.vue
index 060520e84..9576e7e84 100644
--- a/src/pages/Worker/Card/WorkerDescriptor.vue
+++ b/src/pages/Worker/Card/WorkerDescriptor.vue
@@ -116,7 +116,7 @@ const handlePhotoUpdated = (evt = false) => {
         <template #body="{ entity }">
             <VnLv :label="t('globals.user')" :value="entity.user?.name" />
             <VnLv
-                class="ellipsis-text"
+                class="ellipsis"
                 :label="t('globals.params.email')"
                 :value="entity.user?.emailUser?.email"
                 copy
@@ -128,15 +128,13 @@ const handlePhotoUpdated = (evt = false) => {
                 </template>
             </VnLv>
 
-            <VnLv :value="entity.phone">
-                <template #label>
-                    {{ t('globals.phone') }}
+            <VnLv :label="t('globals.phone')">
+                <template #value>
                     <VnLinkPhone :phone-number="entity.phone" />
                 </template>
             </VnLv>
-            <VnLv :value="entity?.sip?.extension">
-                <template #label>
-                    {{ t('worker.summary.sipExtension') }}
+            <VnLv :label="t('worker.summary.sipExtension')">
+                <template #value>
                     <VnLinkPhone :phone-number="entity?.sip?.extension" />
                 </template>
             </VnLv>
diff --git a/src/pages/Worker/Card/WorkerDescriptorProxy.vue b/src/pages/Worker/Card/WorkerDescriptorProxy.vue
index 5f71abbea..baa9aa571 100644
--- a/src/pages/Worker/Card/WorkerDescriptorProxy.vue
+++ b/src/pages/Worker/Card/WorkerDescriptorProxy.vue
@@ -11,7 +11,7 @@ const $props = defineProps({
 </script>
 
 <template>
-    <QPopupProxy>
+    <QPopupProxy data-cy="WorkerDescriptor">
         <WorkerDescriptor
             v-if="$props.id"
             :id="$props.id"
diff --git a/src/pages/Worker/Card/WorkerLocker.vue b/src/pages/Worker/Card/WorkerLocker.vue
index 015bced35..62891070d 100644
--- a/src/pages/Worker/Card/WorkerLocker.vue
+++ b/src/pages/Worker/Card/WorkerLocker.vue
@@ -9,7 +9,7 @@ import VnSelect from 'src/components/common/VnSelect.vue';
 import { useArrayData } from 'src/composables/useArrayData';
 import FetchData from 'components/FetchData.vue';
 
-const { hasAny } = useAcl();
+const { hasAcl } = useAcl();
 const { t } = useI18n();
 const fetchData = ref();
 const originaLockerId = ref();
@@ -58,11 +58,7 @@ const init = async (data) => {
                 option-label="code"
                 option-value="id"
                 hide-selected
-                :readonly="
-                    !hasAny([
-                        { model: 'Worker', props: '__get__locker', accessType: 'READ' },
-                    ])
-                "
+                :readonly="!hasAcl('Worker', '__get__locker', 'READ')"
             />
         </template>
     </FormModel>
diff --git a/src/pages/Worker/Card/WorkerPda.vue b/src/pages/Worker/Card/WorkerPda.vue
index 001eb368a..590cbc2b2 100644
--- a/src/pages/Worker/Card/WorkerPda.vue
+++ b/src/pages/Worker/Card/WorkerPda.vue
@@ -102,8 +102,8 @@ async function fetchDocuware() {
                     Value: ['PDA'],
                 },
                 {
-                    DBName: 'FILENAME',
-                    Value: [`${row.deviceProductionFk}-pda`],
+                    DBName: 'OBSERVACIONES',
+                    Value: [row.deviceProductionFk],
                 },
             ],
         });
@@ -234,7 +234,7 @@ function isSigned(row) {
                 data-cy="workerPda-download"
             >
                 <QTooltip>
-                    {{ t('worker.pda.download') }}
+                    {{ t('globals.downloadPdf') }}
                 </QTooltip>
             </QBtn>
         </template>
@@ -307,4 +307,5 @@ es:
     This PDA is already assigned to another user: Este PDA ya está asignado a otro usuario
     Are you sure you want to send it?: ÂżSeguro que quieres enviarlo?
     Sign PDA: Firmar PDA
+    PDF sended to signed: PDF enviado para firmar
 </i18n>
diff --git a/src/pages/Worker/Card/WorkerSummary.vue b/src/pages/Worker/Card/WorkerSummary.vue
index 40787613c..96d5220f5 100644
--- a/src/pages/Worker/Card/WorkerSummary.vue
+++ b/src/pages/Worker/Card/WorkerSummary.vue
@@ -73,28 +73,25 @@ onBeforeMount(async () => {
                                 />
                             </template>
                         </VnLv>
-                        <VnLv :value="worker.mobileExtension">
-                            <template #label>
-                                {{ t('worker.summary.phoneExtension') }}
+                        <VnLv :label="t('worker.summary.phoneExtension')">
+                            <template #value>
                                 <VnLinkPhone :phone-number="worker.mobileExtension" />
                             </template>
                         </VnLv>
-                        <VnLv :value="worker.phone">
-                            <template #label>
-                                {{ t('worker.summary.entPhone') }}
+                        <VnLv :label="t('worker.summary.entPhone')">
+                            <template #value>
                                 <VnLinkPhone :phone-number="worker.phone" />
                             </template>
                         </VnLv>
-                        <VnLv :value="advancedSummary?.client?.phone">
-                            <template #label>
-                                {{ t('worker.summary.personalPhone') }}
+                        <VnLv :label="t('worker.summary.personalPhone')">
+                            <template #value>
                                 <VnLinkPhone
                                     :phone-number="advancedSummary?.client?.phone"
                                 />
                             </template>
                         </VnLv>
                     </div>
-                    <div class="vn-card-content">
+                    <div class="vn-card-content" v-if="advancedSummary">
                         <VnLv
                             :label="t('worker.summary.fiDueDate')"
                             :value="toDate(advancedSummary.fiDueDate)"
@@ -135,6 +132,7 @@ onBeforeMount(async () => {
                 <VnTitle :text="t('worker.summary.userData')" />
                 <VnLv :label="t('globals.name')" :value="worker?.user?.nickname" />
                 <VnLv
+                    class="ellipsis"
                     :label="t('globals.params.email')"
                     :value="worker.user?.emailUser?.email"
                     copy
@@ -147,9 +145,8 @@ onBeforeMount(async () => {
                         </span>
                     </template>
                 </VnLv>
-                <VnLv :value="worker?.sip?.extension">
-                    <template #label>
-                        {{ t('worker.summary.sipExtension') }}
+                <VnLv :label="t('worker.summary.sipExtension')">
+                    <template #value>
                         <VnLinkPhone :phone-number="worker?.sip?.extension" />
                     </template>
                 </VnLv>
diff --git a/src/pages/Worker/Card/WorkerTimeControl.vue b/src/pages/Worker/Card/WorkerTimeControl.vue
index 9c0fa6758..b64166c7d 100644
--- a/src/pages/Worker/Card/WorkerTimeControl.vue
+++ b/src/pages/Worker/Card/WorkerTimeControl.vue
@@ -68,13 +68,9 @@ const arrayData = useArrayData('Worker');
 const acl = useAcl();
 const selectedDateYear = computed(() => moment(selectedDate.value).isoWeekYear());
 const worker = computed(() => arrayData.store?.data);
-const canSend = computed(() =>
-    acl.hasAny([{ model: 'WorkerTimeControl', props: 'sendMail', accessType: 'WRITE' }]),
-);
+const canSend = computed(() => acl.hasAcl('WorkerTimeControl', 'sendMail', 'WRITE'));
 const canUpdate = computed(() =>
-    acl.hasAny([
-        { model: 'WorkerTimeControl', props: 'updateMailState', accessType: 'WRITE' },
-    ]),
+    acl.hasAcl('WorkerTimeControl', 'updateMailState', 'WRITE'),
 );
 const isHimself = computed(() => user.value.id === Number(route.params.id));
 
diff --git a/src/pages/Worker/WorkerFilter.vue b/src/pages/Worker/WorkerFilter.vue
index 44dfd32b4..c40afe57e 100644
--- a/src/pages/Worker/WorkerFilter.vue
+++ b/src/pages/Worker/WorkerFilter.vue
@@ -102,8 +102,11 @@ en:
         lastName: Last name
         userName: User
         extension: Extension
+        departmentFk: Department
 es:
+
     params:
+        departmentFk: Departamento
         search: Contiene
         firstName: Nombre
         lastName: Apellidos
diff --git a/src/pages/Zone/Card/ZoneDescriptorProxy.vue b/src/pages/Zone/Card/ZoneDescriptorProxy.vue
index 27102ac07..a16d231e6 100644
--- a/src/pages/Zone/Card/ZoneDescriptorProxy.vue
+++ b/src/pages/Zone/Card/ZoneDescriptorProxy.vue
@@ -11,7 +11,7 @@ const $props = defineProps({
 </script>
 
 <template>
-    <QPopupProxy>
+    <QPopupProxy data-cy="ZoneDescriptor">
         <ZoneDescriptor v-if="$props.id" :id="$props.id" :summary="ZoneSummary" />
     </QPopupProxy>
 </template>
diff --git a/src/pages/Zone/Card/ZoneSummary.vue b/src/pages/Zone/Card/ZoneSummary.vue
index 61475b1f6..5958fe27a 100644
--- a/src/pages/Zone/Card/ZoneSummary.vue
+++ b/src/pages/Zone/Card/ZoneSummary.vue
@@ -75,13 +75,13 @@ onMounted(async () => {
         <template #body="{ entity: zone }">
             <QCard class="vn-one">
                 <VnTitle :url="zoneUrl + `basic-data`" :text="t('summary.basicData')" />
-                <div class="card-group">
-                    <div class="card-content">
+                <div class="vn-card-group">
+                    <div class="vn-card-content">
                         <VnLv :label="t('list.agency')" :value="zone.agencyMode?.name" />
                         <VnLv :label="t('list.price')" :value="toCurrency(zone.price)" />
                         <VnLv :label="t('zone.bonus')" :value="toCurrency(zone.bonus)" />
                     </div>
-                    <div class="card-content">
+                    <div class="vn-card-content">
                         <VnLv
                             :label="t('summary.closeHour')"
                             :value="toTimeFormat(zone.hour)"
@@ -98,7 +98,7 @@ onMounted(async () => {
                     </div>
                 </div>
             </QCard>
-            <QCard class="vn-one">
+            <QCard class="vn-max">
                 <VnTitle :url="zoneUrl + `warehouses`" :text="t('list.warehouse')" />
                 <QTable
                     :columns="columns"
@@ -109,15 +109,3 @@ onMounted(async () => {
         </template>
     </CardSummary>
 </template>
-
-<style lang="scss" scoped>
-.card-group {
-    display: flex;
-    flex-direction: column;
-}
-
-.card-content {
-    display: flex;
-    flex-direction: column;
-}
-</style>
diff --git a/src/router/__tests__/hooks.spec.js b/src/router/__tests__/hooks.spec.js
new file mode 100644
index 000000000..97f5eacdc
--- /dev/null
+++ b/src/router/__tests__/hooks.spec.js
@@ -0,0 +1,36 @@
+import { describe, it, expect, vi } from 'vitest';
+import { ref, nextTick } from 'vue';
+import { stateQueryGuard } from 'src/router/hooks';
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
+
+vi.mock('src/stores/useStateQueryStore', () => {
+    const isLoading = ref(true);
+    return {
+        useStateQueryStore: () => ({
+            isLoading: () => isLoading,
+            setLoading: isLoading,
+        }),
+    };
+});
+
+describe('hooks', () => {
+    describe('stateQueryGuard', () => {
+        const foo = { name: 'foo' };
+        it('should wait until the state query is not loading and then call next()', async () => {
+            const next = vi.fn();
+
+            stateQueryGuard(foo, { name: 'bar' }, next);
+            expect(next).not.toHaveBeenCalled();
+
+            useStateQueryStore().setLoading.value = false;
+            await nextTick();
+            expect(next).toHaveBeenCalled();
+        });
+
+        it('should ignore if both routes are the same', () => {
+            const next = vi.fn();
+            stateQueryGuard(foo, foo, next);
+            expect(next).toHaveBeenCalled();
+        });
+    });
+});
diff --git a/src/router/hooks.js b/src/router/hooks.js
new file mode 100644
index 000000000..bd9e5334f
--- /dev/null
+++ b/src/router/hooks.js
@@ -0,0 +1,95 @@
+import { useRole } from 'src/composables/useRole';
+import { useUserConfig } from 'src/composables/useUserConfig';
+import { useTokenConfig } from 'src/composables/useTokenConfig';
+import { useAcl } from 'src/composables/useAcl';
+import { isLoggedIn } from 'src/utils/session';
+import { useSession } from 'src/composables/useSession';
+import { useStateQueryStore } from 'src/stores/useStateQueryStore';
+import { watch } from 'vue';
+import { i18n } from 'src/boot/i18n';
+
+let session = null;
+const { t, te } = i18n.global;
+
+export async function navigationGuard(to, from, next, Router, state) {
+    if (!session) session = useSession();
+    const outLayout = Router.options.routes[0].children.map((r) => r.name);
+    if (!session.isLoggedIn() && !outLayout.includes(to.name)) {
+        return next({ name: 'Login', query: { redirect: to.fullPath } });
+    }
+
+    if (isLoggedIn()) {
+        const stateRoles = state.getRoles().value;
+        if (stateRoles.length === 0) {
+            await useRole().fetch();
+            await useAcl().fetch();
+            await useUserConfig().fetch();
+            await useTokenConfig().fetch();
+        }
+        const matches = to.matched;
+        const hasRequiredAcls = matches.every((route) => {
+            const meta = route.meta;
+            if (!meta?.acls) return true;
+            return useAcl().hasAny(meta.acls);
+        });
+        if (!hasRequiredAcls) return next({ path: '/' });
+    }
+
+    next();
+}
+
+export async function stateQueryGuard(to, from, next) {
+    if (to.name !== from.name) {
+        const stateQuery = useStateQueryStore();
+        await waitUntilFalse(stateQuery.isLoading());
+    }
+
+    next();
+}
+
+export function setPageTitle(to) {
+    let title = t(`login.title`);
+
+    const matches = to.matched;
+    if (matches && matches.length > 1) {
+        const module = matches[1];
+        const moduleTitle = module.meta?.title;
+        if (moduleTitle) {
+            title = t(`globals.pageTitles.${moduleTitle}`);
+        }
+    }
+
+    const childPage = to.meta;
+    const childPageTitle = childPage?.title;
+    if (childPageTitle && matches.length > 2) {
+        if (title != '') title += ': ';
+
+        const moduleLocale = `globals.pageTitles.${childPageTitle}`;
+        const pageTitle = te(moduleLocale)
+            ? t(moduleLocale)
+            : t(`globals.pageTitles.${childPageTitle}`);
+        const idParam = to.params?.id;
+        const idPageTitle = `${idParam} - ${pageTitle}`;
+        const builtTitle = idParam ? idPageTitle : pageTitle;
+
+        title += builtTitle;
+    }
+
+    document.title = title;
+}
+
+function waitUntilFalse(ref) {
+    return new Promise((resolve) => {
+        if (!ref.value) return resolve();
+        const stop = watch(
+            ref,
+            (val) => {
+                if (!val) {
+                    stop();
+                    resolve();
+                }
+            },
+            { immediate: true },
+        );
+    });
+}
diff --git a/src/router/index.js b/src/router/index.js
index 4403901cb..628a53c8e 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -6,101 +6,25 @@ import {
     createWebHashHistory,
 } from 'vue-router';
 import routes from './routes';
-import { i18n } from 'src/boot/i18n';
 import { useState } from 'src/composables/useState';
-import { useRole } from 'src/composables/useRole';
-import { useUserConfig } from 'src/composables/useUserConfig';
-import { useTokenConfig } from 'src/composables/useTokenConfig';
-import { useAcl } from 'src/composables/useAcl';
-import { isLoggedIn } from 'src/utils/session';
-import { useSession } from 'src/composables/useSession';
+import { navigationGuard, setPageTitle, stateQueryGuard } from './hooks';
 
-let session = null;
-const { t, te } = i18n.global;
-
-const createHistory = process.env.SERVER
-    ? createMemoryHistory
-    : process.env.VUE_ROUTER_MODE === 'history'
-      ? createWebHistory
-      : createWebHashHistory;
+const webHistory =
+    process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory;
+const createHistory = process.env.SERVER ? createMemoryHistory : webHistory;
 
 const Router = createRouter({
     scrollBehavior: () => ({ left: 0, top: 0 }),
     routes,
-
-    // Leave this as is and make changes in quasar.conf.js instead!
-    // quasar.conf.js -> build -> vueRouterMode
-    // quasar.conf.js -> build -> publicPath
     history: createHistory(process.env.VUE_ROUTER_BASE),
 });
 
-/*
- * If not building with SSR mode, you can
- * directly export the Router instantiation;
- *
- * The function below can be async too; either use
- * async/await or return a Promise which resolves
- * with the Router instance.
- */
 export { Router };
-export default defineRouter(function (/* { store, ssrContext } */) {
+export default defineRouter(() => {
     const state = useState();
-    Router.beforeEach(async (to, from, next) => {
-        if (!session) session = useSession();
-        const outLayout = Router.options.routes[0].children.map((r) => r.name);
-        if (!session.isLoggedIn() && !outLayout.includes(to.name)) {
-            return next({ name: 'Login', query: { redirect: to.fullPath } });
-        }
-
-        if (isLoggedIn()) {
-            const stateRoles = state.getRoles().value;
-            if (stateRoles.length === 0) {
-                await useRole().fetch();
-                await useAcl().fetch();
-                await useUserConfig().fetch();
-                await useTokenConfig().fetch();
-            }
-            const matches = to.matched;
-            const hasRequiredAcls = matches.every((route) => {
-                const meta = route.meta;
-                if (!meta?.acls) return true;
-                return useAcl().hasAny(meta.acls);
-            });
-            if (!hasRequiredAcls) return next({ path: '/' });
-        }
-
-        next();
-    });
-
-    Router.afterEach((to) => {
-        let title = t(`login.title`);
-
-        const matches = to.matched;
-        if (matches && matches.length > 1) {
-            const module = matches[1];
-            const moduleTitle = module.meta && module.meta.title;
-            if (moduleTitle) {
-                title = t(`globals.pageTitles.${moduleTitle}`);
-            }
-        }
-
-        const childPage = to.meta;
-        const childPageTitle = childPage && childPage.title;
-        if (childPageTitle && matches.length > 2) {
-            if (title != '') title += ': ';
-
-            const moduleLocale = `globals.pageTitles.${childPageTitle}`;
-            const pageTitle = te(moduleLocale)
-                ? t(moduleLocale)
-                : t(`globals.pageTitles.${childPageTitle}`);
-            const idParam = to.params && to.params.id;
-            const idPageTitle = `${idParam} - ${pageTitle}`;
-            const builtTitle = idParam ? idPageTitle : pageTitle;
-
-            title += builtTitle;
-        }
-        document.title = title;
-    });
+    Router.beforeEach((to, from, next) => navigationGuard(to, from, next, Router, state));
+    Router.beforeEach(stateQueryGuard);
+    Router.afterEach(setPageTitle);
 
     Router.onError(({ message }) => {
         const errorMessages = [
diff --git a/src/router/modules/route.js b/src/router/modules/route.js
index 62765a49c..0dd41c86e 100644
--- a/src/router/modules/route.js
+++ b/src/router/modules/route.js
@@ -166,7 +166,7 @@ const vehicleCard = {
     component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'),
     redirect: { name: 'VehicleSummary' },
     meta: {
-        menu: ['VehicleBasicData'],
+        menu: ['VehicleBasicData', 'VehicleNotes'],
     },
     children: [
         {
@@ -187,6 +187,15 @@ const vehicleCard = {
             },
             component: () => import('src/pages/Route/Vehicle/Card/VehicleBasicData.vue'),
         },
+        {
+            name: 'VehicleNotes',
+            path: 'notes',
+            meta: {
+                title: 'notes',
+                icon: 'vn:notes',
+            },
+            component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'),
+        }
     ],
 };
 
@@ -229,6 +238,7 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () => import('src/pages/Route/RouteList.vue'),
                         },
                         routeCard,
                     ],
@@ -277,6 +287,7 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () => import('src/pages/Route/RouteRoadmap.vue'),
                         },
                         roadmapCard,
                     ],
@@ -307,6 +318,8 @@ export default {
                                 title: 'list',
                                 icon: 'view_list',
                             },
+                            component: () =>
+                                import('src/pages/Route/Agency/AgencyList.vue'),
                         },
                         agencyCard,
                     ],
@@ -328,6 +341,8 @@ export default {
                                 title: 'vehicleList',
                                 icon: 'directions_car',
                             },
+                            component: () =>
+                                import('src/pages/Route/Vehicle/VehicleList.vue'),
                         },
                         vehicleCard,
                     ],
diff --git a/src/stores/__tests__/useArrayDataStore.spec.js b/src/stores/__tests__/useArrayDataStore.spec.js
new file mode 100644
index 000000000..79f17cf69
--- /dev/null
+++ b/src/stores/__tests__/useArrayDataStore.spec.js
@@ -0,0 +1,95 @@
+import { describe, expect, it, beforeEach } from 'vitest';
+import { setActivePinia, createPinia } from 'pinia';
+import { useArrayDataStore } from '../useArrayDataStore';
+
+describe('useArrayDataStore', () => {
+    beforeEach(() => {
+        setActivePinia(createPinia());
+    });
+
+    it('should get undefined for non-existent key', () => {
+        const store = useArrayDataStore();
+        expect(store.get('nonExistent')).toBeUndefined();
+    });
+
+    it('should set default state for new key', () => {
+        const store = useArrayDataStore();
+        store.set('test');
+        const state = store.get('test');
+
+        expect(state).toMatchObject({
+            filter: {},
+            userFilter: {},
+            userParams: {},
+            url: '',
+            limit: 20,
+            skip: 0,
+            order: '',
+            isLoading: false,
+            userParamsChanged: false,
+            exprBuilder: null,
+            searchUrl: 'params',
+            navigate: null,
+            page: 1,
+            mapKey: 'id',
+            oneRecord: false,
+        });
+    });
+
+    it('should clear state for specific key', () => {
+        const store = useArrayDataStore();
+        store.set('test');
+        store.clear('test');
+        expect(store.get('test')).toBeUndefined();
+    });
+
+    it('should reset all properties when no options provided', () => {
+        const store = useArrayDataStore();
+        store.set('test');
+        const state = store.get('test');
+        state.limit = 50;
+        state.page = 3;
+
+        store.reset('test');
+        expect(store.get('test').limit).toBe(20);
+        expect(store.get('test').page).toBe(1);
+    });
+
+    it('should reset only specified properties', () => {
+        const store = useArrayDataStore();
+        store.set('test');
+        const state = store.get('test');
+        state.limit = 50;
+        state.page = 3;
+        state.url = 'test-url';
+
+        store.reset('test', ['limit', 'page']);
+        expect(state.limit).toBe(20);
+        expect(state.page).toBe(1);
+        expect(state.url).toBe('test-url');
+    });
+
+    it('should reset nested properties', () => {
+        const store = useArrayDataStore();
+        store.set('test');
+        const state = store.get('test');
+        state.filter.skip = 10;
+
+        store.reset('test', ['filter.skip']);
+        expect(state.filter.skip).toBe(0);
+    });
+
+    it('should reset pagination properties', () => {
+        const store = useArrayDataStore();
+        store.set('test');
+        const state = store.get('test');
+        state.skip = 20;
+        state.filter.skip = 20;
+        state.page = 3;
+
+        store.resetPagination('test');
+        expect(state.skip).toBe(0);
+        expect(state.filter.skip).toBe(0);
+        expect(state.page).toBe(1);
+    });
+});
diff --git a/src/stores/__tests__/useNavigationStore.spec.js b/src/stores/__tests__/useNavigationStore.spec.js
index c5df6157e..120fa64cb 100644
--- a/src/stores/__tests__/useNavigationStore.spec.js
+++ b/src/stores/__tests__/useNavigationStore.spec.js
@@ -1,15 +1,17 @@
 import { setActivePinia, createPinia } from 'pinia';
-import { describe, beforeEach, afterEach, it, expect, vi, beforeAll } from 'vitest';
+import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest';
 import { useNavigationStore } from '../useNavigationStore';
-import axios from 'axios';
+import { default as axios } from 'axios';
 
 let store;
 
-vi.mock('src/router/modules', () => [
-    { name: 'Item', meta: {} },
-    { name: 'Shelving', meta: {} },
-    { name: 'Order', meta: {} },
-]);
+vi.mock('src/router/modules', () => ({
+    default: [
+        { name: 'Item', meta: {} },
+        { name: 'Shelving', meta: {} },
+        { name: 'Order', meta: {} },
+    ],
+}));
 
 vi.mock('src/filters', () => ({
     toLowerCamel: vi.fn((name) => name.toLowerCase()),
diff --git a/src/stores/useArrayDataStore.js b/src/stores/useArrayDataStore.js
index b3996d1e3..569ff1c7e 100644
--- a/src/stores/useArrayDataStore.js
+++ b/src/stores/useArrayDataStore.js
@@ -18,7 +18,6 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
         navigate: null,
         page: 1,
         mapKey: 'id',
-        keepData: false,
         oneRecord: false,
     };
 
diff --git a/src/stores/useDescriptorStore.js b/src/stores/useDescriptorStore.js
index a5b83a42e..be342b016 100644
--- a/src/stores/useDescriptorStore.js
+++ b/src/stores/useDescriptorStore.js
@@ -11,7 +11,7 @@ export const useDescriptorStore = defineStore('descriptorStore', () => {
         const files = import.meta.glob(`/src/**/*DescriptorProxy.vue`);
         const moduleParser = {
             account: 'user',
-            client: 'customer',
+            customer: 'client',
         };
         for (const file in files) {
             const name = file.split('/').at(-1).slice(0, -19).toLowerCase();
diff --git a/test/cypress/cypressParallel.sh b/test/cypress/cypressParallel.sh
deleted file mode 100644
index 8ef26bcde..000000000
--- a/test/cypress/cypressParallel.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-find 'test/cypress/integration' \
-    -mindepth 1 \
-    -maxdepth 1 \
-    -type d | \
-xargs -P "$1" -I {} sh -c '
-    echo "đź”· {}" &&
-    xvfb-run -a cypress run \
-        --headless \
-        --spec "{}" \
-        --quiet \
-        > /dev/null
-'
-wait
diff --git a/test/cypress/docker/cypressParallel.sh b/test/cypress/docker/cypressParallel.sh
new file mode 100644
index 000000000..8e253f1e3
--- /dev/null
+++ b/test/cypress/docker/cypressParallel.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+echo $2
+if [ -z "$2" ]; then
+    TEST_DIRS=$(find 'test/cypress/integration' -mindepth 1 -maxdepth 1 -type d)
+else
+    TEST_DIRS=$2
+fi
+
+echo $TEST_DIRS x$1
+
+echo "$TEST_DIRS" | xargs -P "$1" -I {} sh -c '
+    echo "đź”· {}" &&
+    xvfb-run -a cypress run \
+        --headless \
+        --spec "{}" \
+        --quiet \
+        > /dev/null
+'
+wait
diff --git a/test/cypress/docker/find/find-imports.js b/test/cypress/docker/find/find-imports.js
new file mode 100644
index 000000000..39c3ac3eb
--- /dev/null
+++ b/test/cypress/docker/find/find-imports.js
@@ -0,0 +1,52 @@
+import fs from 'fs';
+import { parse } from 'es-module-lexer';
+import { parse as vueParse } from '@vue/compiler-sfc';
+import glob from 'fast-glob';
+import { resolveImportPath, toRelative } from './resolve-import-path.js';
+
+const ROUTER_MODULES = 'src/router/modules/';
+const files = await glob(['src/**/*.{vue,js,ts}'], { absolute: true });
+const vueFiles = new Map();
+
+export async function findImports(targetFile, visited = new Set(), identation = '') {
+    if (visited.has(targetFile)) return []; // Avoid infinite loops
+    visited.add(targetFile);
+
+    const usageFiles = files
+        .filter((file) => {
+            let content = fs.readFileSync(file, 'utf8');
+            if (file.endsWith('.vue')) {
+                if (vueFiles.has(file)) {
+                    content = vueFiles.get(file);
+                } else {
+                    const { descriptor } = vueParse(content);
+                    content = descriptor?.scriptSetup?.content ?? '';
+                    vueFiles.set(file, content);
+                }
+            }
+            if (!content.trim()) return false;
+
+            return parse(content)[0].some((imp) => {
+                if (!imp?.n) return false;
+                return resolveImportPath(imp.n, targetFile) === targetFile;
+            });
+        })
+        .map((file) => toRelative(file));
+
+    let fullTree = [...usageFiles];
+    for (const file of usageFiles) {
+        if (file.startsWith(ROUTER_MODULES)) {
+            continue;
+        }
+        fullTree = [
+            ...fullTree,
+            ...(await findImports(file, visited, identation + '  ')),
+        ];
+    }
+
+    return getUniques(fullTree); // Remove duplicates
+}
+
+function getUniques(array) {
+    return Array.from(new Set(array));
+}
diff --git a/test/cypress/docker/find/find.js b/test/cypress/docker/find/find.js
new file mode 100644
index 000000000..b89aab230
--- /dev/null
+++ b/test/cypress/docker/find/find.js
@@ -0,0 +1,36 @@
+import { execSync } from 'child_process';
+import { findImports } from './find-imports.js';
+import { getModules } from './get-modules.js';
+const E2E_PATH = 'test/cypress/integration';
+const FINDED_PATHS = ['src', E2E_PATH];
+
+function getGitDiff(options) {
+    const TARGET_BRANCH = options[2] || 'dev';
+    const diff = execSync(`git diff --name-only origin/${TARGET_BRANCH}`, {
+        encoding: 'utf-8',
+    });
+    return diff.split('\n');
+}
+
+async function getChangedModules() {
+    let changedModules = new Set();
+    const changes = getGitDiff(process.argv);
+    for (const change of changes) {
+        if (!change) continue;
+        if (!FINDED_PATHS.some((prefix) => change.startsWith(prefix))) return '';
+        const changedArray = [
+            ...changedModules,
+            ...new Set(getModules(await findImports(change))),
+        ];
+        if (change.startsWith(E2E_PATH)) changedArray.push(change);
+        changedModules = new Set(changedArray);
+    }
+    return [...changedModules].join('\n');
+}
+
+getChangedModules()
+    .then((modules) => console.log(modules)) // is return
+    .catch((e) => {
+        console.error(e);
+        process.exit(1);
+    });
diff --git a/test/cypress/docker/find/get-modules.js b/test/cypress/docker/find/get-modules.js
new file mode 100644
index 000000000..4ac9ec8c4
--- /dev/null
+++ b/test/cypress/docker/find/get-modules.js
@@ -0,0 +1,13 @@
+export function getModules(files) {
+    const CYPRESS_PREFIX = 'test/cypress/integration/';
+    const CYPRESS_SUFIX = '/**/*.spec.js';
+    const modules = [];
+    for (const file of files) {
+        if (file.startsWith('src/page')) {
+            modules.push(
+                CYPRESS_PREFIX + file.split('/')[2].toLowerCase() + CYPRESS_SUFIX,
+            );
+        }
+    }
+    return modules;
+}
diff --git a/test/cypress/docker/find/resolve-import-path.js b/test/cypress/docker/find/resolve-import-path.js
new file mode 100644
index 000000000..38c225fd2
--- /dev/null
+++ b/test/cypress/docker/find/resolve-import-path.js
@@ -0,0 +1,34 @@
+import fs from 'fs';
+import path from 'path';
+const rootDir = process.cwd();
+const config = JSON.parse(fs.readFileSync('jsconfig.json', 'utf-8'));
+const { paths, baseUrl } = config.compilerOptions;
+
+function resolveImportPath(importPath, fileBase) {
+    if (!importPath) return null;
+    importPath = jsConfigPaths(importPath);
+    const fileDir = path.dirname(fileBase);
+    if (importPath.startsWith('.') || importPath.startsWith('/')) {
+        return path.relative(rootDir, path.resolve(fileDir, importPath));
+    }
+
+    return importPath;
+}
+function toRelative(file) {
+    return path.relative(rootDir, file);
+}
+
+function jsConfigPaths(importPath) {
+    for (const [aliasPattern, [target]] of Object.entries(paths)) {
+        const alias = aliasPattern.replace('/*', '');
+        const targetBase = target.replace('/*', '');
+
+        if (importPath.startsWith(alias)) {
+            const rest = importPath.slice(alias.length);
+            return path.resolve(baseUrl, targetBase + rest);
+        }
+    }
+    return importPath;
+}
+
+export { resolveImportPath, toRelative };
diff --git a/test/cypress/run.sh b/test/cypress/docker/run.sh
similarity index 89%
rename from test/cypress/run.sh
rename to test/cypress/docker/run.sh
index 0f8c59902..f62f57960 100755
--- a/test/cypress/run.sh
+++ b/test/cypress/docker/run.sh
@@ -35,6 +35,8 @@ docker build -f ./docs/Dockerfile.dev -t lilium-dev .
 # END IMAGES
 
 docker-compose -p e2e --project-directory . -f test/cypress/docker-compose.yml up -d
+files=$(node test/cypress/docker/find/find.js)
+echo $files
 
 docker run -it --rm \
     -v "$(pwd)":/app \
@@ -42,6 +44,6 @@ docker run -it --rm \
     -e CI \
     -e TZ \
     lilium-dev \
-    bash -c 'sh test/cypress/cypressParallel.sh 2'
+    bash -c "sh test/cypress/docker/cypressParallel.sh 2 '$files'"
 
 cleanup
diff --git a/test/cypress/summary.sh b/test/cypress/docker/summary.sh
similarity index 100%
rename from test/cypress/summary.sh
rename to test/cypress/docker/summary.sh
diff --git a/test/cypress/integration/account/accountDescriptorMenu.spec.js b/test/cypress/integration/account/accountDescriptorMenu.spec.js
index 67a7d8ef6..04fc57040 100644
--- a/test/cypress/integration/account/accountDescriptorMenu.spec.js
+++ b/test/cypress/integration/account/accountDescriptorMenu.spec.js
@@ -1,4 +1,4 @@
-describe('ClaimNotes', () => {
+describe('Account descriptor', () => {
     const descriptorOptions = '[data-cy="descriptor-more-opts-menu"] > .q-list';
     const url = '/#/account/1/summary';
 
@@ -7,6 +7,9 @@ describe('ClaimNotes', () => {
         cy.visit(url);
         cy.dataCy('descriptor-more-opts').click();
         cy.get(descriptorOptions)
+            .should('exist')
+            .should('be.visible')
+
             .find('.q-item')
             .its('length')
             .then((count) => {
diff --git a/test/cypress/integration/client/clientAddress.spec.js b/test/cypress/integration/customer/clientAddress.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientAddress.spec.js
rename to test/cypress/integration/customer/clientAddress.spec.js
diff --git a/test/cypress/integration/client/clientBalance.spec.js b/test/cypress/integration/customer/clientBalance.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientBalance.spec.js
rename to test/cypress/integration/customer/clientBalance.spec.js
diff --git a/test/cypress/integration/client/clientBasicData.spec.js b/test/cypress/integration/customer/clientBasicData.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientBasicData.spec.js
rename to test/cypress/integration/customer/clientBasicData.spec.js
diff --git a/test/cypress/integration/client/clientBillingData.spec.js b/test/cypress/integration/customer/clientBillingData.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientBillingData.spec.js
rename to test/cypress/integration/customer/clientBillingData.spec.js
diff --git a/test/cypress/integration/client/clientCredits.spec.js b/test/cypress/integration/customer/clientCredits.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientCredits.spec.js
rename to test/cypress/integration/customer/clientCredits.spec.js
diff --git a/test/cypress/integration/client/clientFiscalData.spec.js b/test/cypress/integration/customer/clientFiscalData.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientFiscalData.spec.js
rename to test/cypress/integration/customer/clientFiscalData.spec.js
diff --git a/test/cypress/integration/client/clientGreuges.spec.js b/test/cypress/integration/customer/clientGreuges.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientGreuges.spec.js
rename to test/cypress/integration/customer/clientGreuges.spec.js
diff --git a/test/cypress/integration/client/clientList.spec.js b/test/cypress/integration/customer/clientList.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientList.spec.js
rename to test/cypress/integration/customer/clientList.spec.js
diff --git a/test/cypress/integration/client/clientNotes.spec.js b/test/cypress/integration/customer/clientNotes.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientNotes.spec.js
rename to test/cypress/integration/customer/clientNotes.spec.js
diff --git a/test/cypress/integration/client/clientRecoveries.spec.js b/test/cypress/integration/customer/clientRecoveries.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientRecoveries.spec.js
rename to test/cypress/integration/customer/clientRecoveries.spec.js
diff --git a/test/cypress/integration/client/clientSms.spec.js b/test/cypress/integration/customer/clientSms.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientSms.spec.js
rename to test/cypress/integration/customer/clientSms.spec.js
diff --git a/test/cypress/integration/client/clientWebAccess.spec.js b/test/cypress/integration/customer/clientWebAccess.spec.js
similarity index 100%
rename from test/cypress/integration/client/clientWebAccess.spec.js
rename to test/cypress/integration/customer/clientWebAccess.spec.js
diff --git a/test/cypress/integration/client/credit-management/clientCreditContracts.spec.js b/test/cypress/integration/customer/credit-management/clientCreditContracts.spec.js
similarity index 100%
rename from test/cypress/integration/client/credit-management/clientCreditContracts.spec.js
rename to test/cypress/integration/customer/credit-management/clientCreditContracts.spec.js
diff --git a/test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js b/test/cypress/integration/customer/credit-management/clientCreditOpinion.spec.js
similarity index 100%
rename from test/cypress/integration/client/credit-management/clientCreditOpinion.spec.js
rename to test/cypress/integration/customer/credit-management/clientCreditOpinion.spec.js
diff --git a/test/cypress/integration/client/others/clientConsumption.spec.js b/test/cypress/integration/customer/others/clientConsumption.spec.js
similarity index 100%
rename from test/cypress/integration/client/others/clientConsumption.spec.js
rename to test/cypress/integration/customer/others/clientConsumption.spec.js
diff --git a/test/cypress/integration/client/others/clientContacts.spec.js b/test/cypress/integration/customer/others/clientContacts.spec.js
similarity index 100%
rename from test/cypress/integration/client/others/clientContacts.spec.js
rename to test/cypress/integration/customer/others/clientContacts.spec.js
diff --git a/test/cypress/integration/client/others/clientMandates.spec.js b/test/cypress/integration/customer/others/clientMandates.spec.js
similarity index 100%
rename from test/cypress/integration/client/others/clientMandates.spec.js
rename to test/cypress/integration/customer/others/clientMandates.spec.js
diff --git a/test/cypress/integration/client/others/clientSamples.spec.js b/test/cypress/integration/customer/others/clientSamples.spec.js
similarity index 100%
rename from test/cypress/integration/client/others/clientSamples.spec.js
rename to test/cypress/integration/customer/others/clientSamples.spec.js
diff --git a/test/cypress/integration/client/others/clientUnpaid.spec.js b/test/cypress/integration/customer/others/clientUnpaid.spec.js
similarity index 100%
rename from test/cypress/integration/client/others/clientUnpaid.spec.js
rename to test/cypress/integration/customer/others/clientUnpaid.spec.js
diff --git a/test/cypress/integration/client/others/clientWebPayments.spec.js b/test/cypress/integration/customer/others/clientWebPayments.spec.js
similarity index 100%
rename from test/cypress/integration/client/others/clientWebPayments.spec.js
rename to test/cypress/integration/customer/others/clientWebPayments.spec.js
diff --git a/test/cypress/integration/entry/commands.js b/test/cypress/integration/entry/commands.js
index 7c96a5440..4d4a8f980 100644
--- a/test/cypress/integration/entry/commands.js
+++ b/test/cypress/integration/entry/commands.js
@@ -1,6 +1,6 @@
 Cypress.Commands.add('selectTravel', (warehouse = '1') => {
     cy.get('i[data-cy="Travel_icon"]').click();
-    cy.get('input[data-cy="Warehouse Out_select"]').type(warehouse);
+    cy.selectOption('input[data-cy="Warehouse Out_select"]', warehouse);
     cy.get('div[role="listbox"] > div > div[role="option"]').eq(0).click();
     cy.get('button[data-cy="save-filter-travel-form"]').click();
     cy.get('tr').eq(1).click();
@@ -9,7 +9,6 @@ Cypress.Commands.add('selectTravel', (warehouse = '1') => {
 Cypress.Commands.add('deleteEntry', () => {
     cy.get('[data-cy="descriptor-more-opts"]').should('be.visible').click();
     cy.waitForElement('div[data-cy="delete-entry"]').click();
-    cy.url().should('include', 'list');
 });
 
 Cypress.Commands.add('createEntry', () => {
diff --git a/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js b/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js
index 554471008..8185866db 100644
--- a/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js
+++ b/test/cypress/integration/entry/entryCard/entryDescriptor.spec.js
@@ -28,12 +28,8 @@ describe('EntryDescriptor', () => {
                     cy.get('.q-notification__message')
                         .eq(2)
                         .should('have.text', 'Entry prices recalculated');
-
-                    cy.get('[data-cy="descriptor-more-opts"]').click();
                     cy.deleteEntry();
 
-                    cy.log(previousUrl);
-
                     cy.visit(previousUrl);
 
                     cy.waitForElement('[data-cy="entry-buys"]');
diff --git a/test/cypress/integration/entry/entryList.spec.js b/test/cypress/integration/entry/entryList.spec.js
index 990f74261..bad47615f 100644
--- a/test/cypress/integration/entry/entryList.spec.js
+++ b/test/cypress/integration/entry/entryList.spec.js
@@ -44,11 +44,12 @@ describe('EntryList', () => {
             },
         );
 
-        checkBadgeDate(
+        // fix on task https://redmine.verdnatura.es/issues/8638
+        /* checkBadgeDate(
             'td[data-col-field="landed"] > div .bg-info',
             (badgeDate, compareDate) => {
                 expect(badgeDate.getTime()).to.be.lessThan(compareDate.getTime());
             },
-        );
+        ); */
     });
 });
diff --git a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
index 7058e154c..9744486e0 100644
--- a/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInDescriptor.spec.js
@@ -40,7 +40,7 @@ describe('InvoiceInDescriptor', () => {
             cy.visit('/#/invoice-in/6/summary');
             cy.selectDescriptorOption(5);
 
-            cy.dataCy('SendEmailNotifiactionDialogInput_input').type(
+            cy.dataCy('SendEmailNotificationDialogInput_input').type(
                 '{selectall}jorgito@gmail.mx',
             );
             cy.clickConfirm();
diff --git a/test/cypress/integration/invoiceIn/invoiceInList.spec.js b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
index 6b5d28c70..7254e8909 100644
--- a/test/cypress/integration/invoiceIn/invoiceInList.spec.js
+++ b/test/cypress/integration/invoiceIn/invoiceInList.spec.js
@@ -41,12 +41,12 @@ describe('InvoiceInList', () => {
         cy.fillInForm({ ...mock }, { attr: 'data-cy' });
         cy.dataCy('FormModelPopup_save').click();
         cy.intercept('GET', /\/api\/InvoiceIns\/\d+\/getTotals$/).as('invoice');
-        cy.wait('@invoice').then(() =>
+        cy.wait('@invoice').then(() => {
             cy.validateDescriptor({
                 title: mockInvoiceRef,
                 listBox: { 0: '11/16/2001', 3: 'The farmer' },
-            }),
-        );
-        cy.get('[data-cy="vnLvCompany"]').should('contain.text', 'ORN');
+            });
+            cy.dataCy('invoiceInBasicDataCompanyFk').should('have.value', 'ORN');
+        });
     });
 });
diff --git a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
index 63e828f55..49eed32c7 100644
--- a/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
+++ b/test/cypress/integration/invoiceOut/invoiceOutSummary.spec.js
@@ -37,7 +37,7 @@ describe('InvoiceOut summary', () => {
         });
     });
 
-    it('should transfer the invoice ', () => {
+    it.skip('should transfer the invoice ', () => {
         cy.typeSearchbar('T1111111{enter}');
         cy.dataCy('descriptor-more-opts').click();
         cy.get(selectMenuOption(1)).click();
@@ -50,7 +50,7 @@ describe('InvoiceOut summary', () => {
         cy.dataCy('descriptor-more-opts').click();
         cy.get(selectMenuOption(3)).click();
         cy.dataCy('InvoiceOutDescriptorMenuSendPdfOption').click();
-        cy.dataCy('SendEmailNotifiactionDialogInput').should('be.visible');
+        cy.dataCy('SendEmailNotificationDialogInput').should('be.visible');
         cy.get(confirmSend).click();
         cy.checkNotification('Notification sent');
     });
@@ -59,7 +59,7 @@ describe('InvoiceOut summary', () => {
         cy.dataCy('descriptor-more-opts').click();
         cy.get(selectMenuOption(3)).click();
         cy.dataCy('InvoiceOutDescriptorMenuSendCsvOption').click();
-        cy.dataCy('SendEmailNotifiactionDialogInput').should('be.visible');
+        cy.dataCy('SendEmailNotificationDialogInput').should('be.visible');
         cy.get(confirmSend).click();
         cy.checkNotification('Notification sent');
     });
diff --git a/test/cypress/integration/item/itemSummary.spec.js b/test/cypress/integration/item/itemSummary.spec.js
index ad8267ecf..8d67c8e3c 100644
--- a/test/cypress/integration/item/itemSummary.spec.js
+++ b/test/cypress/integration/item/itemSummary.spec.js
@@ -19,6 +19,7 @@ describe('Item summary', () => {
         cy.get('.q-menu > .q-list > :nth-child(1) > .q-item__section').click();
         cy.dataCy('regularizeStockInput').type('10');
         cy.dataCy('Warehouse_select').type('Warehouse One{enter}');
+        cy.dataCy('FormModelPopup_save').click();
         cy.checkNotification('Data created');
     });
 });
diff --git a/test/cypress/integration/outLogin/login.spec.js b/test/cypress/integration/login/login.spec.js
similarity index 100%
rename from test/cypress/integration/outLogin/login.spec.js
rename to test/cypress/integration/login/login.spec.js
diff --git a/test/cypress/integration/outLogin/logout.spec.js b/test/cypress/integration/login/logout.spec.js
similarity index 100%
rename from test/cypress/integration/outLogin/logout.spec.js
rename to test/cypress/integration/login/logout.spec.js
diff --git a/test/cypress/integration/outLogin/recoverPassword.spec.js b/test/cypress/integration/login/recoverPassword.spec.js
similarity index 100%
rename from test/cypress/integration/outLogin/recoverPassword.spec.js
rename to test/cypress/integration/login/recoverPassword.spec.js
diff --git a/test/cypress/integration/outLogin/twoFactor.spec.js b/test/cypress/integration/login/twoFactor.spec.js
similarity index 100%
rename from test/cypress/integration/outLogin/twoFactor.spec.js
rename to test/cypress/integration/login/twoFactor.spec.js
diff --git a/test/cypress/integration/Order/orderCatalog.spec.js b/test/cypress/integration/order/orderCatalog.spec.js
similarity index 100%
rename from test/cypress/integration/Order/orderCatalog.spec.js
rename to test/cypress/integration/order/orderCatalog.spec.js
diff --git a/test/cypress/integration/order/orderList.spec.js b/test/cypress/integration/order/orderList.spec.js
index 34cd2bffc..ee011ea05 100644
--- a/test/cypress/integration/order/orderList.spec.js
+++ b/test/cypress/integration/order/orderList.spec.js
@@ -30,9 +30,11 @@ describe('OrderList', () => {
         cy.url().should('include', `/order`);
     });
 
-    it.skip('filter list and create order', () => {
+    it('filter list and create order', () => {
         cy.dataCy('Customer ID_input').type('1101{enter}');
+        cy.intercept('GET', /\/api\/Clients/).as('clientFilter');
         cy.dataCy('vnTableCreateBtn').click();
+        cy.wait('@clientFilter');
         cy.dataCy('landedDate').find('input').type('06/01/2001');
         cy.selectOption(agencyCreateSelect, 1);
 
diff --git a/test/cypress/integration/route/agency/agencyModes.spec.js b/test/cypress/integration/route/agency/agencyModes.spec.js
new file mode 100644
index 000000000..3f5784997
--- /dev/null
+++ b/test/cypress/integration/route/agency/agencyModes.spec.js
@@ -0,0 +1,15 @@
+describe('Agency modes', () => {
+    const name = 'inhouse pickup';
+
+    beforeEach(() => {
+        cy.viewport(1920, 1080);
+        cy.login('developer');
+        cy.visit(`/#/route/agency/1/modes`);
+    });
+
+    it('should display the agency modes page', () => {
+        cy.get('.flex > .title').should('have.text', name);
+        cy.get('.flex > .q-chip > .q-chip__content').should('have.text', 'ID: 1');
+        cy.get('.list-items > :nth-child(1) > .value').should('have.text', name);
+    });
+});
diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js
index acf82bd95..d77584c04 100644
--- a/test/cypress/integration/route/routeAutonomous.spec.js
+++ b/test/cypress/integration/route/routeAutonomous.spec.js
@@ -1,4 +1,4 @@
-describe('RouteAutonomous', () => {
+describe.skip('RouteAutonomous', () => {
     const getLinkSelector = (colField) =>
         `tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`;
 
@@ -49,12 +49,12 @@ describe('RouteAutonomous', () => {
         cy.get(selectors.firstRowCheckbox).click();
         cy.get(selectors.createInvoiceBtn).click();
         cy.dataCy(selectors.reference).type(data.reference);
+        cy.dataCy('attachFile').click();
         cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
             force: true,
         });
-        cy.dataCy(selectors.saveFormBtn).click();
+        cy.dataCy(selectors.saveFormBtn).should('be.visible').click();
         cy.checkNotification(dataSaved);
-        cy.typeSearchbar('{enter}');
     });
 
     it('Should display the total price of the selected rows', () => {
diff --git a/test/cypress/integration/route/routeExtendedList.spec.js b/test/cypress/integration/route/routeExtendedList.spec.js
index a183c08cb..e6c873d5e 100644
--- a/test/cypress/integration/route/routeExtendedList.spec.js
+++ b/test/cypress/integration/route/routeExtendedList.spec.js
@@ -53,17 +53,20 @@ describe('Route extended list', () => {
     function fillField(selector, type, value) {
         switch (type) {
             case 'select':
-                cy.get(selector).should('be.visible').click();
-                cy.dataCy('null_select').clear().type(value);
+                cy.get(selector).should('be.visible').click().clear().type(value);
                 cy.get('.q-item').contains(value).click();
                 break;
             case 'input':
-                cy.get(selector).should('be.visible').click();
-                cy.dataCy('null_input').clear().type(`${value}`);
+                cy.get(selector)
+                    .should('be.visible')
+                    .click()
+                    .type(`{selectall}{backspace}${value}`);
                 break;
             case 'date':
-                cy.get(selector).should('be.visible').click();
-                cy.dataCy('null_inputDate').clear().type(`${value}`);
+                cy.get(selector)
+                    .should('be.visible')
+                    .click()
+                    .type(`{selectall}{backspace}${value}`);
                 break;
             case 'checkbox':
                 cy.get(selector).should('be.visible').click().click();
@@ -103,8 +106,8 @@ describe('Route extended list', () => {
         cy.fillInForm(data);
 
         cy.dataCy(selectors.saveFormBtn).click();
-        cy.checkNotification(dataCreated);
         cy.url().should('include', '/summary');
+        cy.checkNotification(dataCreated);
     });
 
     it('Should reset changed values when click reset button', () => {
@@ -140,7 +143,7 @@ describe('Route extended list', () => {
         const downloadsFolder = Cypress.config('downloadsFolder');
         cy.get(selectors.lastRowSelectCheckBox).click();
         cy.get(selectors.downloadBtn).click();
-        cy.wait(5000);
+        cy.wait(3000);
 
         const fileName = 'download.zip';
         cy.readFile(`${downloadsFolder}/${fileName}`).should('exist');
@@ -177,7 +180,7 @@ describe('Route extended list', () => {
                 const [month, day, year] = value.split('/');
                 value = `${day}/${month}/${year}`;
             }
-            cy.validateContent(selector, value);
+            cy.get(selector).should('contain', value);
         });
     });
 
diff --git a/test/cypress/integration/route/vehicle/vehicleNotes.spec.js b/test/cypress/integration/route/vehicle/vehicleNotes.spec.js
new file mode 100644
index 000000000..cd92cc4af
--- /dev/null
+++ b/test/cypress/integration/route/vehicle/vehicleNotes.spec.js
@@ -0,0 +1,28 @@
+describe('Vehicle Notes', () => {
+    const selectors = {
+        addNoteInput: 'Add note here..._input',
+        saveNoteBtn: 'saveNote',
+        deleteNoteBtn: 'notesRemoveNoteBtn',
+        noteCard: '.column.full-width > :nth-child(1) > .q-card__section--vert',
+    };
+
+    const noteText = 'Golpe parachoques trasero';
+    const newNoteText = 'probando';
+
+    beforeEach(() => {
+        cy.viewport(1920, 1080);
+        cy.login('developer');
+        cy.visit(`/#/route/vehicle/1/notes`);
+    });
+
+    it('Should add new note', () => {
+        cy.dataCy(selectors.addNoteInput).should('be.visible').type(newNoteText);
+        cy.dataCy(selectors.saveNoteBtn).click();
+        cy.validateContent(selectors.noteCard, newNoteText);
+    });
+
+    it('Should delete note', () => {
+        cy.dataCy(selectors.deleteNoteBtn).first().should('be.visible').click();
+        cy.get(selectors.noteCard).first().should('have.text', noteText);
+    });
+});
diff --git a/test/cypress/integration/Supplier/SupplierBalance.spec.js b/test/cypress/integration/supplier/SupplierBalance.spec.js
similarity index 100%
rename from test/cypress/integration/Supplier/SupplierBalance.spec.js
rename to test/cypress/integration/supplier/SupplierBalance.spec.js
diff --git a/test/cypress/integration/ticket/ticketBasicData.spec.js b/test/cypress/integration/ticket/ticketBasicData.spec.js
new file mode 100644
index 000000000..443e9569b
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketBasicData.spec.js
@@ -0,0 +1,46 @@
+/// <reference types="cypress" />
+describe('TicketBasicData', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/basic-data');
+    });
+
+    it('Should redirect to customer basic data', () => {
+        cy.get('.q-page').should('be.visible');
+        cy.get(':nth-child(2) > div > .text-primary').click();
+        cy.dataCy('Address_select').click();
+        cy.get('.q-btn-group ').find('.q-btn__content > .q-icon').click();
+        cy.get(
+            '[data-cy="CustomerBasicData-menu-item"] > .q-item__section--main',
+        ).click();
+        cy.url().should('include', '/customer/1104/basic-data');
+    });
+    it.only('stepper', () => {
+        cy.get('.q-stepper__tab--active').should('have.class', 'q-stepper__tab--active');
+
+        cy.get('.q-stepper__nav > .q-btn--standard').click();
+        cy.get('.q-stepper__tab--done').should('have.class', 'q-stepper__tab--done');
+        cy.get('.q-stepper__tab--active').should('have.class', 'q-stepper__tab--active');
+        cy.get('tr:nth-child(1)>:nth-child(1)>span').should('have.class', 'link').click();
+        cy.dataCy('ItemDescriptor').should('exist');
+
+        cy.get('.q-drawer__content > :nth-child(1)').each(() => {
+            cy.get('span').should('contain.text', 'Price: €');
+            cy.get('span').should('contain.text', 'New price: €');
+            cy.get('span').should('contain.text', 'Difference: €');
+        });
+        cy.get(
+            ':nth-child(3) > .q-radio > .q-radio__inner > .q-radio__bg > .q-radio__check',
+        ).should('have.class', 'q-radio__check');
+        cy.get(
+            '.q-stepper__step-inner > .q-drawer-container > .q-drawer > .q-drawer__content',
+        ).click();
+        cy.get(':nth-child(2) > :nth-child(1) > .text-weight-bold').click();
+        cy.get(':nth-child(3) > .q-radio > .q-radio__inner').should(
+            'have.class',
+            'q-radio__inner--truthy',
+        );
+        cy.get('.q-drawer__content > :nth-child(2)').click();
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketComponents.spec.js b/test/cypress/integration/ticket/ticketComponents.spec.js
new file mode 100644
index 000000000..23dbf8bcd
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketComponents.spec.js
@@ -0,0 +1,30 @@
+/// <reference types="cypress" />
+
+describe('TicketComponents', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/1/components');
+    });
+    it('Should load layout', () => {
+        cy.get('.q-page').should('be.visible');
+        cy.validateScrollContent([
+            { row: 2, col: 2, text: 'Base to commission: €799.20' },
+            { row: 2, col: 3, text: 'Total without VAT: €807.20' },
+            { row: 3, col: 2, text: 'valor de compra: €425.000' },
+            { row: 3, col: 4, text: 'maná auto: €7.998' },
+            { row: 4, col: 2, text: 'Price: €5.00' },
+            { row: 4, col: 3, text: 'Bonus: €1.00' },
+            { row: 4, col: 5, text: 'Packages: 6' },
+            { row: 4, col: 4, text: 'Zone: Zone pickup A ' },
+            { row: 5, col: 2, text: 'Total price: €16.00' },
+        ]);
+        cy.get(':nth-child(4) > .link').click();
+
+        cy.dataCy('ZoneDescriptor').should('exist');
+        cy.getRowCol('total').should('have.text', '€250.000€247.000€4.970');
+        cy.getRowCol('import').should('have.text', '€50.000€49.400€0.994');
+        cy.getRowCol('components').should('have.text', 'valor de compramargenmaná auto');
+        cy.getRowCol('serie').should('have.text', 'costeempresacartera_comercial');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketList.spec.js b/test/cypress/integration/ticket/ticketList.spec.js
index 5613a5854..e18025319 100644
--- a/test/cypress/integration/ticket/ticketList.spec.js
+++ b/test/cypress/integration/ticket/ticketList.spec.js
@@ -1,7 +1,5 @@
 /// <reference types="cypress" />
 describe('TicketList', () => {
-    const firstRow = 'tbody.q-virtual-scroll__content tr:nth-child(1)';
-
     beforeEach(() => {
         cy.login('developer');
         cy.viewport(1920, 1080);
@@ -11,7 +9,7 @@ describe('TicketList', () => {
     const searchResults = (search) => {
         if (search) cy.typeSearchbar().type(search);
         cy.dataCy('vn-searchbar').find('input').type('{enter}');
-        cy.get(firstRow).should('exist');
+        cy.getRow().should('exist');
     };
 
     it('should search results', () => {
@@ -24,13 +22,13 @@ describe('TicketList', () => {
         cy.window().then((win) => {
             cy.stub(win, 'open').as('windowOpen');
         });
-        cy.get(firstRow).should('be.visible').find('.q-btn:first').click();
+        cy.getRow().should('be.visible').find('.q-btn:first').click();
         cy.get('@windowOpen').should('be.calledWithMatch', /\/ticket\/\d+\/sale/);
     });
 
     it('should open ticket summary', () => {
         searchResults();
-        cy.get(firstRow).find('.q-btn:last').click();
+        cy.getRow().find('.q-btn:last').click();
         cy.get('.summaryHeader').should('exist');
         cy.get('.summaryBody').should('exist');
     });
@@ -43,8 +41,9 @@ describe('TicketList', () => {
         cy.dataCy('Customer ID_input').clear('1');
         cy.dataCy('Customer ID_input').type('1101{enter}');
 
-        cy.get('[data-cy="vnTableCreateBtn"] > .q-btn__content > .q-icon').click();
-        cy.waitSpinner();
+        cy.intercept('GET', /\/api\/Clients\?filter/).as('clientFilter');
+        cy.vnTableCreateBtn();
+        cy.wait('@clientFilter');
         cy.dataCy('Customer_select').should('have.value', 'Bruce Wayne');
         cy.dataCy('Address_select').click();
 
@@ -52,8 +51,7 @@ describe('TicketList', () => {
         cy.dataCy('Address_select').should('have.value', 'Bruce Wayne');
     });
     it('Client list create new ticket', () => {
-        cy.dataCy('vnTableCreateBtn').should('exist');
-        cy.dataCy('vnTableCreateBtn').click();
+        cy.vnTableCreateBtn();
         const data = {
             Customer: { val: 1, type: 'select' },
             Warehouse: { val: 'Warehouse One', type: 'select' },
diff --git a/test/cypress/integration/ticket/ticketNotes.spec.js b/test/cypress/integration/ticket/ticketNotes.spec.js
index 5b44f9e1f..df1ff9137 100644
--- a/test/cypress/integration/ticket/ticketNotes.spec.js
+++ b/test/cypress/integration/ticket/ticketNotes.spec.js
@@ -19,7 +19,7 @@ describe('TicketNotes', () => {
         cy.checkNotification('Data saved');
         cy.dataCy('ticketNotesRemoveNoteBtn').should('exist');
         cy.dataCy('ticketNotesRemoveNoteBtn').click();
-        cy.dataCy('VnConfirm_confirm').click();
+        cy.confirmVnConfirm();
         cy.checkNotification('Data saved');
     });
 });
diff --git a/test/cypress/integration/ticket/ticketPackage.spec.js b/test/cypress/integration/ticket/ticketPackage.spec.js
new file mode 100644
index 000000000..992efd53b
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketPackage.spec.js
@@ -0,0 +1,21 @@
+/// <reference types="cypress" />
+describe('TicketPackages', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/package');
+    });
+
+    it('Should load layout', () => {
+        cy.get('.q-page').should('be.visible');
+        cy.get('.vn-row > .q-btn > .q-btn__content > .q-icon').click();
+        cy.dataCy('Package_select').click();
+        cy.get('.q-menu :nth-child(1) >.q-item__section').click();
+        cy.dataCy('Quantity_input').clear().type('5');
+        cy.saveCrudModel();
+        cy.checkNotification('Data saved');
+        cy.get('.q-mb-md > .text-primary').click();
+        cy.confirmVnConfirm();
+        cy.checkNotification('Data saved');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketPictures.spec.js b/test/cypress/integration/ticket/ticketPictures.spec.js
new file mode 100644
index 000000000..1165b54bf
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketPictures.spec.js
@@ -0,0 +1,18 @@
+/// <reference types="cypress" />
+describe('TicketPictures', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/picture');
+    });
+    it('Should load layout', () => {
+        cy.get(':nth-child(1) > .q-card > .content').should('be.visible');
+        cy.get('.content > .link').should('be.visible').click();
+        cy.dataCy('ItemDescriptor').should('exist');
+        cy.dataCy('vnLvColor:');
+        cy.dataCy('vnLvColor:');
+        cy.dataCy('vnLvTallos:');
+        cy.get('.q-mt-md').should('be.visible');
+        cy.get(':nth-child(1) > .q-card > .img-wrapper').should('be.visible');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketRequest.spec.js b/test/cypress/integration/ticket/ticketRequest.spec.js
index b9dc509ef..3b237826e 100644
--- a/test/cypress/integration/ticket/ticketRequest.spec.js
+++ b/test/cypress/integration/ticket/ticketRequest.spec.js
@@ -7,8 +7,7 @@ describe('TicketRequest', () => {
     });
 
     it('Creates a new request', () => {
-        cy.dataCy('vnTableCreateBtn').should('exist');
-        cy.dataCy('vnTableCreateBtn').click();
+        cy.vnTableCreateBtn();
         const data = {
             Description: { val: 'Purchase description' },
             Atender: { val: 'buyerNick', type: 'select' },
diff --git a/test/cypress/integration/ticket/ticketSale.spec.js b/test/cypress/integration/ticket/ticketSale.spec.js
index 6d84f214c..f433f0d11 100644
--- a/test/cypress/integration/ticket/ticketSale.spec.js
+++ b/test/cypress/integration/ticket/ticketSale.spec.js
@@ -2,9 +2,9 @@
 const firstRow = 'tbody > :nth-child(1)';
 
 describe('TicketSale', () => {
-    describe('Ticket  #23', () => {
+    describe('#23', () => {
         beforeEach(() => {
-            cy.login('developer');
+            cy.login('salesBoss');
             cy.viewport(1920, 1080);
             cy.visit('/#/ticket/23/sale');
         });
@@ -16,10 +16,12 @@ describe('TicketSale', () => {
             cy.waitForElement('[data-cy="ticketEditManaProxy"]');
             cy.dataCy('ticketEditManaProxy').should('exist');
             cy.waitForElement('[data-cy="Price_input"]');
-            cy.dataCy('Price_input').clear();
-            cy.dataCy('Price_input').type(price);
+            cy.dataCy('Price_input').clear().type(price);
+            cy.intercept('POST', /\/api\/Sales\/\d+\/updatePrice/).as('updatePrice');
+
             cy.dataCy('saveManaBtn').click();
             handleVnConfirm();
+            cy.wait('@updatePrice').its('response.statusCode').should('eq', 200);
 
             cy.get('[data-col-field="price"]')
                 .find('.q-btn > .q-btn__content')
@@ -32,10 +34,14 @@ describe('TicketSale', () => {
             cy.waitForElement('[data-cy="ticketEditManaProxy"]');
             cy.dataCy('ticketEditManaProxy').should('exist');
             cy.waitForElement('[data-cy="Disc_input"]');
-            cy.dataCy('Disc_input').clear();
-            cy.dataCy('Disc_input').type(discount);
+            cy.dataCy('Disc_input').clear().type(discount);
+            cy.intercept('POST', /\/api\/Tickets\/\d+\/updateDiscount/).as(
+                'updateDiscount',
+            );
+
             cy.dataCy('saveManaBtn').click();
             handleVnConfirm();
+            cy.wait('@updateDiscount').its('response.statusCode').should('eq', 204);
 
             cy.get('[data-col-field="discount"]')
                 .find('.q-btn > .q-btn__content')
@@ -46,6 +52,8 @@ describe('TicketSale', () => {
             const concept = Math.floor(Math.random() * 100) + 1;
             cy.waitForElement(firstRow);
             cy.get('[data-col-field="item"]').click();
+            cy.intercept('POST', '**/api').as('postRequest');
+
             cy.get('.q-menu')
                 .find('[data-cy="undefined_input"]')
                 .type(concept)
@@ -58,6 +66,8 @@ describe('TicketSale', () => {
             const quantity = Math.floor(Math.random() * 100) + 1;
             cy.waitForElement(firstRow);
             cy.dataCy('ticketSaleQuantityInput').find('input').clear();
+            cy.intercept('POST', '**/api').as('postRequest');
+
             cy.dataCy('ticketSaleQuantityInput')
                 .find('input')
                 .type(quantity)
@@ -71,7 +81,7 @@ describe('TicketSale', () => {
                 .should('have.value', `${quantity}`);
         });
     });
-    describe('Ticket to add claim #24', () => {
+    describe('#24 add claim', () => {
         beforeEach(() => {
             cy.login('developer');
             cy.viewport(1920, 1080);
@@ -82,15 +92,15 @@ describe('TicketSale', () => {
             selectFirstRow();
             cy.dataCy('ticketSaleMoreActionsDropdown').click();
             cy.dataCy('createClaimItem').click();
-            cy.dataCy('VnConfirm_confirm').click();
+            cy.confirmVnConfirm();
             cy.url().should('contain', 'claim/');
             // Delete created claim to avoid cluttering the database
             cy.dataCy('descriptor-more-opts').click();
             cy.dataCy('deleteClaim').click();
-            cy.dataCy('VnConfirm_confirm').click();
+            cy.confirmVnConfirm();
         });
     });
-    describe('Free ticket #31', () => {
+    describe('#31 free ticket', () => {
         beforeEach(() => {
             cy.login('developer');
             cy.viewport(1920, 1080);
@@ -129,7 +139,9 @@ describe('TicketSale', () => {
             cy.dataCy('ticketSaleMoreActionsDropdown').should('be.disabled');
         });
 
-        it('should update discount when "Update discount" is clicked', () => {
+        it.only('should update discount when "Update discount" is clicked', () => {
+            const discount = Number((Math.random() * 99 + 1).toFixed(2));
+
             selectFirstRow();
             cy.dataCy('ticketSaleMoreActionsDropdown').click();
             cy.waitForElement('[data-cy="updateDiscountItem"]');
@@ -137,9 +149,13 @@ describe('TicketSale', () => {
             cy.dataCy('updateDiscountItem').click();
             cy.waitForElement('[data-cy="ticketSaleDiscountInput"]');
             cy.dataCy('ticketSaleDiscountInput').find('input').focus();
-            cy.dataCy('ticketSaleDiscountInput').find('input').type('10');
+            cy.intercept('POST', /\/api\/Tickets\/\d+\/updateDiscount/).as(
+                'updateDiscount',
+            );
+            cy.dataCy('ticketSaleDiscountInput').find('input').type(discount);
+
             cy.dataCy('saveManaBtn').click();
-            cy.waitForElement('.q-notification__message');
+            cy.wait('@updateDiscount').its('response.statusCode').should('eq', 204);
             cy.checkNotification('Data saved');
             cy.dataCy('ticketSaleMoreActionsDropdown').should('be.disabled');
         });
@@ -148,7 +164,7 @@ describe('TicketSale', () => {
             selectFirstRow();
             cy.dataCy('ticketSaleMoreActionsDropdown').click();
             cy.dataCy('createClaimItem').click();
-            cy.dataCy('VnConfirm_confirm').click();
+            cy.confirmVnConfirm();
             cy.checkNotification('Future ticket date not allowed');
         });
 
@@ -173,7 +189,7 @@ describe('TicketSale', () => {
             cy.url().should('match', /\/ticket\/31\/log/);
         });
     });
-    describe('Ticket to transfer #32', () => {
+    describe('#32 transfer', () => {
         beforeEach(() => {
             cy.login('developer');
             cy.viewport(1920, 1080);
@@ -194,9 +210,7 @@ function selectFirstRow() {
     cy.get(firstRow).find('.q-checkbox__inner').click();
 }
 function handleVnConfirm() {
-    cy.get('[data-cy="VnConfirm_confirm"]').click();
-    cy.waitForElement('.q-notification__message');
+    cy.confirmVnConfirm();
 
-    cy.get('.q-notification__message').should('be.visible');
     cy.checkNotification('Data saved');
 }
diff --git a/test/cypress/integration/ticket/ticketSaleTracking.spec.js b/test/cypress/integration/ticket/ticketSaleTracking.spec.js
new file mode 100644
index 000000000..9ee9f8824
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketSaleTracking.spec.js
@@ -0,0 +1,53 @@
+/// <reference types="cypress" />
+function uncheckedSVG(className, state) {
+    cy.get(`${className} .q-checkbox__svg`).should(
+        state === 'checked' ? 'not.have.attr' : 'have.attr',
+        'fill',
+        'none',
+    );
+}
+function checkedSVG(className, state) {
+    cy.get(`${className} .q-checkbox__svg> .q-checkbox__truthy`).should(
+        state === 'checked' ? 'not.have.attr' : 'have.attr',
+        'fill',
+        'none',
+    );
+}
+
+function clickIconAndCloseDialog(n) {
+    cy.get(
+        `:nth-child(1) > :nth-child(6) > :nth-child(${n}) > .q-btn__content > .q-icon`,
+    ).click();
+}
+
+describe('TicketSaleTracking', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/1/sale-tracking');
+    });
+
+    it('Should load layout', () => {
+        cy.get('.q-page').should('be.visible');
+        // Check checkbox states
+        uncheckedSVG('.pink', 'checked');
+        uncheckedSVG('.cyan', 'checked');
+        uncheckedSVG('.warning', 'checked');
+        uncheckedSVG('.info', 'checked');
+        checkedSVG('.yellow', 'unchecked');
+
+        cy.get('.q-page').click();
+        cy.get(
+            ':nth-child(1) > :nth-child(6) > :nth-child(2) > .q-btn__content > .q-icon',
+        ).click();
+        cy.get('body').type('{esc}');
+        cy.get(
+            ':nth-child(1) > :nth-child(6) > :nth-child(1) > .q-btn__content > .q-icon',
+        ).click();
+        cy.get(
+            '.q-dialog__inner > .q-table__container   :nth-child(1) > :nth-child(2) .link.q-btn',
+        ).click();
+
+        cy.dataCy('WorkerDescriptor').should('exist');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketService.spec.js b/test/cypress/integration/ticket/ticketService.spec.js
new file mode 100644
index 000000000..5bf8e2aab
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketService.spec.js
@@ -0,0 +1,23 @@
+/// <reference types="cypress" />
+describe('TicketService', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/service');
+    });
+
+    it('Add and remove service', () => {
+        cy.get('.q-page').should('be.visible');
+        cy.addBtnClick();
+        cy.dataCy('Description_icon').click();
+        cy.dataCy('Description_input').clear().type('test');
+        cy.saveFormModel();
+        cy.selectOption('[data-cy="Description_select"]', 'test');
+
+        cy.dataCy('Quantity_input').clear().type('1');
+        cy.dataCy('Price_input').clear().type('2');
+        cy.saveCrudModel();
+        cy.checkNotification('Data saved');
+        cy.get(':nth-child(5) > .q-icon').click();
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketSms.spec.js b/test/cypress/integration/ticket/ticketSms.spec.js
new file mode 100644
index 000000000..feafb2157
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketSms.spec.js
@@ -0,0 +1,22 @@
+/// <reference types="cypress" />
+describe('TicketSms', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/32/sms');
+    });
+
+    it('Should load layout', () => {
+        cy.get('.q-page').should('be.visible');
+        cy.get('.q-infinite-scroll > :nth-child(1)').should(
+            'contain.text',
+            '0004 444444444Lorem ipsum dolor sit amet, consectetur adipiscing elit.2001-01-01 00:00:00OK',
+        );
+        cy.get(
+            ':nth-child(1) > .q-item > .q-item__section--top > .column > .q-avatar',
+        ).should('be.visible');
+        cy.get(
+            ':nth-child(1) > .q-item > .q-item__section--side.justify-center > .center > .q-chip > .q-chip__content',
+        ).should('have.class', 'q-chip__content');
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketTracking.spec.js b/test/cypress/integration/ticket/ticketTracking.spec.js
new file mode 100644
index 000000000..f351ee0a1
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketTracking.spec.js
@@ -0,0 +1,25 @@
+/// <reference types="cypress" />
+describe('Ticket tracking', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/31/tracking');
+    });
+
+    it('Add new tracking', () => {
+        cy.get('.q-page').should('be.visible');
+
+        cy.getRowCol('worker').find('span').should('have.class', 'link').click();
+        cy.dataCy('WorkerDescriptor').should('exist');
+        cy.vnTableCreateBtn();
+        cy.selectOption('.q-field--float [data-cy="State_select"]', 'OK').click();
+        cy.saveFormModel();
+        cy.get(
+            ':last-child > [data-col-field="state"] > [data-cy="vnTableCell_state"]',
+        ).should('have.text', 'OK');
+        cy.get(':last-child > [data-col-field="worker"]').should(
+            'have.text',
+            'developer ',
+        );
+    });
+});
diff --git a/test/cypress/integration/ticket/ticketVolume.spec.js b/test/cypress/integration/ticket/ticketVolume.spec.js
new file mode 100644
index 000000000..59ff6dcb2
--- /dev/null
+++ b/test/cypress/integration/ticket/ticketVolume.spec.js
@@ -0,0 +1,27 @@
+/// <reference types="cypress" />
+function checkRightLabel(index, value, tag = 'Volume: ') {
+    cy.get(`.q-scrollarea__content > :nth-child(${index}) > :nth-child(2) > span`)
+        .should('be.visible')
+        .should('have.text', `${tag}${value}`);
+}
+describe('TicketVolume', () => {
+    beforeEach(() => {
+        cy.login('developer');
+        cy.viewport(1920, 1080);
+        cy.visit('/#/ticket/1/volume');
+    });
+
+    it('Check right panel info', () => {
+        cy.get('.q-page').should('be.visible');
+        checkRightLabel(2, '0.028');
+        checkRightLabel(3, '0.014');
+        checkRightLabel(4, '1.526');
+    });
+    it('Descriptors', () => {
+        cy.get(':nth-child(1) > [data-col-field="itemFk"]')
+            .find('span')
+            .should('have.class', 'link')
+            .click();
+        cy.dataCy('ItemDescriptor').should('exist');
+    });
+});
diff --git a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js b/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
deleted file mode 100644
index 053902f35..000000000
--- a/test/cypress/integration/vnComponent/VnAccountNumber.spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-describe('VnAccountNumber', () => {
-    const accountInput = 'input[data-cy="supplierFiscalDataAccount_input"]';
-    beforeEach(() => {
-        cy.login('developer');
-        cy.viewport(1920, 1080);
-        cy.visit('/#/supplier/1/fiscal-data');
-    });
-
-    describe('VnInput handleInsertMode()', () => {
-        it('should replace character at cursor position in insert mode', () => {
-            cy.get(accountInput).type('{selectall}4100000001');
-            cy.get(accountInput).type('{movetostart}');
-            cy.get(accountInput).type('999');
-            cy.get(accountInput).should('have.value', '9990000001');
-        });
-
-        it('should replace character at cursor position in insert mode', () => {
-            cy.get(accountInput).clear();
-            cy.get(accountInput).type('4100000001');
-            cy.get(accountInput).type('{movetostart}');
-            cy.get(accountInput).type('999');
-            cy.get(accountInput).should('have.value', '9990000001');
-        });
-
-        it('should respect maxlength prop', () => {
-            cy.get(accountInput).clear();
-            cy.get(accountInput).type('123456789012345');
-            cy.get(accountInput).should('have.value', '1234567890');
-        });
-    });
-
-    it('should convert short account number to standard format', () => {
-        cy.get(accountInput).clear();
-        cy.get(accountInput).type('123.');
-        cy.get(accountInput).should('have.value', '1230000000');
-    });
-});
diff --git a/test/cypress/integration/vnComponent/VnLog.spec.js b/test/cypress/integration/vnComponent/VnLog.spec.js
index 8ca32b681..57faeac85 100644
--- a/test/cypress/integration/vnComponent/VnLog.spec.js
+++ b/test/cypress/integration/vnComponent/VnLog.spec.js
@@ -1,26 +1,23 @@
 /// <reference types="cypress" />
 describe('VnLog', () => {
-    const chips = [
-        ':nth-child(1) > :nth-child(1) > .q-item__label > .q-chip > .q-chip__content',
-        ':nth-child(2) > :nth-child(1) > .q-item__label > .q-chip > .q-chip__content',
-    ];
     beforeEach(() => {
         cy.login('developer');
         cy.visit(`/#/claim/${1}/log`);
-        cy.openRightMenu();
     });
 
     it('should filter by insert actions', () => {
-        cy.checkOption(':nth-child(7) > .q-checkbox');
-        cy.get('.q-page').click();
-        cy.validateContent(chips[0], 'Document');
-        cy.validateContent(chips[1], 'Beginning');
+        cy.get('[data-cy="vnLog-checkbox"]').eq(0).click();
+        cy.get('[data-cy="vnLog-action-icon"]').each(($el) => {
+            cy.wrap($el).should('have.attr', 'title', 'Creates');
+        });
     });
 
     it('should filter by entity', () => {
-        cy.selectOption('.q-drawer--right .q-item > .q-select', 'Claim');
-        cy.get('.q-page').click();
-        cy.validateContent(chips[0], 'Beginning');
+        const entity = 'Document';
+        cy.selectOption('[data-cy="vnLog-entity"]', entity);
+        cy.get('[data-cy="vnLog-model-chip"]').each(($el) => {
+            cy.wrap($el).should('have.text', entity);
+        });
     });
 
     it('should show claimDescriptor', () => {
diff --git a/test/cypress/integration/vnComponent/VnShortcut.spec.js b/test/cypress/integration/vnComponent/VnShortcut.spec.js
index e08c44635..cc5cacbe4 100644
--- a/test/cypress/integration/vnComponent/VnShortcut.spec.js
+++ b/test/cypress/integration/vnComponent/VnShortcut.spec.js
@@ -1,6 +1,6 @@
 /// <reference types="cypress" />
-
-describe('VnShortcuts', () => {
+// https://redmine.verdnatura.es/issues/8848
+describe.skip('VnShortcuts', () => {
     const modules = {
         item: 'a',
         customer: 'c',
@@ -27,12 +27,15 @@ describe('VnShortcuts', () => {
                 code: `Key${shortcut.toUpperCase()}`,
             });
 
+            cy.waitSpinner();
             cy.url().should('include', module);
             if (['monitor', 'claim'].includes(module)) {
                 return;
             }
             cy.waitForElement('.q-page').should('exist');
             cy.dataCy('vnTableCreateBtn').should('exist');
+            cy.waitSpinner();
+
             cy.get('.q-page').trigger('keydown', {
                 ctrlKey: true,
                 altKey: true,
diff --git a/test/cypress/integration/vnComponent/crudModel.commands.js b/test/cypress/integration/vnComponent/crudModel.commands.js
new file mode 100644
index 000000000..9d08f064a
--- /dev/null
+++ b/test/cypress/integration/vnComponent/crudModel.commands.js
@@ -0,0 +1,3 @@
+Cypress.Commands.add('saveCrudModel', () =>
+    cy.dataCy('crudModelDefaultSaveBtn').should('exist').click(),
+);
diff --git a/test/cypress/integration/vnComponent/formModel.commands.js b/test/cypress/integration/vnComponent/formModel.commands.js
new file mode 100644
index 000000000..2814b0091
--- /dev/null
+++ b/test/cypress/integration/vnComponent/formModel.commands.js
@@ -0,0 +1,3 @@
+Cypress.Commands.add('saveFormModel', () =>
+    cy.dataCy('FormModelPopup_save').should('exist').click(),
+);
diff --git a/test/cypress/integration/vnComponent/vnConfirm.commands.js b/test/cypress/integration/vnComponent/vnConfirm.commands.js
new file mode 100644
index 000000000..9f93967d6
--- /dev/null
+++ b/test/cypress/integration/vnComponent/vnConfirm.commands.js
@@ -0,0 +1,3 @@
+Cypress.Commands.add('confirmVnConfirm', () =>
+    cy.dataCy('VnConfirm_confirm').should('exist').click(),
+);
diff --git a/test/cypress/integration/vnComponent/vnSelect.commands.js b/test/cypress/integration/vnComponent/vnSelect.commands.js
new file mode 100644
index 000000000..017b6e7ea
--- /dev/null
+++ b/test/cypress/integration/vnComponent/vnSelect.commands.js
@@ -0,0 +1,3 @@
+Cypress.Commands.add('clickOption', (index = 1) =>
+    cy.get(`.q-menu :nth-child(${index}) >.q-item__section`).click(),
+);
diff --git a/test/cypress/integration/vnComponent/vnTable.commands.js b/test/cypress/integration/vnComponent/vnTable.commands.js
new file mode 100644
index 000000000..6c7e71e13
--- /dev/null
+++ b/test/cypress/integration/vnComponent/vnTable.commands.js
@@ -0,0 +1,16 @@
+Cypress.Commands.add('getRow', (index = 1) =>
+    cy.get(`.vnTable .q-virtual-scroll__content tr:nth-child(${index})`),
+);
+Cypress.Commands.add('getRowCol', (field, index = 1) =>
+    cy.get(
+        `.vnTable .q-virtual-scroll__content > :nth-child(${index}) > [data-col-field="${field}"]`,
+    ),
+);
+
+Cypress.Commands.add('vnTableCreateBtn', () =>
+    cy.dataCy('vnTableCreateBtn').should('exist').click(),
+);
+
+Cypress.Commands.add('waitTableScrollLoad', () =>
+    cy.waitForElement('[data-q-vs-anchor]'),
+);
diff --git a/test/cypress/integration/worker/workerList.spec.js b/test/cypress/integration/worker/workerList.spec.js
index 0a45441c1..d964c3dc8 100644
--- a/test/cypress/integration/worker/workerList.spec.js
+++ b/test/cypress/integration/worker/workerList.spec.js
@@ -1,4 +1,5 @@
-describe('WorkerList', () => {
+// https://redmine.verdnatura.es/issues/8848
+describe.skip('WorkerList', () => {
     const inputName = '.q-drawer .q-form input[aria-label="First Name"]';
     const searchBtn = '.q-drawer button:nth-child(3)';
     const descriptorTitle = '.descriptor .title span';
@@ -13,7 +14,7 @@ describe('WorkerList', () => {
         cy.intercept('GET', /\/api\/Workers\/summary+/).as('worker');
         cy.get(searchBtn).click();
         cy.wait('@worker').then(() =>
-            cy.get(descriptorTitle).should('include.text', 'Jessica')
+            cy.get(descriptorTitle).should('include.text', 'Jessica'),
         );
     });
 });
diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js
index 7f5203547..41f91e855 100755
--- a/test/cypress/support/commands.js
+++ b/test/cypress/support/commands.js
@@ -29,7 +29,12 @@
 // import { registerCommands } from '@quasar/quasar-app-extension-testing-e2e-cypress';
 import moment from 'moment';
 import waitUntil from './waitUntil';
+// Importar dinámicamente todos los archivos con el sufijo .commands.js dentro de la carpeta src/test/cypress/integration
+const requireCommands = require.context('../integration', true, /\.commands\.js$/);
+// Iterar sobre cada archivo y requerirlo
+requireCommands.keys().forEach(requireCommands);
 
+// Common comma
 Cypress.Commands.add('waitUntil', { prevSubject: 'optional' }, waitUntil);
 
 Cypress.Commands.add('resetDB', () => {
@@ -606,6 +611,11 @@ Cypress.Commands.add('checkQueryParams', (expectedParams = {}) => {
     });
 });
 
-Cypress.Commands.add('waitTableScrollLoad', () =>
-    cy.waitForElement('[data-q-vs-anchor]'),
-);
+Cypress.Commands.add('validateScrollContent', (validations) => {
+    validations.forEach(({ row, col, text }) => {
+        cy.get(`.q-scrollarea__content > :nth-child(${row}) > :nth-child(${col})`).should(
+            'have.text',
+            text,
+        );
+    });
+});
diff --git a/test/vitest/helper.js b/test/vitest/helper.js
index 1e693ab63..be0029ee8 100644
--- a/test/vitest/helper.js
+++ b/test/vitest/helper.js
@@ -4,7 +4,6 @@ import { createTestingPinia } from '@pinia/testing';
 import { vi } from 'vitest';
 import { i18n } from 'src/boot/i18n';
 import { Notify, Dialog } from 'quasar';
-import axios from 'axios';
 import * as useValidator from 'src/composables/useValidator';
 
 installQuasarPlugin({
@@ -41,8 +40,6 @@ vi.mock('vue-router', () => ({
     onBeforeRouteLeave: () => {},
 }));
 
-vi.mock('axios');
-
 vi.spyOn(useValidator, 'useValidator').mockImplementation(() => {
     return {
         validate: vi.fn(),
@@ -112,5 +109,4 @@ export function createWrapper(component, options) {
 
     return { vm, wrapper };
 }
-
-export { axios, flushPromises };
+export { flushPromises };
diff --git a/test/vitest/setup-file.js b/test/vitest/setup-file.js
index 288f80beb..0ba9e53c2 100644
--- a/test/vitest/setup-file.js
+++ b/test/vitest/setup-file.js
@@ -1 +1,27 @@
 // This file will be run before each test file, don't delete or vitest will not work.
+import { vi } from 'vitest';
+
+vi.mock('axios');
+vi.mock('vue-router', () => ({
+    useRouter: () => ({
+        push: vi.fn(),
+        replace: vi.fn(),
+        currentRoute: {
+            value: {
+                params: {
+                    id: 1,
+                },
+                meta: { moduleName: 'mockName' },
+                matched: [{ path: 'mockName/list' }],
+            },
+        },
+    }),
+    useRoute: () => ({
+        matched: [],
+        query: {},
+        params: {},
+        meta: { moduleName: 'mockName' },
+        path: 'mockSection/list',
+    }),
+    onBeforeRouteLeave: () => {},
+}));
diff --git a/vitest.config.js b/vitest.config.js
index f856a1dc9..331d21ef9 100644
--- a/vitest.config.js
+++ b/vitest.config.js
@@ -5,12 +5,11 @@ import jsconfigPaths from 'vite-jsconfig-paths';
 import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
 import path from 'path';
 
-let reporters,
-    outputFile;
+let reporters, outputFile;
 
 if (process.env.CI) {
     reporters = ['junit', 'default'];
-    outputFile = {junit: './junit/vitest.xml'};
+    outputFile = { junit: './junit/vitest.xml' };
 } else {
     reporters = 'default';
 }
@@ -28,6 +27,9 @@ export default defineConfig({
             'src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}',
         ],
     },
+    server: {
+        hmr: { overlay: false },
+    },
     plugins: [
         vue({
             template: {
@@ -39,8 +41,11 @@ export default defineConfig({
             sassVariables: 'src/quasar-variables.scss',
         }),
         VueI18nPlugin({
+            strictMessage: false,
+
+            runtimeOnly: false,
             include: [
-                path.resolve(__dirname, 'src/i18n/**'),
+                path.resolve(__dirname, 'src/i18n/locale/**'),
                 path.resolve(__dirname, 'src/pages/**/locale/**'),
             ],
         }),