diff --git a/.env.dev b/.env.dev
new file mode 100644
index 0000000..17fd0de
--- /dev/null
+++ b/.env.dev
@@ -0,0 +1 @@
+VITE_APP_BASE_URL=/
diff --git a/.env.pord b/.env.pord
new file mode 100644
index 0000000..17fd0de
--- /dev/null
+++ b/.env.pord
@@ -0,0 +1 @@
+VITE_APP_BASE_URL=/
diff --git a/.env.test b/.env.test
new file mode 100644
index 0000000..17fd0de
--- /dev/null
+++ b/.env.test
@@ -0,0 +1 @@
+VITE_APP_BASE_URL=/
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..a7cea0b
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["Vue.volar"]
+}
diff --git a/env.d.ts b/env.d.ts
new file mode 100644
index 0000000..323c78a
--- /dev/null
+++ b/env.d.ts
@@ -0,0 +1,7 @@
+///
+
+declare module '*.vue' {
+ import type { DefineComponent } from 'vue'
+ const component: DefineComponent<{}, {}, any>
+ export default component
+}
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..542f7e7
--- /dev/null
+++ b/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ hi快下载
+
+
+
+
+
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..71e91a5
--- /dev/null
+++ b/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "hi-download",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite --mode dev",
+ "build:test": "vite build --mode test",
+ "build:prod": "vite build --mode pord",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "@tailwindcss/vite": "^4.1.18",
+ "axios": "^1.13.2",
+ "clsx": "^2.1.1",
+ "lucide-vue-next": "^0.562.0",
+ "reka-ui": "^2.7.0",
+ "tailwindcss": "^4.1.18",
+ "vue": "^3.5.24",
+ "vue-sonner": "^2.0.9"
+ },
+ "devDependencies": {
+ "@tsconfig/node24": "^24.0.3",
+ "@types/node": "^24.10.4",
+ "@vitejs/plugin-vue": "^6.0.1",
+ "@vue/tsconfig": "^0.8.1",
+ "prettier": "^3.8.0",
+ "prettier-plugin-tailwindcss": "^0.7.2",
+ "tailwind-merge": "^3.4.0",
+ "tw-animate-css": "^1.4.0",
+ "typescript": "^5.9.3",
+ "vite": "^7.2.4",
+ "vite-svg-loader": "^5.1.0",
+ "vue-tsc": "^3.2.2"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..2959cbd
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,1921 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@tailwindcss/vite':
+ specifier: ^4.1.18
+ version: 4.1.18(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2))
+ axios:
+ specifier: ^1.13.2
+ version: 1.13.2
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ lucide-vue-next:
+ specifier: ^0.562.0
+ version: 0.562.0(vue@3.5.27(typescript@5.9.3))
+ reka-ui:
+ specifier: ^2.7.0
+ version: 2.7.0(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3))
+ tailwindcss:
+ specifier: ^4.1.18
+ version: 4.1.18
+ vue:
+ specifier: ^3.5.24
+ version: 3.5.27(typescript@5.9.3)
+ vue-sonner:
+ specifier: ^2.0.9
+ version: 2.0.9
+ devDependencies:
+ '@tsconfig/node24':
+ specifier: ^24.0.3
+ version: 24.0.4
+ '@types/node':
+ specifier: ^24.10.4
+ version: 24.10.9
+ '@vitejs/plugin-vue':
+ specifier: ^6.0.1
+ version: 6.0.3(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.9.3))
+ '@vue/tsconfig':
+ specifier: ^0.8.1
+ version: 0.8.1(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3))
+ prettier:
+ specifier: ^3.8.0
+ version: 3.8.0
+ prettier-plugin-tailwindcss:
+ specifier: ^0.7.2
+ version: 0.7.2(prettier@3.8.0)
+ tailwind-merge:
+ specifier: ^3.4.0
+ version: 3.4.0
+ tw-animate-css:
+ specifier: ^1.4.0
+ version: 1.4.0
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+ vite:
+ specifier: ^7.2.4
+ version: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2)
+ vite-svg-loader:
+ specifier: ^5.1.0
+ version: 5.1.0(vue@3.5.27(typescript@5.9.3))
+ vue-tsc:
+ specifier: ^3.2.2
+ version: 3.2.2(typescript@5.9.3)
+
+packages:
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.28.6':
+ resolution: {integrity: sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.28.6':
+ resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==}
+ engines: {node: '>=6.9.0'}
+
+ '@esbuild/aix-ppc64@0.27.2':
+ resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.27.2':
+ resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.2':
+ resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.2':
+ resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.27.2':
+ resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.2':
+ resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.27.2':
+ resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.2':
+ resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.27.2':
+ resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.2':
+ resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.2':
+ resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.2':
+ resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.2':
+ resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.2':
+ resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.2':
+ resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.2':
+ resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.2':
+ resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.2':
+ resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.2':
+ resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.2':
+ resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.2':
+ resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.27.2':
+ resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.2':
+ resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.2':
+ resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@floating-ui/core@1.7.3':
+ resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
+
+ '@floating-ui/dom@1.7.4':
+ resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
+
+ '@floating-ui/utils@0.2.10':
+ resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
+
+ '@floating-ui/vue@1.1.9':
+ resolution: {integrity: sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==}
+
+ '@internationalized/date@3.10.1':
+ resolution: {integrity: sha512-oJrXtQiAXLvT9clCf1K4kxp3eKsQhIaZqxEyowkBcsvZDdZkbWrVmnGknxs5flTD0VGsxrxKgBCZty1EzoiMzA==}
+
+ '@internationalized/number@3.6.5':
+ resolution: {integrity: sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==}
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/remapping@2.3.5':
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@rolldown/pluginutils@1.0.0-beta.53':
+ resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==}
+
+ '@rollup/rollup-android-arm-eabi@4.55.2':
+ resolution: {integrity: sha512-21J6xzayjy3O6NdnlO6aXi/urvSRjm6nCI6+nF6ra2YofKruGixN9kfT+dt55HVNwfDmpDHJcaS3JuP/boNnlA==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.55.2':
+ resolution: {integrity: sha512-eXBg7ibkNUZ+sTwbFiDKou0BAckeV6kIigK7y5Ko4mB/5A1KLhuzEKovsmfvsL8mQorkoincMFGnQuIT92SKqA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.55.2':
+ resolution: {integrity: sha512-UCbaTklREjrc5U47ypLulAgg4njaqfOVLU18VrCrI+6E5MQjuG0lSWaqLlAJwsD7NpFV249XgB0Bi37Zh5Sz4g==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.55.2':
+ resolution: {integrity: sha512-dP67MA0cCMHFT2g5XyjtpVOtp7y4UyUxN3dhLdt11at5cPKnSm4lY+EhwNvDXIMzAMIo2KU+mc9wxaAQJTn7sQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.55.2':
+ resolution: {integrity: sha512-WDUPLUwfYV9G1yxNRJdXcvISW15mpvod1Wv3ok+Ws93w1HjIVmCIFxsG2DquO+3usMNCpJQ0wqO+3GhFdl6Fow==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.55.2':
+ resolution: {integrity: sha512-Ng95wtHVEulRwn7R0tMrlUuiLVL/HXA8Lt/MYVpy88+s5ikpntzZba1qEulTuPnPIZuOPcW9wNEiqvZxZmgmqQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.55.2':
+ resolution: {integrity: sha512-AEXMESUDWWGqD6LwO/HkqCZgUE1VCJ1OhbvYGsfqX2Y6w5quSXuyoy/Fg3nRqiwro+cJYFxiw5v4kB2ZDLhxrw==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.55.2':
+ resolution: {integrity: sha512-ZV7EljjBDwBBBSv570VWj0hiNTdHt9uGznDtznBB4Caj3ch5rgD4I2K1GQrtbvJ/QiB+663lLgOdcADMNVC29Q==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.55.2':
+ resolution: {integrity: sha512-uvjwc8NtQVPAJtq4Tt7Q49FOodjfbf6NpqXyW/rjXoV+iZ3EJAHLNAnKT5UJBc6ffQVgmXTUL2ifYiLABlGFqA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.55.2':
+ resolution: {integrity: sha512-s3KoWVNnye9mm/2WpOZ3JeUiediUVw6AvY/H7jNA6qgKA2V2aM25lMkVarTDfiicn/DLq3O0a81jncXszoyCFA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-gnu@4.55.2':
+ resolution: {integrity: sha512-gi21faacK+J8aVSyAUptML9VQN26JRxe484IbF+h3hpG+sNVoMXPduhREz2CcYr5my0NE3MjVvQ5bMKX71pfVA==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-musl@4.55.2':
+ resolution: {integrity: sha512-qSlWiXnVaS/ceqXNfnoFZh4IiCA0EwvCivivTGbEu1qv2o+WTHpn1zNmCTAoOG5QaVr2/yhCoLScQtc/7RxshA==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.55.2':
+ resolution: {integrity: sha512-rPyuLFNoF1B0+wolH277E780NUKf+KoEDb3OyoLbAO18BbeKi++YN6gC/zuJoPPDlQRL3fIxHxCxVEWiem2yXw==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-musl@4.55.2':
+ resolution: {integrity: sha512-g+0ZLMook31iWV4PvqKU0i9E78gaZgYpSrYPed/4Bu+nGTgfOPtfs1h11tSSRPXSjC5EzLTjV/1A7L2Vr8pJoQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.55.2':
+ resolution: {integrity: sha512-i+sGeRGsjKZcQRh3BRfpLsM3LX3bi4AoEVqmGDyc50L6KfYsN45wVCSz70iQMwPWr3E5opSiLOwsC9WB4/1pqg==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-musl@4.55.2':
+ resolution: {integrity: sha512-C1vLcKc4MfFV6I0aWsC7B2Y9QcsiEcvKkfxprwkPfLaN8hQf0/fKHwSF2lcYzA9g4imqnhic729VB9Fo70HO3Q==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.55.2':
+ resolution: {integrity: sha512-68gHUK/howpQjh7g7hlD9DvTTt4sNLp1Bb+Yzw2Ki0xvscm2cOdCLZNJNhd2jW8lsTPrHAHuF751BygifW4bkQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.55.2':
+ resolution: {integrity: sha512-1e30XAuaBP1MAizaOBApsgeGZge2/Byd6wV4a8oa6jPdHELbRHBiw7wvo4dp7Ie2PE8TZT4pj9RLGZv9N4qwlw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.55.2':
+ resolution: {integrity: sha512-4BJucJBGbuGnH6q7kpPqGJGzZnYrpAzRd60HQSt3OpX/6/YVgSsJnNzR8Ot74io50SeVT4CtCWe/RYIAymFPwA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-openbsd-x64@4.55.2':
+ resolution: {integrity: sha512-cT2MmXySMo58ENv8p6/O6wI/h/gLnD3D6JoajwXFZH6X9jz4hARqUhWpGuQhOgLNXscfZYRQMJvZDtWNzMAIDw==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.55.2':
+ resolution: {integrity: sha512-sZnyUgGkuzIXaK3jNMPmUIyJrxu/PjmATQrocpGA1WbCPX8H5tfGgRSuYtqBYAvLuIGp8SPRb1O4d1Fkb5fXaQ==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.55.2':
+ resolution: {integrity: sha512-sDpFbenhmWjNcEbBcoTV0PWvW5rPJFvu+P7XoTY0YLGRupgLbFY0XPfwIbJOObzO7QgkRDANh65RjhPmgSaAjQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.55.2':
+ resolution: {integrity: sha512-GvJ03TqqaweWCigtKQVBErw2bEhu1tyfNQbarwr94wCGnczA9HF8wqEe3U/Lfu6EdeNP0p6R+APeHVwEqVxpUQ==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.55.2':
+ resolution: {integrity: sha512-KvXsBvp13oZz9JGe5NYS7FNizLe99Ny+W8ETsuCyjXiKdiGrcz2/J/N8qxZ/RSwivqjQguug07NLHqrIHrqfYw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.55.2':
+ resolution: {integrity: sha512-xNO+fksQhsAckRtDSPWaMeT1uIM+JrDRXlerpnWNXhn1TdB3YZ6uKBMBTKP0eX9XtYEP978hHk1f8332i2AW8Q==}
+ cpu: [x64]
+ os: [win32]
+
+ '@swc/helpers@0.5.18':
+ resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==}
+
+ '@tailwindcss/node@4.1.18':
+ resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==}
+
+ '@tailwindcss/oxide-android-arm64@4.1.18':
+ resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.1.18':
+ resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.1.18':
+ resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.1.18':
+ resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18':
+ resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.1.18':
+ resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.1.18':
+ resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.1.18':
+ resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.1.18':
+ resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-wasm32-wasi@4.1.18':
+ resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
+ bundledDependencies:
+ - '@napi-rs/wasm-runtime'
+ - '@emnapi/core'
+ - '@emnapi/runtime'
+ - '@tybys/wasm-util'
+ - '@emnapi/wasi-threads'
+ - tslib
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.1.18':
+ resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.1.18':
+ resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.1.18':
+ resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==}
+ engines: {node: '>= 10'}
+
+ '@tailwindcss/vite@4.1.18':
+ resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==}
+ peerDependencies:
+ vite: ^5.2.0 || ^6 || ^7
+
+ '@tanstack/virtual-core@3.13.18':
+ resolution: {integrity: sha512-Mx86Hqu1k39icq2Zusq+Ey2J6dDWTjDvEv43PJtRCoEYTLyfaPnxIQ6iy7YAOK0NV/qOEmZQ/uCufrppZxTgcg==}
+
+ '@tanstack/vue-virtual@3.13.18':
+ resolution: {integrity: sha512-6pT8HdHtTU5Z+t906cGdCroUNA5wHjFXsNss9gwk7QAr1VNZtz9IQCs2Nhx0gABK48c+OocHl2As+TMg8+Hy4A==}
+ peerDependencies:
+ vue: ^2.7.0 || ^3.0.0
+
+ '@trysound/sax@0.2.0':
+ resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
+ engines: {node: '>=10.13.0'}
+
+ '@tsconfig/node24@24.0.4':
+ resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/node@24.10.9':
+ resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==}
+
+ '@types/web-bluetooth@0.0.21':
+ resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
+
+ '@vitejs/plugin-vue@6.0.3':
+ resolution: {integrity: sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
+ vue: ^3.2.25
+
+ '@volar/language-core@2.4.27':
+ resolution: {integrity: sha512-DjmjBWZ4tJKxfNC1F6HyYERNHPYS7L7OPFyCrestykNdUZMFYzI9WTyvwPcaNaHlrEUwESHYsfEw3isInncZxQ==}
+
+ '@volar/source-map@2.4.27':
+ resolution: {integrity: sha512-ynlcBReMgOZj2i6po+qVswtDUeeBRCTgDurjMGShbm8WYZgJ0PA4RmtebBJ0BCYol1qPv3GQF6jK7C9qoVc7lg==}
+
+ '@volar/typescript@2.4.27':
+ resolution: {integrity: sha512-eWaYCcl/uAPInSK2Lze6IqVWaBu/itVqR5InXcHXFyles4zO++Mglt3oxdgj75BDcv1Knr9Y93nowS8U3wqhxg==}
+
+ '@vue/compiler-core@3.5.27':
+ resolution: {integrity: sha512-gnSBQjZA+//qDZen+6a2EdHqJ68Z7uybrMf3SPjEGgG4dicklwDVmMC1AeIHxtLVPT7sn6sH1KOO+tS6gwOUeQ==}
+
+ '@vue/compiler-dom@3.5.27':
+ resolution: {integrity: sha512-oAFea8dZgCtVVVTEC7fv3T5CbZW9BxpFzGGxC79xakTr6ooeEqmRuvQydIiDAkglZEAd09LgVf1RoDnL54fu5w==}
+
+ '@vue/compiler-sfc@3.5.27':
+ resolution: {integrity: sha512-sHZu9QyDPeDmN/MRoshhggVOWE5WlGFStKFwu8G52swATgSny27hJRWteKDSUUzUH+wp+bmeNbhJnEAel/auUQ==}
+
+ '@vue/compiler-ssr@3.5.27':
+ resolution: {integrity: sha512-Sj7h+JHt512fV1cTxKlYhg7qxBvack+BGncSpH+8vnN+KN95iPIcqB5rsbblX40XorP+ilO7VIKlkuu3Xq2vjw==}
+
+ '@vue/language-core@3.2.2':
+ resolution: {integrity: sha512-5DAuhxsxBN9kbriklh3Q5AMaJhyOCNiQJvCskN9/30XOpdLiqZU9Q+WvjArP17ubdGEyZtBzlIeG5nIjEbNOrQ==}
+
+ '@vue/reactivity@3.5.27':
+ resolution: {integrity: sha512-vvorxn2KXfJ0nBEnj4GYshSgsyMNFnIQah/wczXlsNXt+ijhugmW+PpJ2cNPe4V6jpnBcs0MhCODKllWG+nvoQ==}
+
+ '@vue/runtime-core@3.5.27':
+ resolution: {integrity: sha512-fxVuX/fzgzeMPn/CLQecWeDIFNt3gQVhxM0rW02Tvp/YmZfXQgcTXlakq7IMutuZ/+Ogbn+K0oct9J3JZfyk3A==}
+
+ '@vue/runtime-dom@3.5.27':
+ resolution: {integrity: sha512-/QnLslQgYqSJ5aUmb5F0z0caZPGHRB8LEAQ1s81vHFM5CBfnun63rxhvE/scVb/j3TbBuoZwkJyiLCkBluMpeg==}
+
+ '@vue/server-renderer@3.5.27':
+ resolution: {integrity: sha512-qOz/5thjeP1vAFc4+BY3Nr6wxyLhpeQgAE/8dDtKo6a6xdk+L4W46HDZgNmLOBUDEkFXV3G7pRiUqxjX0/2zWA==}
+ peerDependencies:
+ vue: 3.5.27
+
+ '@vue/shared@3.5.27':
+ resolution: {integrity: sha512-dXr/3CgqXsJkZ0n9F3I4elY8wM9jMJpP3pvRG52r6m0tu/MsAFIe6JpXVGeNMd/D9F4hQynWT8Rfuj0bdm9kFQ==}
+
+ '@vue/tsconfig@0.8.1':
+ resolution: {integrity: sha512-aK7feIWPXFSUhsCP9PFqPyFOcz4ENkb8hZ2pneL6m2UjCkccvaOhC/5KCKluuBufvp2KzkbdA2W2pk20vLzu3g==}
+ peerDependencies:
+ typescript: 5.x
+ vue: ^3.4.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ vue:
+ optional: true
+
+ '@vueuse/core@12.8.2':
+ resolution: {integrity: sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==}
+
+ '@vueuse/metadata@12.8.2':
+ resolution: {integrity: sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==}
+
+ '@vueuse/shared@12.8.2':
+ resolution: {integrity: sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==}
+
+ alien-signals@3.1.2:
+ resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==}
+
+ aria-hidden@1.2.6:
+ resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
+ engines: {node: '>=10'}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ axios@1.13.2:
+ resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ commander@7.2.0:
+ resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
+ engines: {node: '>= 10'}
+
+ css-select@5.2.2:
+ resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
+
+ css-tree@2.2.1:
+ resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ css-tree@2.3.1:
+ resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
+ css-what@6.2.2:
+ resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
+ engines: {node: '>= 6'}
+
+ csso@5.0.5:
+ resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ defu@6.1.4:
+ resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ dom-serializer@2.0.0:
+ resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
+
+ domelementtype@2.3.0:
+ resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
+
+ domhandler@5.0.3:
+ resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
+ engines: {node: '>= 4'}
+
+ domutils@3.2.2:
+ resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ enhanced-resolve@5.18.4:
+ resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
+ engines: {node: '>=10.13.0'}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ entities@7.0.0:
+ resolution: {integrity: sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==}
+ engines: {node: '>=0.12'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.1:
+ resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.27.2:
+ resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ follow-redirects@1.15.11:
+ resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ form-data@4.0.5:
+ resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
+ engines: {node: '>= 6'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ jiti@2.6.1:
+ resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
+ hasBin: true
+
+ lightningcss-android-arm64@1.30.2:
+ resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.30.2:
+ resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.30.2:
+ resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.30.2:
+ resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.30.2:
+ resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.30.2:
+ resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.30.2:
+ resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.30.2:
+ resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.30.2:
+ resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.30.2:
+ resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.30.2:
+ resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.30.2:
+ resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
+ engines: {node: '>= 12.0.0'}
+
+ lucide-vue-next@0.562.0:
+ resolution: {integrity: sha512-LN0BLGKMFulv0lnfK29r14DcngRUhIqdcaL0zXTt2o0oS9odlrjCGaU3/X9hIihOjjN8l8e+Y9G/famcNYaI7Q==}
+ peerDependencies:
+ vue: '>=3.0.1'
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ mdn-data@2.0.28:
+ resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
+
+ mdn-data@2.0.30:
+ resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ ohash@2.0.11:
+ resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.3:
+ resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
+ engines: {node: '>=12'}
+
+ postcss@8.5.6:
+ resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prettier-plugin-tailwindcss@0.7.2:
+ resolution: {integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==}
+ engines: {node: '>=20.19'}
+ peerDependencies:
+ '@ianvs/prettier-plugin-sort-imports': '*'
+ '@prettier/plugin-hermes': '*'
+ '@prettier/plugin-oxc': '*'
+ '@prettier/plugin-pug': '*'
+ '@shopify/prettier-plugin-liquid': '*'
+ '@trivago/prettier-plugin-sort-imports': '*'
+ '@zackad/prettier-plugin-twig': '*'
+ prettier: ^3.0
+ prettier-plugin-astro: '*'
+ prettier-plugin-css-order: '*'
+ prettier-plugin-jsdoc: '*'
+ prettier-plugin-marko: '*'
+ prettier-plugin-multiline-arrays: '*'
+ prettier-plugin-organize-attributes: '*'
+ prettier-plugin-organize-imports: '*'
+ prettier-plugin-sort-imports: '*'
+ prettier-plugin-svelte: '*'
+ peerDependenciesMeta:
+ '@ianvs/prettier-plugin-sort-imports':
+ optional: true
+ '@prettier/plugin-hermes':
+ optional: true
+ '@prettier/plugin-oxc':
+ optional: true
+ '@prettier/plugin-pug':
+ optional: true
+ '@shopify/prettier-plugin-liquid':
+ optional: true
+ '@trivago/prettier-plugin-sort-imports':
+ optional: true
+ '@zackad/prettier-plugin-twig':
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+ prettier-plugin-css-order:
+ optional: true
+ prettier-plugin-jsdoc:
+ optional: true
+ prettier-plugin-marko:
+ optional: true
+ prettier-plugin-multiline-arrays:
+ optional: true
+ prettier-plugin-organize-attributes:
+ optional: true
+ prettier-plugin-organize-imports:
+ optional: true
+ prettier-plugin-sort-imports:
+ optional: true
+ prettier-plugin-svelte:
+ optional: true
+
+ prettier@3.8.0:
+ resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
+ reka-ui@2.7.0:
+ resolution: {integrity: sha512-m+XmxQN2xtFzBP3OAdIafKq7C8OETo2fqfxcIIxYmNN2Ch3r5oAf6yEYCIJg5tL/yJU2mHqF70dCCekUkrAnXA==}
+ peerDependencies:
+ vue: '>= 3.2.0'
+
+ rollup@4.55.2:
+ resolution: {integrity: sha512-PggGy4dhwx5qaW+CKBilA/98Ql9keyfnb7lh4SR6shQ91QQQi1ORJ1v4UinkdP2i87OBs9AQFooQylcrrRfIcg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ svgo@3.3.2:
+ resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ tailwind-merge@3.4.0:
+ resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==}
+
+ tailwindcss@4.1.18:
+ resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==}
+
+ tapable@2.3.0:
+ resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
+ engines: {node: '>=6'}
+
+ tinyglobby@0.2.15:
+ resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
+ engines: {node: '>=12.0.0'}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tw-animate-css@1.4.0:
+ resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@7.16.0:
+ resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
+
+ vite-svg-loader@5.1.0:
+ resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==}
+ peerDependencies:
+ vue: '>=3.2.13'
+
+ vite@7.3.1:
+ resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ 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
+
+ vscode-uri@3.1.0:
+ resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-sonner@2.0.9:
+ resolution: {integrity: sha512-i6BokNlNDL93fpzNxN/LZSn6D6MzlO+i3qXt6iVZne3x1k7R46d5HlFB4P8tYydhgqOrRbIZEsnRd3kG7qGXyw==}
+ peerDependencies:
+ '@nuxt/kit': ^4.0.3
+ '@nuxt/schema': ^4.0.3
+ nuxt: ^4.0.3
+ peerDependenciesMeta:
+ '@nuxt/kit':
+ optional: true
+ '@nuxt/schema':
+ optional: true
+ nuxt:
+ optional: true
+
+ vue-tsc@3.2.2:
+ resolution: {integrity: sha512-r9YSia/VgGwmbbfC06hDdAatH634XJ9nVl6Zrnz1iK4ucp8Wu78kawplXnIDa3MSu1XdQQePTHLXYwPDWn+nyQ==}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.0.0'
+
+ vue@3.5.27:
+ resolution: {integrity: sha512-aJ/UtoEyFySPBGarREmN4z6qNKpbEguYHMmXSiOGk69czc+zhs0NF6tEFrY8TZKAl8N/LYAkd4JHVd5E/AsSmw==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+snapshots:
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/parser@7.28.6':
+ dependencies:
+ '@babel/types': 7.28.6
+
+ '@babel/types@7.28.6':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@esbuild/aix-ppc64@0.27.2':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/android-arm@0.27.2':
+ optional: true
+
+ '@esbuild/android-x64@0.27.2':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.2':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.2':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.2':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.2':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.2':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.2':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.2':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.2':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.2':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.2':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.2':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.2':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.2':
+ optional: true
+
+ '@floating-ui/core@1.7.3':
+ dependencies:
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/dom@1.7.4':
+ dependencies:
+ '@floating-ui/core': 1.7.3
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/utils@0.2.10': {}
+
+ '@floating-ui/vue@1.1.9(vue@3.5.27(typescript@5.9.3))':
+ dependencies:
+ '@floating-ui/dom': 1.7.4
+ '@floating-ui/utils': 0.2.10
+ vue-demi: 0.14.10(vue@3.5.27(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@internationalized/date@3.10.1':
+ dependencies:
+ '@swc/helpers': 0.5.18
+
+ '@internationalized/number@3.6.5':
+ dependencies:
+ '@swc/helpers': 0.5.18
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/remapping@2.3.5':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@rolldown/pluginutils@1.0.0-beta.53': {}
+
+ '@rollup/rollup-android-arm-eabi@4.55.2':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.55.2':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.55.2':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.55.2':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.55.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.55.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.55.2':
+ optional: true
+
+ '@swc/helpers@0.5.18':
+ dependencies:
+ tslib: 2.8.1
+
+ '@tailwindcss/node@4.1.18':
+ dependencies:
+ '@jridgewell/remapping': 2.3.5
+ enhanced-resolve: 5.18.4
+ jiti: 2.6.1
+ lightningcss: 1.30.2
+ magic-string: 0.30.21
+ source-map-js: 1.2.1
+ tailwindcss: 4.1.18
+
+ '@tailwindcss/oxide-android-arm64@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-wasm32-wasi@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.1.18':
+ optional: true
+
+ '@tailwindcss/oxide@4.1.18':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.1.18
+ '@tailwindcss/oxide-darwin-arm64': 4.1.18
+ '@tailwindcss/oxide-darwin-x64': 4.1.18
+ '@tailwindcss/oxide-freebsd-x64': 4.1.18
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18
+ '@tailwindcss/oxide-linux-arm64-musl': 4.1.18
+ '@tailwindcss/oxide-linux-x64-gnu': 4.1.18
+ '@tailwindcss/oxide-linux-x64-musl': 4.1.18
+ '@tailwindcss/oxide-wasm32-wasi': 4.1.18
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18
+ '@tailwindcss/oxide-win32-x64-msvc': 4.1.18
+
+ '@tailwindcss/vite@4.1.18(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2))':
+ dependencies:
+ '@tailwindcss/node': 4.1.18
+ '@tailwindcss/oxide': 4.1.18
+ tailwindcss: 4.1.18
+ vite: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2)
+
+ '@tanstack/virtual-core@3.13.18': {}
+
+ '@tanstack/vue-virtual@3.13.18(vue@3.5.27(typescript@5.9.3))':
+ dependencies:
+ '@tanstack/virtual-core': 3.13.18
+ vue: 3.5.27(typescript@5.9.3)
+
+ '@trysound/sax@0.2.0': {}
+
+ '@tsconfig/node24@24.0.4': {}
+
+ '@types/estree@1.0.8': {}
+
+ '@types/node@24.10.9':
+ dependencies:
+ undici-types: 7.16.0
+
+ '@types/web-bluetooth@0.0.21': {}
+
+ '@vitejs/plugin-vue@6.0.3(vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.27(typescript@5.9.3))':
+ dependencies:
+ '@rolldown/pluginutils': 1.0.0-beta.53
+ vite: 7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2)
+ vue: 3.5.27(typescript@5.9.3)
+
+ '@volar/language-core@2.4.27':
+ dependencies:
+ '@volar/source-map': 2.4.27
+
+ '@volar/source-map@2.4.27': {}
+
+ '@volar/typescript@2.4.27':
+ dependencies:
+ '@volar/language-core': 2.4.27
+ path-browserify: 1.0.1
+ vscode-uri: 3.1.0
+
+ '@vue/compiler-core@3.5.27':
+ dependencies:
+ '@babel/parser': 7.28.6
+ '@vue/shared': 3.5.27
+ entities: 7.0.0
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.27':
+ dependencies:
+ '@vue/compiler-core': 3.5.27
+ '@vue/shared': 3.5.27
+
+ '@vue/compiler-sfc@3.5.27':
+ dependencies:
+ '@babel/parser': 7.28.6
+ '@vue/compiler-core': 3.5.27
+ '@vue/compiler-dom': 3.5.27
+ '@vue/compiler-ssr': 3.5.27
+ '@vue/shared': 3.5.27
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.6
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.27':
+ dependencies:
+ '@vue/compiler-dom': 3.5.27
+ '@vue/shared': 3.5.27
+
+ '@vue/language-core@3.2.2':
+ dependencies:
+ '@volar/language-core': 2.4.27
+ '@vue/compiler-dom': 3.5.27
+ '@vue/shared': 3.5.27
+ alien-signals: 3.1.2
+ muggle-string: 0.4.1
+ path-browserify: 1.0.1
+ picomatch: 4.0.3
+
+ '@vue/reactivity@3.5.27':
+ dependencies:
+ '@vue/shared': 3.5.27
+
+ '@vue/runtime-core@3.5.27':
+ dependencies:
+ '@vue/reactivity': 3.5.27
+ '@vue/shared': 3.5.27
+
+ '@vue/runtime-dom@3.5.27':
+ dependencies:
+ '@vue/reactivity': 3.5.27
+ '@vue/runtime-core': 3.5.27
+ '@vue/shared': 3.5.27
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.27(vue@3.5.27(typescript@5.9.3))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.27
+ '@vue/shared': 3.5.27
+ vue: 3.5.27(typescript@5.9.3)
+
+ '@vue/shared@3.5.27': {}
+
+ '@vue/tsconfig@0.8.1(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3))':
+ optionalDependencies:
+ typescript: 5.9.3
+ vue: 3.5.27(typescript@5.9.3)
+
+ '@vueuse/core@12.8.2(typescript@5.9.3)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.21
+ '@vueuse/metadata': 12.8.2
+ '@vueuse/shared': 12.8.2(typescript@5.9.3)
+ vue: 3.5.27(typescript@5.9.3)
+ transitivePeerDependencies:
+ - typescript
+
+ '@vueuse/metadata@12.8.2': {}
+
+ '@vueuse/shared@12.8.2(typescript@5.9.3)':
+ dependencies:
+ vue: 3.5.27(typescript@5.9.3)
+ transitivePeerDependencies:
+ - typescript
+
+ alien-signals@3.1.2: {}
+
+ aria-hidden@1.2.6:
+ dependencies:
+ tslib: 2.8.1
+
+ asynckit@0.4.0: {}
+
+ axios@1.13.2:
+ dependencies:
+ follow-redirects: 1.15.11
+ form-data: 4.0.5
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
+ boolbase@1.0.0: {}
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ clsx@2.1.1: {}
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ commander@7.2.0: {}
+
+ css-select@5.2.2:
+ dependencies:
+ boolbase: 1.0.0
+ css-what: 6.2.2
+ domhandler: 5.0.3
+ domutils: 3.2.2
+ nth-check: 2.1.1
+
+ css-tree@2.2.1:
+ dependencies:
+ mdn-data: 2.0.28
+ source-map-js: 1.2.1
+
+ css-tree@2.3.1:
+ dependencies:
+ mdn-data: 2.0.30
+ source-map-js: 1.2.1
+
+ css-what@6.2.2: {}
+
+ csso@5.0.5:
+ dependencies:
+ css-tree: 2.2.1
+
+ csstype@3.2.3: {}
+
+ defu@6.1.4: {}
+
+ delayed-stream@1.0.0: {}
+
+ detect-libc@2.1.2: {}
+
+ dom-serializer@2.0.0:
+ dependencies:
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+ entities: 4.5.0
+
+ domelementtype@2.3.0: {}
+
+ domhandler@5.0.3:
+ dependencies:
+ domelementtype: 2.3.0
+
+ domutils@3.2.2:
+ dependencies:
+ dom-serializer: 2.0.0
+ domelementtype: 2.3.0
+ domhandler: 5.0.3
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ enhanced-resolve@5.18.4:
+ dependencies:
+ graceful-fs: 4.2.11
+ tapable: 2.3.0
+
+ entities@4.5.0: {}
+
+ entities@7.0.0: {}
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-object-atoms@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.2
+
+ esbuild@0.27.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.2
+ '@esbuild/android-arm': 0.27.2
+ '@esbuild/android-arm64': 0.27.2
+ '@esbuild/android-x64': 0.27.2
+ '@esbuild/darwin-arm64': 0.27.2
+ '@esbuild/darwin-x64': 0.27.2
+ '@esbuild/freebsd-arm64': 0.27.2
+ '@esbuild/freebsd-x64': 0.27.2
+ '@esbuild/linux-arm': 0.27.2
+ '@esbuild/linux-arm64': 0.27.2
+ '@esbuild/linux-ia32': 0.27.2
+ '@esbuild/linux-loong64': 0.27.2
+ '@esbuild/linux-mips64el': 0.27.2
+ '@esbuild/linux-ppc64': 0.27.2
+ '@esbuild/linux-riscv64': 0.27.2
+ '@esbuild/linux-s390x': 0.27.2
+ '@esbuild/linux-x64': 0.27.2
+ '@esbuild/netbsd-arm64': 0.27.2
+ '@esbuild/netbsd-x64': 0.27.2
+ '@esbuild/openbsd-arm64': 0.27.2
+ '@esbuild/openbsd-x64': 0.27.2
+ '@esbuild/openharmony-arm64': 0.27.2
+ '@esbuild/sunos-x64': 0.27.2
+ '@esbuild/win32-arm64': 0.27.2
+ '@esbuild/win32-ia32': 0.27.2
+ '@esbuild/win32-x64': 0.27.2
+
+ estree-walker@2.0.2: {}
+
+ fdir@6.5.0(picomatch@4.0.3):
+ optionalDependencies:
+ picomatch: 4.0.3
+
+ follow-redirects@1.15.11: {}
+
+ form-data@4.0.5:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.2
+ mime-types: 2.1.35
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.1
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.1
+
+ gopd@1.2.0: {}
+
+ graceful-fs@4.2.11: {}
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ jiti@2.6.1: {}
+
+ lightningcss-android-arm64@1.30.2:
+ optional: true
+
+ lightningcss-darwin-arm64@1.30.2:
+ optional: true
+
+ lightningcss-darwin-x64@1.30.2:
+ optional: true
+
+ lightningcss-freebsd-x64@1.30.2:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.30.2:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.30.2:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.30.2:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.30.2:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.30.2:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.30.2:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.30.2:
+ optional: true
+
+ lightningcss@1.30.2:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.30.2
+ lightningcss-darwin-arm64: 1.30.2
+ lightningcss-darwin-x64: 1.30.2
+ lightningcss-freebsd-x64: 1.30.2
+ lightningcss-linux-arm-gnueabihf: 1.30.2
+ lightningcss-linux-arm64-gnu: 1.30.2
+ lightningcss-linux-arm64-musl: 1.30.2
+ lightningcss-linux-x64-gnu: 1.30.2
+ lightningcss-linux-x64-musl: 1.30.2
+ lightningcss-win32-arm64-msvc: 1.30.2
+ lightningcss-win32-x64-msvc: 1.30.2
+
+ lucide-vue-next@0.562.0(vue@3.5.27(typescript@5.9.3)):
+ dependencies:
+ vue: 3.5.27(typescript@5.9.3)
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ math-intrinsics@1.1.0: {}
+
+ mdn-data@2.0.28: {}
+
+ mdn-data@2.0.30: {}
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.11: {}
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ ohash@2.0.11: {}
+
+ path-browserify@1.0.1: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.3: {}
+
+ postcss@8.5.6:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prettier-plugin-tailwindcss@0.7.2(prettier@3.8.0):
+ dependencies:
+ prettier: 3.8.0
+
+ prettier@3.8.0: {}
+
+ proxy-from-env@1.1.0: {}
+
+ reka-ui@2.7.0(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)):
+ dependencies:
+ '@floating-ui/dom': 1.7.4
+ '@floating-ui/vue': 1.1.9(vue@3.5.27(typescript@5.9.3))
+ '@internationalized/date': 3.10.1
+ '@internationalized/number': 3.6.5
+ '@tanstack/vue-virtual': 3.13.18(vue@3.5.27(typescript@5.9.3))
+ '@vueuse/core': 12.8.2(typescript@5.9.3)
+ '@vueuse/shared': 12.8.2(typescript@5.9.3)
+ aria-hidden: 1.2.6
+ defu: 6.1.4
+ ohash: 2.0.11
+ vue: 3.5.27(typescript@5.9.3)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - typescript
+
+ rollup@4.55.2:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.55.2
+ '@rollup/rollup-android-arm64': 4.55.2
+ '@rollup/rollup-darwin-arm64': 4.55.2
+ '@rollup/rollup-darwin-x64': 4.55.2
+ '@rollup/rollup-freebsd-arm64': 4.55.2
+ '@rollup/rollup-freebsd-x64': 4.55.2
+ '@rollup/rollup-linux-arm-gnueabihf': 4.55.2
+ '@rollup/rollup-linux-arm-musleabihf': 4.55.2
+ '@rollup/rollup-linux-arm64-gnu': 4.55.2
+ '@rollup/rollup-linux-arm64-musl': 4.55.2
+ '@rollup/rollup-linux-loong64-gnu': 4.55.2
+ '@rollup/rollup-linux-loong64-musl': 4.55.2
+ '@rollup/rollup-linux-ppc64-gnu': 4.55.2
+ '@rollup/rollup-linux-ppc64-musl': 4.55.2
+ '@rollup/rollup-linux-riscv64-gnu': 4.55.2
+ '@rollup/rollup-linux-riscv64-musl': 4.55.2
+ '@rollup/rollup-linux-s390x-gnu': 4.55.2
+ '@rollup/rollup-linux-x64-gnu': 4.55.2
+ '@rollup/rollup-linux-x64-musl': 4.55.2
+ '@rollup/rollup-openbsd-x64': 4.55.2
+ '@rollup/rollup-openharmony-arm64': 4.55.2
+ '@rollup/rollup-win32-arm64-msvc': 4.55.2
+ '@rollup/rollup-win32-ia32-msvc': 4.55.2
+ '@rollup/rollup-win32-x64-gnu': 4.55.2
+ '@rollup/rollup-win32-x64-msvc': 4.55.2
+ fsevents: 2.3.3
+
+ source-map-js@1.2.1: {}
+
+ svgo@3.3.2:
+ dependencies:
+ '@trysound/sax': 0.2.0
+ commander: 7.2.0
+ css-select: 5.2.2
+ css-tree: 2.3.1
+ css-what: 6.2.2
+ csso: 5.0.5
+ picocolors: 1.1.1
+
+ tailwind-merge@3.4.0: {}
+
+ tailwindcss@4.1.18: {}
+
+ tapable@2.3.0: {}
+
+ tinyglobby@0.2.15:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+
+ tslib@2.8.1: {}
+
+ tw-animate-css@1.4.0: {}
+
+ typescript@5.9.3: {}
+
+ undici-types@7.16.0: {}
+
+ vite-svg-loader@5.1.0(vue@3.5.27(typescript@5.9.3)):
+ dependencies:
+ svgo: 3.3.2
+ vue: 3.5.27(typescript@5.9.3)
+
+ vite@7.3.1(@types/node@24.10.9)(jiti@2.6.1)(lightningcss@1.30.2):
+ dependencies:
+ esbuild: 0.27.2
+ fdir: 6.5.0(picomatch@4.0.3)
+ picomatch: 4.0.3
+ postcss: 8.5.6
+ rollup: 4.55.2
+ tinyglobby: 0.2.15
+ optionalDependencies:
+ '@types/node': 24.10.9
+ fsevents: 2.3.3
+ jiti: 2.6.1
+ lightningcss: 1.30.2
+
+ vscode-uri@3.1.0: {}
+
+ vue-demi@0.14.10(vue@3.5.27(typescript@5.9.3)):
+ dependencies:
+ vue: 3.5.27(typescript@5.9.3)
+
+ vue-sonner@2.0.9: {}
+
+ vue-tsc@3.2.2(typescript@5.9.3):
+ dependencies:
+ '@volar/typescript': 2.4.27
+ '@vue/language-core': 3.2.2
+ typescript: 5.9.3
+
+ vue@3.5.27(typescript@5.9.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.27
+ '@vue/compiler-sfc': 3.5.27
+ '@vue/runtime-dom': 3.5.27
+ '@vue/server-renderer': 3.5.27(vue@3.5.27(typescript@5.9.3))
+ '@vue/shared': 3.5.27
+ optionalDependencies:
+ typescript: 5.9.3
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..2c3a369
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..89b690d
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/ui/button/Button.vue b/src/components/ui/button/Button.vue
new file mode 100644
index 0000000..374320b
--- /dev/null
+++ b/src/components/ui/button/Button.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
diff --git a/src/components/ui/button/index.ts b/src/components/ui/button/index.ts
new file mode 100644
index 0000000..5262d70
--- /dev/null
+++ b/src/components/ui/button/index.ts
@@ -0,0 +1,35 @@
+import type { VariantProps } from 'class-variance-authority'
+import { cva } from 'class-variance-authority'
+
+export { default as Button } from './Button.vue'
+
+export const buttonVariants = cva(
+ "inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
+ {
+ variants: {
+ variant: {
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
+ destructive:
+ 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
+ outline:
+ 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
+ ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
+ link: 'text-primary underline-offset-4 hover:underline',
+ },
+ size: {
+ default: 'h-9 px-4 py-2 has-[>svg]:px-3',
+ sm: 'h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5',
+ lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
+ icon: 'size-9',
+ 'icon-sm': 'size-8',
+ 'icon-lg': 'size-10',
+ },
+ },
+ defaultVariants: {
+ variant: 'default',
+ size: 'default',
+ },
+ },
+)
+export type ButtonVariants = VariantProps
diff --git a/src/components/ui/input/Input.vue b/src/components/ui/input/Input.vue
new file mode 100644
index 0000000..e5135c1
--- /dev/null
+++ b/src/components/ui/input/Input.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/src/components/ui/input/index.ts b/src/components/ui/input/index.ts
new file mode 100644
index 0000000..9976b86
--- /dev/null
+++ b/src/components/ui/input/index.ts
@@ -0,0 +1 @@
+export { default as Input } from "./Input.vue"
diff --git a/src/components/ui/sonner/Sonner.vue b/src/components/ui/sonner/Sonner.vue
new file mode 100644
index 0000000..6830896
--- /dev/null
+++ b/src/components/ui/sonner/Sonner.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ui/sonner/index.ts b/src/components/ui/sonner/index.ts
new file mode 100644
index 0000000..6673112
--- /dev/null
+++ b/src/components/ui/sonner/index.ts
@@ -0,0 +1 @@
+export { default as Toaster } from "./Sonner.vue"
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
new file mode 100644
index 0000000..c66a9d9
--- /dev/null
+++ b/src/lib/utils.ts
@@ -0,0 +1,7 @@
+import type { ClassValue } from "clsx"
+import { clsx } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..94336c5
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,6 @@
+import { createApp } from 'vue'
+import './styles/index.css'
+import App from './App.vue'
+import '@/utils/openinstall.ts'
+
+createApp(App).mount('#app')
diff --git a/src/pages/Home/Liquid-button-bg.png b/src/pages/Home/Liquid-button-bg.png
new file mode 100644
index 0000000..7211f47
Binary files /dev/null and b/src/pages/Home/Liquid-button-bg.png differ
diff --git a/src/pages/Home/bg-desktop.webp b/src/pages/Home/bg-desktop.webp
new file mode 100644
index 0000000..67822bb
Binary files /dev/null and b/src/pages/Home/bg-desktop.webp differ
diff --git a/src/pages/Home/bg-mobile.webp b/src/pages/Home/bg-mobile.webp
new file mode 100644
index 0000000..f2ffe7c
Binary files /dev/null and b/src/pages/Home/bg-mobile.webp differ
diff --git a/src/pages/Home/components/DownloadButton.vue b/src/pages/Home/components/DownloadButton.vue
new file mode 100644
index 0000000..2f41740
--- /dev/null
+++ b/src/pages/Home/components/DownloadButton.vue
@@ -0,0 +1,66 @@
+
+
+
+
+
diff --git a/src/pages/Home/components/Group 105.svg b/src/pages/Home/components/Group 105.svg
new file mode 100644
index 0000000..e2c1136
--- /dev/null
+++ b/src/pages/Home/components/Group 105.svg
@@ -0,0 +1,7 @@
+
diff --git a/src/pages/Home/components/Group 106.svg b/src/pages/Home/components/Group 106.svg
new file mode 100644
index 0000000..42552bf
--- /dev/null
+++ b/src/pages/Home/components/Group 106.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/pages/Home/components/Group 107.svg b/src/pages/Home/components/Group 107.svg
new file mode 100644
index 0000000..26e3f17
--- /dev/null
+++ b/src/pages/Home/components/Group 107.svg
@@ -0,0 +1,6 @@
+
diff --git a/src/pages/Home/components/Group 108.svg b/src/pages/Home/components/Group 108.svg
new file mode 100644
index 0000000..ea8d296
--- /dev/null
+++ b/src/pages/Home/components/Group 108.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/pages/Home/connected-bg.png b/src/pages/Home/connected-bg.png
new file mode 100644
index 0000000..b7a217a
Binary files /dev/null and b/src/pages/Home/connected-bg.png differ
diff --git a/src/pages/Home/connected-mobile-bg.png b/src/pages/Home/connected-mobile-bg.png
new file mode 100644
index 0000000..e4c284a
Binary files /dev/null and b/src/pages/Home/connected-mobile-bg.png differ
diff --git a/src/pages/Home/hiLogo.svg b/src/pages/Home/hiLogo.svg
new file mode 100644
index 0000000..6264878
--- /dev/null
+++ b/src/pages/Home/hiLogo.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/pages/Home/image-1.png b/src/pages/Home/image-1.png
new file mode 100644
index 0000000..526f87e
Binary files /dev/null and b/src/pages/Home/image-1.png differ
diff --git a/src/pages/Home/index.vue b/src/pages/Home/index.vue
new file mode 100644
index 0000000..fc94bd0
--- /dev/null
+++ b/src/pages/Home/index.vue
@@ -0,0 +1,182 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![App Screenshot]()
+
+
+
+
+
+
+
+
+
+
+
最新加密协议-安全有保障
+
IEPL专线-纯净、稳定
+
不限速/不限流-网速多快,Hi快多快
+
极速闪连-永远快人一步
+
+
+
+

+
+
+
+
+
+
+
+
+
![App Screenshot]()
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/Home/logo.svg b/src/pages/Home/logo.svg
new file mode 100644
index 0000000..b23a2dd
--- /dev/null
+++ b/src/pages/Home/logo.svg
@@ -0,0 +1,9 @@
+
diff --git a/src/pages/Home/mobile-logo.svg b/src/pages/Home/mobile-logo.svg
new file mode 100644
index 0000000..7be4d9c
--- /dev/null
+++ b/src/pages/Home/mobile-logo.svg
@@ -0,0 +1,18 @@
+
diff --git a/src/pages/Home/screenshot-desktop.webp b/src/pages/Home/screenshot-desktop.webp
new file mode 100644
index 0000000..047cb64
Binary files /dev/null and b/src/pages/Home/screenshot-desktop.webp differ
diff --git a/src/pages/Home/screenshot-mobile.png b/src/pages/Home/screenshot-mobile.png
new file mode 100644
index 0000000..bde8220
Binary files /dev/null and b/src/pages/Home/screenshot-mobile.png differ
diff --git a/src/pages/Home/x-logo.png b/src/pages/Home/x-logo.png
new file mode 100644
index 0000000..5c647a2
Binary files /dev/null and b/src/pages/Home/x-logo.png differ
diff --git a/src/styles/index.css b/src/styles/index.css
new file mode 100644
index 0000000..9912913
--- /dev/null
+++ b/src/styles/index.css
@@ -0,0 +1,186 @@
+@font-face {
+ font-family: 'Roboto';
+ src: url('/src/styles/roboto.woff2') format('woff2');
+ font-weight: 100 900;
+ font-style: normal;
+ font-display: swap;
+}
+html, body {
+ background: #000;
+}
+.lucid-glass-bar {
+ /* 基础背景:Figma 中通常是叠加的,这里取中值确保通透度 */
+ background: rgb(255 255 255 / 6%);
+
+ /* 核心模糊 */
+ @apply backdrop-blur-[36px];
+
+ /* 圆角:由于你有 border-image,建议使用这种方式保留圆角 */
+ border-radius: 999px;
+
+ /* 边框:Figma 的 border-image 在 CSS 圆角容器上会有兼容问题
+ 建议改用单纯的 border 配合 rgba 以达到线性渐变的效果 */
+ border: 1px solid rgba(255, 255, 255, 0.2);
+
+ /* 阴影叠加:按照 Figma 从上到下的顺序转换 */
+ box-shadow:
+ /* 1. 这里的 #F2F2F280 33px 扩散是导致发白的主因,建议将其放在最底层并调低不透明度 */
+ inset 0px 0px 33px 0px rgba(242, 242, 242, 0.15),
+
+ /* 2. 右下角的反向高光 (原本的 -3px -4.5px) */
+ inset 0px -2px 1.5px -3px rgba(179, 179, 179, 0.5),
+
+ /* 3. 左上角的微弱亮边 */
+ inset 3px 4.5px 1.5px -3px rgba(179, 179, 179, 0.2),
+
+ /* 4. 核心受光面 (Figma: 4.5px 4.5px #FFFFFF80) */
+ inset 4.5px 4.5px 1.5px -5.25px rgba(255, 255, 255, 0.4),
+
+ /* 5. 核心背光面 (Figma: -4.5px -4.5px #FFFFFF80) */
+ inset -4.5px -4.5px 1.5px -5.25px rgba(255, 255, 255, 0.3);
+}
+
+@import "tailwindcss";
+@import "tw-animate-css";
+
+@layer components {
+ .container {
+ width: 100%;
+ margin-left: auto;
+ margin-right: auto;
+
+ /* 1. 移动端默认:左右 18px 边距 */
+ padding-left: 18px;
+ padding-right: 18px;
+
+ /* 2. 桌面端逻辑:当屏幕达到 1440px 及以上 */
+ @media (width >= 1440px) {
+ /* 计算公式:
+ 内容区固定为 1268px
+ 侧边留白 = (1440 - 1268) / 2 = 86px
+ */
+ max-width: 1268px;
+
+ /* 此时 padding 可以设为 0,因为 max-width 配合 margin: auto 已经产生了 86px 的留白 */
+ padding-left: 0;
+ padding-right: 0;
+ }
+ }
+}
+@custom-variant dark (&:is(.dark *));
+
+@theme inline {
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+ --radius-xl: calc(var(--radius) + 4px);
+ --color-background: var(--background);
+ --color-foreground: var(--foreground);
+ --color-card: var(--card);
+ --color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
+ --color-primary: var(--primary);
+ --color-primary-foreground: var(--primary-foreground);
+ --color-secondary: var(--secondary);
+ --color-secondary-foreground: var(--secondary-foreground);
+ --color-muted: var(--muted);
+ --color-muted-foreground: var(--muted-foreground);
+ --color-accent: var(--accent);
+ --color-accent-foreground: var(--accent-foreground);
+ --color-destructive: var(--destructive);
+ --color-border: var(--border);
+ --color-input: var(--input);
+ --color-ring: var(--ring);
+ --color-chart-1: var(--chart-1);
+ --color-chart-2: var(--chart-2);
+ --color-chart-3: var(--chart-3);
+ --color-chart-4: var(--chart-4);
+ --color-chart-5: var(--chart-5);
+ --color-sidebar: var(--sidebar);
+ --color-sidebar-foreground: var(--sidebar-foreground);
+ --color-sidebar-primary: var(--sidebar-primary);
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
+ --color-sidebar-accent: var(--sidebar-accent);
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
+ --color-sidebar-border: var(--sidebar-border);
+ --color-sidebar-ring: var(--sidebar-ring);
+}
+
+:root {
+ --radius: 0.625rem;
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.145 0 0);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.145 0 0);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.145 0 0);
+ --primary: oklch(0.205 0 0);
+ --primary-foreground: oklch(0.985 0 0);
+ --secondary: oklch(0.97 0 0);
+ --secondary-foreground: oklch(0.205 0 0);
+ --muted: oklch(0.97 0 0);
+ --muted-foreground: oklch(0.556 0 0);
+ --accent: oklch(0.97 0 0);
+ --accent-foreground: oklch(0.205 0 0);
+ --destructive: oklch(0.577 0.245 27.325);
+ --border: oklch(0.922 0 0);
+ --input: oklch(0.922 0 0);
+ --ring: oklch(0.708 0 0);
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.145 0 0);
+ --sidebar-primary: oklch(0.205 0 0);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.97 0 0);
+ --sidebar-accent-foreground: oklch(0.205 0 0);
+ --sidebar-border: oklch(0.922 0 0);
+ --sidebar-ring: oklch(0.708 0 0);
+}
+
+.dark {
+ --background: oklch(0.145 0 0);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.205 0 0);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.205 0 0);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.922 0 0);
+ --primary-foreground: oklch(0.205 0 0);
+ --secondary: oklch(0.269 0 0);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.269 0 0);
+ --muted-foreground: oklch(0.708 0 0);
+ --accent: oklch(0.269 0 0);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.704 0.191 22.216);
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.556 0 0);
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ --sidebar: oklch(0.205 0 0);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.269 0 0);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(1 0 0 / 10%);
+ --sidebar-ring: oklch(0.556 0 0);
+}
+
+@layer base {
+ * {
+ @apply border-border outline-ring/50;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/src/styles/roboto.woff2 b/src/styles/roboto.woff2
new file mode 100644
index 0000000..0943c6b
Binary files /dev/null and b/src/styles/roboto.woff2 differ
diff --git a/src/utils/constant.ts b/src/utils/constant.ts
new file mode 100644
index 0000000..dad7cb4
--- /dev/null
+++ b/src/utils/constant.ts
@@ -0,0 +1,7 @@
+// utils/constant.ts
+const BASE_URL = window.location.origin // 自动获取当前域名
+
+export const downLoadAndroid = `${BASE_URL}/download/app-arm64-v8a-release.apk`
+export const downLoadMac = `${BASE_URL}/download/HiFastVPN-1.0.0+100-macos.dmg`
+export const downLoadWin = `${BASE_URL}/download/HiFastVPN-0.0.2-windows-setup.exe`
+export const downLoadIos = 'https://apps.apple.com/us/app/hi%E5%BF%ABvpn/id6755683167'
diff --git a/src/utils/openinstall.ts b/src/utils/openinstall.ts
new file mode 100644
index 0000000..65faf54
--- /dev/null
+++ b/src/utils/openinstall.ts
@@ -0,0 +1,72 @@
+import { getAllQuertString } from '@/utils/url-utils.ts'
+
+/**
+ * OpenInstall sdk 用于上报h5邀请参数
+ * 自动注册openinstall sdk 挂在到window对象上 通过window.OI_SDK访问
+ * sdk初始化时会自动检索url上的参数并作为拉起下载或唤醒app时的参数
+ */
+const script = document.createElement('script')
+script.type = 'text/javascript'
+script.charset = 'UTF-8'
+script.src = 'https://web.cdn.openinstall.io/openinstall.js'
+document.head.appendChild(script)
+
+script.addEventListener('load', () => {
+ window.OI_SDK = new OpenInstallSdk()
+})
+
+class OpenInstallSdk {
+ public urlQuery: any // openinstall.js中提供的api,解析当前网页url中的查询参数并对data进行赋值
+
+ public OI: Record // openinstall 实例
+
+ constructor() {
+ this.OI = {}
+ this.urlQuery = window.OpenInstall.parseUrlParams()
+ const id = getAllQuertString('id')
+ if (id) {
+ this.urlQuery = {
+ platform: 'merchant',
+ code: id,
+ }
+ }
+ this.init()
+ }
+
+ async init() {
+ try {
+ this.OI = new window.OpenInstall({
+ appKey: 'alf57p',
+ onready: function () { // 初始化成功回调方法。当初始化完成后,会自动进入
+ this.schemeWakeup()// 尝试使用scheme打开App(主要用于Android以及iOS的QQ环境中)
+ const m = this
+ const button = document.getElementById('downloadButton_apple')
+ const button1 = document.getElementById('downloadButton_android')
+ const ic = getAllQuertString('ic')
+ if (button) {
+ button.onclick = function () {
+ if (ic) {
+ m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
+ } else {
+ m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
+ }
+ return false
+ }
+ }
+ if (button1) {
+ button1.onclick = function () {
+ if (ic) {
+ m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
+ } else {
+ m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
+ }
+ return false
+ }
+ }
+ },
+ }, this.urlQuery)// 初始化时传入data,作为一键拉起/App传参安装时候的参数
+ } catch (e) {
+ console.log(e, 'OpenInstall——sdk初始化失败')
+ }
+ }
+}
diff --git a/src/utils/request/cancel.ts b/src/utils/request/cancel.ts
new file mode 100644
index 0000000..f63a223
--- /dev/null
+++ b/src/utils/request/cancel.ts
@@ -0,0 +1,58 @@
+import type { AxiosRequestConfig, Canceler } from 'axios'
+import axios from 'axios'
+
+// Used to store the identification and cancellation function of each request
+let pendingMap = new Map()
+
+const getPendingUrl = (config: AxiosRequestConfig) => [config.method, config.url].join('&')
+
+export class AxiosCanceler {
+ /**
+ * Add request
+ * @param {Object} config
+ */
+ addPending(config: AxiosRequestConfig): void {
+ this.removePending(config)
+ const url = getPendingUrl(config)
+ config.cancelToken = config.cancelToken
+ || new axios.CancelToken((cancel) => {
+ if (!pendingMap.has(url)) {
+ // If there is no current request in pending, add it
+ pendingMap.set(url, cancel)
+ }
+ })
+ }
+
+ /**
+ * @description: Clear all pending
+ */
+ removeAllPending(): void {
+ pendingMap.forEach((cancel) => {
+ cancel?.()
+ })
+ pendingMap.clear()
+ }
+
+ /**
+ * Removal request
+ * @param {Object} config
+ */
+ removePending(config: AxiosRequestConfig): void {
+ const url = getPendingUrl(config)
+
+ if (pendingMap.has(url)) {
+ // If there is a current request identifier in pending,
+ // the current request needs to be cancelled and removed
+ const cancel = pendingMap.get(url)
+ cancel && cancel(url)
+ pendingMap.delete(url)
+ }
+ }
+
+ /**
+ * @description: reset
+ */
+ reset(): void {
+ pendingMap = new Map()
+ }
+}
diff --git a/src/utils/request/core.ts b/src/utils/request/core.ts
new file mode 100644
index 0000000..c6bb05a
--- /dev/null
+++ b/src/utils/request/core.ts
@@ -0,0 +1,269 @@
+import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
+import axios from 'axios'
+import { AxiosCanceler } from './cancel'
+import { toast } from 'vue-sonner'
+export interface ExtraConfig {
+ /**
+ * 默认值 1 错误等级 0-忽略,1-warning,2-error
+ */
+ errorLevel?: 0 | 1 | 2
+ /**
+ * 默认true 是否携带token
+ */
+ withToken?: boolean
+ /**
+ * 默认true 是否处理响应
+ */
+ handleResponse?: boolean
+ /**
+ * 默认false 是否取消重复请求
+ */
+ cancelRepetition?: boolean
+ /**
+ * 默认false 是否返回axios完整响应
+ */
+ originResponseData?: boolean
+ /**
+ * 默认token 存储key
+ */
+ tokenKey?: string
+ /**
+ * 获取token的方法
+ */
+ getToken?: () => string
+ /**
+ * 自定义header方法,此方法返回的header会覆盖默认的header
+ */
+ formatHeader?: (header: Record) => Record
+}
+
+export interface RequestConfig extends AxiosRequestConfig {
+ extraConfig?: ExtraConfig
+}
+
+interface ResponseType extends AxiosResponse {
+ config: RequestConfig
+}
+
+const ERROR_MESSAGES: Record = {
+ '200': '成功',
+ '500': '内部服务器错误',
+ '10001': '数据库查询错误',
+ '10002': '数据库更新错误',
+ '10003': '数据库插入错误',
+ '10004': '数据库删除错误',
+ '20001': '用户已存在',
+ '20002': '用户不存在',
+ '20003': '用户密码错误',
+ '20004': '用户已禁用',
+ '20005': '余额不足',
+ '20006': '停止注册',
+ '20007': '未绑定Telegram',
+ '20008': '用户未绑定OAuth方式',
+ '20009': '邀请码错误',
+ '30001': '节点已存在',
+ '30002': '节点不存在',
+ '30003': '节点组已存在',
+ '30004': '节点组不存在',
+ '30005': '节点组不为空',
+ '400': '参数错误',
+ '40002': '用户令牌为空',
+ '40003': '用户令牌无效',
+ '40004': '用户令牌已过期',
+ '40005': '您还没有登录',
+ '401': '请求过多',
+ '50001': '优惠券不存在',
+ '50002': '优惠券已被使用',
+ '50003': '优惠券不匹配',
+ '60001': '订阅已过期',
+ '60002': '订阅不可用',
+ '60003': '用户已有订阅',
+ '60004': '订阅已被使用',
+ '60005': '单一订阅模式超出限制',
+ '60006': '订阅配额限制',
+ '70001': '验证码错误',
+ '80001': '队列入队错误',
+ '90001': '调试模式已启用',
+ '90002': '发送短信错误',
+ '90003': '短信功能未启用',
+ '90004': '电子邮件功能未启用',
+ '90005': '不支持的登录方式',
+ '90006': '身份验证器不支持此方式',
+ '90007': '电话区号为空',
+ '90008': '密码为空',
+ '90009': '区号为空',
+ '90010': '需要密码或验证码',
+ '90011': '电子邮件已存在',
+ '90012': '电话号码已存在',
+ '90013': '设备已存在',
+ '90014': '电话号码错误',
+ '90015': '此账户今日已达到发送次数限制',
+ '90017': '设备不存在',
+ '90018': '用户 ID 不匹配',
+ '61001': '订单不存在',
+ '61002': '支付方式未找到',
+ '61003': '订单状态错误',
+ '61004': '重置周期不足',
+ '61005': '存在没用完的流量',
+}
+
+export default class Request {
+ public axiosInstance: AxiosInstance
+
+ private config: RequestConfig
+
+ constructor(config: RequestConfig) {
+ this.config = config
+ this.axiosInstance = axios.create(config)
+ this.init()
+ }
+
+ static defaultConfig: Required = {
+ errorLevel: 2,
+ withToken: true,
+ handleResponse: true,
+ cancelRepetition: false,
+ originResponseData: false,
+ tokenKey: 'token',
+ formatHeader: (headers) => {
+ return headers
+ },
+ getToken: () => '',
+ }
+
+ private errorReport(lv: number, message: string) {
+ toast(message)
+ }
+
+ private init() {
+ const axiosCanceler = new AxiosCanceler()
+
+ this.axiosInstance.interceptors.request.use(
+ (config: RequestConfig) => {
+ const mergeExtraConfig = {
+ ...Request.defaultConfig,
+ ...this.config.extraConfig,
+ ...config.extraConfig,
+ }
+
+ // if (config.data && !(config.data instanceof FormData)) {
+ // const plainText = JSON.stringify(config.data)
+ // config.data = HiAesUtil.encryptData(plainText, encryptionKey)
+ // }
+ //
+ // if (config.method?.toLowerCase() === 'get' || config.params) {
+ // const paramsToEncrypt = config.params || {}
+ // const plainParamsText = JSON.stringify(paramsToEncrypt)
+ // const encryptedParams = HiAesUtil.encryptData(plainParamsText, encryptionKey)
+ //
+ // config.params = {
+ // data: encryptedParams.data,
+ // time: encryptedParams.time,
+ // }
+ // }
+
+ config.headers = mergeExtraConfig.formatHeader({
+ ...this.config.headers,
+ ...config.headers,
+ lang: 'zh_CN',
+ // 'login-type': 'device',
+ ...(mergeExtraConfig.withToken && {
+ [mergeExtraConfig.tokenKey]: mergeExtraConfig.getToken(),
+ }),
+ } as any)
+ config.extraConfig = mergeExtraConfig
+ if (mergeExtraConfig.cancelRepetition) {
+ axiosCanceler.addPending(config)
+ }
+ return config
+ },
+ (error) => {
+ this.errorReport(error?.config.extraConfig.errorLevel, error)
+ return Promise.reject(error)
+ },
+ )
+
+ this.axiosInstance.interceptors.response.use(
+ (response: ResponseType) => {
+ const { data, config } = response
+ const responseData = response.data.data
+
+ // if (responseData && responseData.data && responseData.time) {
+ // try {
+ // const decryptedStr = HiAesUtil.decryptData(
+ // responseData.data,
+ // responseData.time,
+ // encryptionKey,
+ // )
+ // responseData = JSON.parse(decryptedStr)
+ // } catch (e) {
+ // console.error('解密失败:', e)
+ // return Promise.reject({ message: '数据解密异常' })
+ // }
+ // }
+ axiosCanceler.removePending(config)
+
+ if (data.code !== 200) {
+ const msg = ERROR_MESSAGES[data.code] || response.data?.msg || data?.error || '未知错误'
+ if (data.code == 40004 || data.code == 40003 || data.code == 40005) {
+ toast.error(msg)
+ return
+ }
+
+ if (config.extraConfig?.handleResponse) {
+ this.errorReport(config.extraConfig.errorLevel ?? 2, msg)
+ return Promise.reject({
+ ...data,
+ message: msg,
+ })
+ }
+ }
+
+ return config.extraConfig?.originResponseData ? response : responseData
+ },
+ (error) => {
+ const status = error?.response?.status
+ const code = error?.code
+ let message = error?.message
+ if (status === 401) {
+ return
+ }
+ if (code === 'ECONNABORTED') {
+ message = '网络环境太差,请求超时'
+ } else if (code === 'Network Error' || message === 'Network Error') {
+ if (error.response) {
+ message = `${error.response.status}:network连接失败,请求中断`
+ } else {
+ message = '网络好像出现问题了'
+ }
+ }
+ if (error.__CANCEL__) {
+ console.warn('request canceled', error?.message)
+ } else {
+ this.errorReport(error?.config?.extraConfig?.errorLevel, message)
+ }
+ return Promise.reject(error)
+ },
+ )
+ }
+
+ public get(url: string, params?: Record, config?: RequestConfig): Promise {
+ return this.axiosInstance.get(url, { ...config, params })
+ }
+
+ public post(url: string, data?: D, config?: RequestConfig): Promise {
+ return this.axiosInstance.post(url, data, { ...config })
+ }
+
+ public put(url: string, data?: D, config?: RequestConfig): Promise {
+ return this.axiosInstance.put(url, data, { ...config })
+ }
+
+ public patch(url: string, data?: D, config?: RequestConfig): Promise {
+ return this.axiosInstance.patch(url, data, { ...config })
+ }
+
+ public delete(url: string, params?: D, config?: RequestConfig): Promise {
+ return this.axiosInstance.delete(url, { ...config, params })
+ }
+}
diff --git a/src/utils/request/index.ts b/src/utils/request/index.ts
new file mode 100644
index 0000000..eafe3c5
--- /dev/null
+++ b/src/utils/request/index.ts
@@ -0,0 +1,16 @@
+import Request from './core'
+export * from './core'
+const baseUrl = import.meta.env.VITE_APP_BASE_URL
+
+const request = new Request({
+ baseURL: baseUrl,
+ timeout: 6000,
+ headers: {},
+ extraConfig: {
+ /** 这里是核心配置,一般不需要再去修改request/core.ts */
+ tokenKey: 'Authorization',
+ getToken: () => localStorage.getItem('Authorization') || '',
+ },
+})
+
+export default request
diff --git a/src/utils/url-utils.ts b/src/utils/url-utils.ts
new file mode 100644
index 0000000..c8c24d9
--- /dev/null
+++ b/src/utils/url-utils.ts
@@ -0,0 +1,157 @@
+/**
+ * 拼接参数
+ * @param {Object} data
+ */
+export const param = data => {
+ if (!data) {
+ return ''
+ }
+
+ let url = ''
+ for (const k in data) {
+ const value = data[k] !== undefined ? data[k] : ''
+ url += `&${k}=${encodeURIComponent(value)}`
+ }
+ return url ? url.substr(1) : ''
+}
+/**
+ * 拼接参数,处理对象类型数据
+ */
+export const paramToObj = data => {
+ if (!data) {
+ return ''
+ }
+ let url = ''
+ for (const k in data) {
+ const value = data[k] !== undefined ? data[k] : ''
+ if (typeof value === 'object') {
+ url += `&${k}=${encodeURIComponent(JSON.stringify(value))}`
+ } else {
+ url += `&${k}=${encodeURIComponent(value)}`
+ }
+ }
+ return url ? url.substr(1) : ''
+}
+
+/**
+ * 为了获取微信登录的code
+ * @param {string} name
+ */
+export const getQueryString = name => {
+ const reg = `(^|&)${name}=([^&]*)(&|$)`
+ const query = window.location.search.substr(1) || window.location.hash.split('?')[1]
+ const r = query ? query.match(reg) : null
+ if (r != null) return decodeURIComponent(r[2])
+ return null
+}
+
+/**
+ * 为了获取URL上的值
+ * @param {*} name 需要获取的key
+ * @param {*} isMerge 是否合并hash和search,search优先级高
+ */
+export const getAllQuertString = (name, isMerge = true) => {
+ const reg = `(?:^|&)${name}=([^&]*)(?:&|$)`
+ const search = window.location.search.substr(1)
+ const hash = window.location.hash.split('?')[1]
+ const searchR = search ? search.match(reg) && search.match(reg)![1] : null
+ const hashR = hash ? hash.match(reg) && hash.match(reg)![1] : null
+ if (isMerge) {
+ const result = searchR || hashR
+ return result ? unescape(result) : null
+ }
+ return {
+ search: searchR ? unescape(searchR) : null,
+ hash: hashR ? unescape(hashR) : null,
+ }
+}
+
+/**
+ * 授权时把所有参数进行筛选,防止二次授权存在多个code情况
+ * @param {string} url
+ */
+export function parseURL(url) {
+ const a = document.createElement('a')
+ a.href = url
+ const protocol = a.protocol.replace(':', '')
+ const host = a.hostname
+ const path = a.pathname.replace(/^([^\/])/, '/$1')
+ return {
+ href: `${protocol}://${host}${path}?`,
+ source: url,
+ protocol,
+ host,
+ port: a.port,
+ query: a.search,
+ params: (function () {
+ const params = {}
+ const seg = a.search.replace(/^\?/, '').split('&')
+ const len = seg.length
+ let p
+ for (let i = 0; i < len; i++) {
+ if (seg[i]) {
+ p = seg[i].split('=')
+ params[p[0]] = p[1]
+ }
+ }
+ return params
+ }()),
+ hash: a.hash.replace('#', ''),
+ path,
+ }
+}
+
+/**
+ * 获取url query对象
+ */
+export function urlGetParam() {
+ const t = location.search
+ .substring(1)
+ .split('&')
+ .filter(item => !!item)
+ const f = {}
+ for (let i = 0; i < t.length; i++) {
+ const x = t[i].split('=')
+ f[x[0]] = x[1]
+ }
+ return f
+}
+
+/**
+ * 批量删除地址参数
+ * @param {array} removes 需要删除的参数
+ * @param {boolean} hash 返回的链接是否拼上hash值
+ */
+export function removeUrlQuery(removes, isHash = false) {
+ const currentParam = urlGetParam()
+ removes.forEach(removeItem => {
+ delete currentParam[removeItem]
+ })
+ return `${location.origin}${location.pathname}?${param(currentParam)}${
+ isHash ? location.hash : ''
+ }`
+}
+
+/**
+ * 获取链接上的keyValue
+ */
+export function hrefKeyValue(key, url) {
+ const reg = new RegExp(/(\w+)=(\w+)/, 'gi')
+ const currentUrl = url || location.href
+ const results = currentUrl.match(reg)
+ if (results) {
+ const resultKeyValues = results.map(o => ({
+ [o.split('=')[0]]: o.split('=')[1],
+ }))
+ const result = resultKeyValues.find(o => o.hasOwnProperty(key))
+ return (result && result[key]) || null
+ }
+ return null
+}
+/**
+ * 替换url中的参数
+ */
+export function replaceQueryString(url, name, value) {
+ const re = new RegExp(name + '=[^&]*', 'gi')
+ return url.replace(re, name + '=' + value)
+}
diff --git a/tsconfig.app.json b/tsconfig.app.json
new file mode 100644
index 0000000..8d16e42
--- /dev/null
+++ b/tsconfig.app.json
@@ -0,0 +1,16 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "types": ["vite/client"],
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..6421ddd
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,18 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ],
+ /* 必须在根目录也加上这部分,让 shadcn 的脚本能读到 */
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/tsconfig.node.json b/tsconfig.node.json
new file mode 100644
index 0000000..8a67f62
--- /dev/null
+++ b/tsconfig.node.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2023",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "types": ["node"],
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "erasableSyntaxOnly": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 0000000..b3fe030
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,35 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import tailwindcss from '@tailwindcss/vite'
+import svgLoader from 'vite-svg-loader'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [vue(), tailwindcss(),svgLoader()],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
+ },
+ },
+ server: {
+ proxy: {
+ // 将所有以 /api 开头的请求转发到目标服务器
+ // 1. 匹配所有以 /public 开头的请求
+ '/api/v1': {
+ target: 'https://hifastvpn.com',
+ changeOrigin: true,
+ // rewrite: (path) => path.replace(/^\/api/, ''),
+ autoRewrite: true,
+ // 3. 关键:将路径重写,在前面补上 /api/v1
+ // 验证请求是否进入代理,可以在终端看到打印
+ configure: (proxy, _options) => {
+ proxy.on('proxyReq', (proxyReq, req, _res) => {
+ console.log('代理请求:', req.method, req.url, ' -> ', proxyReq.path)
+ })
+ },
+ },
+ },
+ },
+})