commit 293951a6102b07168ab71c39ce75c1d167918ab9 Author: leilei Date: Fri Sep 19 17:24:46 2025 +0800 项目初始化 diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..6d1fc1d --- /dev/null +++ b/.env.development @@ -0,0 +1,18 @@ +# 开发环境配置 +VITE_APP_ENV = 'development' + +VITE_BASE_PATH = '/' + +VITE_APP_PORT = 80 + +# 应用模板管理后台/开发环境 +VITE_APP_BASE_API = '/dev-api' + +# 后端实际地址(可选,用于proxy.target) +VITE_API_TARGET = 'https://xsynergy.gxtech.ltd' + +# 公网为“ web ” 私有化为不跳转为“ private ” 私有化跳转为“ skip ” +VITE_APP_COOPERATION_TYPE = 'skip' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..d330703 --- /dev/null +++ b/.env.production @@ -0,0 +1,15 @@ +# 生产环境配置 +VITE_APP_ENV = 'production' + +VITE_APP_PORT = 80 + +VITE_BASE_PATH = '/' + +# 应用模板管理后台/生产环境 +VITE_APP_BASE_API = 'https://xsynergy.gxtech.ltd' + +# 公网为“web” 私有化为不跳转为“private” 私有化跳转为“skip” +VITE_APP_COOPERATION_TYPE = 'skip' + +# 是否在打包时开启压缩,支持 gzip 和 brotli +VITE_BUILD_COMPRESS = gzip \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ee54e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo 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/README.md b/README.md new file mode 100644 index 0000000..b8203e3 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# tabula-rase-project + +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## Customize configuration + +See [Vite Configuration Reference](https://vite.dev/config/). + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Compile and Minify for Production + +```sh +npm run build +``` diff --git a/index.html b/index.html new file mode 100644 index 0000000..eaea997 --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + 互动白板 + + +
+ + + diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..540a53f --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "strict": false, + "jsx": "preserve", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "checkJs": true, + "lib": ["esnext", "dom"] + }, + "include": ["src/**/*.js", "src/**/*.vue"], + "exclude": ["node_modules", "dist"] + } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5075944 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3924 @@ +{ + "name": "tabula-rase-project", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tabula-rase-project", + "version": "0.0.0", + "license": "MIT", + "dependencies": { + "@element-plus/icons-vue": "^2.0.10", + "autoprefixer": "^10.4.21", + "axios": "^0.27.2", + "code-inspector-plugin": "^0.20.12", + "element-plus": "^2.2.27", + "js-cookie": "^3.0.1", + "mitt": "^3.0.0", + "mqtt": "^5.14.0", + "pinia": "^2.0.22", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.1", + "uuid": "^11.1.0", + "vue": "^3.5.12", + "vue-router": "^4.4.5" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.1.4", + "sass": "^1.56.1", + "unplugin-auto-import": "^20.1.0", + "unplugin-vue-components": "^29.0.0", + "vite": "^5.4.10" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.3", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "dependencies": { + "@babel/types": "^7.28.2" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.3", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.3.tgz", + "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.2", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.0.10.tgz", + "integrity": "sha512-ygEZ1mwPjcPo/OulhzLE7mtDrQBWI8vZzEWSNB2W/RNCRjoQGwbaK4N8lV4rid7Ts4qvySU3njMN7YCiSlSaTQ==", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.7.3", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.3.tgz", + "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", + "dependencies": { + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.7.4", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.4.tgz", + "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", + "dependencies": { + "@floating-ui/core": "^1.7.3", + "@floating-ui/utils": "^0.2.10" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.10", + "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.30", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", + "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.0.tgz", + "integrity": "sha512-lVgpeQyy4fWN5QYebtW4buT/4kn4p4IJ+kDNB4uYNT5b8c8DLJDg6titg20NIg7E8RWwdWZORW6vUFfrLyG3KQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.0.tgz", + "integrity": "sha512-2O73dR4Dc9bp+wSYhviP6sDziurB5/HCym7xILKifWdE9UsOe2FtNcM+I4xZjKrfLJnq5UR8k9riB87gauiQtw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.0.tgz", + "integrity": "sha512-vwSXQN8T4sKf1RHr1F0s98Pf8UPz7pS6P3LG9NSmuw0TVh7EmaE+5Ny7hJOZ0M2yuTctEsHHRTMi2wuHkdS6Hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.0.tgz", + "integrity": "sha512-cQp/WG8HE7BCGyFVuzUg0FNmupxC+EPZEwWu2FCGGw5WDT1o2/YlENbm5e9SMvfDFR6FRhVCBePLqj0o8MN7Vw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.0.tgz", + "integrity": "sha512-UR1uTJFU/p801DvvBbtDD7z9mQL8J80xB0bR7DqW7UGQHRm/OaKzp4is7sQSdbt2pjjSS72eAtRh43hNduTnnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.0.tgz", + "integrity": "sha512-G/DKyS6PK0dD0+VEzH/6n/hWDNPDZSMBmqsElWnCRGrYOb2jC0VSupp7UAHHQ4+QILwkxSMaYIbQ72dktp8pKA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.0.tgz", + "integrity": "sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.0.tgz", + "integrity": "sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.0.tgz", + "integrity": "sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.0.tgz", + "integrity": "sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.50.0.tgz", + "integrity": "sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.0.tgz", + "integrity": "sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.0.tgz", + "integrity": "sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.0.tgz", + "integrity": "sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.0.tgz", + "integrity": "sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.0.tgz", + "integrity": "sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.0.tgz", + "integrity": "sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.0.tgz", + "integrity": "sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.0.tgz", + "integrity": "sha512-q7cIIdFvWQoaCbLDUyUc8YfR3Jh2xx3unO8Dn6/TTogKjfwrax9SyfmGGK6cQhKtjePI7jRfd7iRYcxYs93esg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.0.tgz", + "integrity": "sha512-XzNOVg/YnDOmFdDKcxxK410PrcbcqZkBmz+0FicpW5jtjKQxcW1BZJEQOF0NJa6JO7CZhett8GEtRN/wYLYJuw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz", + "integrity": "sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "24.3.0", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "dependencies": { + "undici-types": "~7.10.0" + } + }, + "node_modules/@types/readable-stream": { + "version": "4.0.21", + "resolved": "https://registry.npmmirror.com/@types/readable-stream/-/readable-stream-4.0.21.tgz", + "integrity": "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.20.tgz", + "integrity": "sha512-8TWXUyiqFd3GmP4JTX9hbiTFRwYHgVL/vr3cqhr4YQ258+9FADwvj7golk2sWNGHR67QgmCZ8gz80nQcMokhwg==", + "dependencies": { + "@babel/parser": "^7.28.3", + "@vue/shared": "3.5.20", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.20.tgz", + "integrity": "sha512-whB44M59XKjqUEYOMPYU0ijUV0G+4fdrHVKDe32abNdX/kJe1NUEMqsi4cwzXa9kyM9w5S8WqFsrfo1ogtBZGQ==", + "dependencies": { + "@vue/compiler-core": "3.5.20", + "@vue/shared": "3.5.20" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.20.tgz", + "integrity": "sha512-SFcxapQc0/feWiSBfkGsa1v4DOrnMAQSYuvDMpEaxbpH5dKbnEM5KobSNSgU+1MbHCl+9ftm7oQWxvwDB6iBfw==", + "dependencies": { + "@babel/parser": "^7.28.3", + "@vue/compiler-core": "3.5.20", + "@vue/compiler-dom": "3.5.20", + "@vue/compiler-ssr": "3.5.20", + "@vue/shared": "3.5.20", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.17", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.20.tgz", + "integrity": "sha512-RSl5XAMc5YFUXpDQi+UQDdVjH9FnEpLDHIALg5J0ITHxkEzJ8uQLlo7CIbjPYqmZtt6w0TsIPbo1izYXwDG7JA==", + "dependencies": { + "@vue/compiler-dom": "3.5.20", + "@vue/shared": "3.5.20" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, + "node_modules/@vue/reactivity": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.20.tgz", + "integrity": "sha512-hS8l8x4cl1fmZpSQX/NXlqWKARqEsNmfkwOIYqtR2F616NGfsLUm0G6FQBK6uDKUCVyi1YOL8Xmt/RkZcd/jYQ==", + "dependencies": { + "@vue/shared": "3.5.20" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.20.tgz", + "integrity": "sha512-vyQRiH5uSZlOa+4I/t4Qw/SsD/gbth0SW2J7oMeVlMFMAmsG1rwDD6ok0VMmjXY3eI0iHNSSOBilEDW98PLRKw==", + "dependencies": { + "@vue/reactivity": "3.5.20", + "@vue/shared": "3.5.20" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.20.tgz", + "integrity": "sha512-KBHzPld/Djw3im0CQ7tGCpgRedryIn4CcAl047EhFTCCPT2xFf4e8j6WeKLgEEoqPSl9TYqShc3Q6tpWpz/Xgw==", + "dependencies": { + "@vue/reactivity": "3.5.20", + "@vue/runtime-core": "3.5.20", + "@vue/shared": "3.5.20", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.20.tgz", + "integrity": "sha512-HthAS0lZJDH21HFJBVNTtx+ULcIbJQRpjSVomVjfyPkFSpCwvsPTA+jIzOaUm3Hrqx36ozBHePztQFg6pj5aKg==", + "dependencies": { + "@vue/compiler-ssr": "3.5.20", + "@vue/shared": "3.5.20" + }, + "peerDependencies": { + "vue": "3.5.20" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.20.tgz", + "integrity": "sha512-SoRGP596KU/ig6TfgkCMbXkr4YJ91n/QSdMuqeP5r3hVIYA3CPHUBCc7Skak0EAKV+5lL4KyIh61VA/pK1CIAA==" + }, + "node_modules/@vueuse/core": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz", + "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/metadata": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz", + "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz", + "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmmirror.com/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmmirror.com/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "6.1.2", + "resolved": "https://registry.npmmirror.com/bl/-/bl-6.1.2.tgz", + "integrity": "sha512-6J3oG82fpJ71WF4l0W6XslkwAPMr+Zcp+AmdxJ0L8LsXNzFeO8GYesV2J9AzGArBjrsb2xR50Ocbn/CL1B44TA==", + "dependencies": { + "@types/readable-stream": "^4.0.0", + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^4.2.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/broker-factory": { + "version": "3.1.9", + "resolved": "https://registry.npmmirror.com/broker-factory/-/broker-factory-3.1.9.tgz", + "integrity": "sha512-MzvndyD6EcbkBtX4NXm/HfdO1+cOR5ONNdMCXEKfHpxGdMtuDz7+o+nJf7HMtyPH1sUVf/lEIP+DMluC5PgaBQ==", + "dependencies": { + "@babel/runtime": "^7.28.3", + "fast-unique-numbers": "^9.0.23", + "tslib": "^2.8.1", + "worker-factory": "^7.0.45" + } + }, + "node_modules/browserslist": { + "version": "4.25.4", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.25.4.tgz", + "integrity": "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001737", + "electron-to-chromium": "^1.5.211", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmmirror.com/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001739", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001739.tgz", + "integrity": "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/code-inspector-core": { + "version": "0.20.12", + "resolved": "https://registry.npmmirror.com/code-inspector-core/-/code-inspector-core-0.20.12.tgz", + "integrity": "sha512-OaEZhQ3c2pYpNB4E0ggXfSv5cUhGEbXcdQMsi3agnQBKYe6gr1nkO1g1E1xXgFD62c4FPw/YjVyoTCDhrpd8kw==", + "dependencies": { + "@vue/compiler-dom": "^3.5.13", + "chalk": "^4.1.1", + "dotenv": "^16.1.4", + "launch-ide": "1.0.7", + "portfinder": "^1.0.28" + } + }, + "node_modules/code-inspector-plugin": { + "version": "0.20.12", + "resolved": "https://registry.npmmirror.com/code-inspector-plugin/-/code-inspector-plugin-0.20.12.tgz", + "integrity": "sha512-dG8m2zvkZU85FrFZImmXAhkJbK7PWS4bFX2KgQyRgOr7VlLSgQ/ZdNFiHyuP5XVUo5dMYChQ93ZeTKvjpExoHQ==", + "dependencies": { + "chalk": "4.1.1", + "code-inspector-core": "0.20.12", + "dotenv": "^16.3.1", + "esbuild-code-inspector-plugin": "0.20.12", + "vite-code-inspector-plugin": "0.20.12", + "webpack-code-inspector-plugin": "0.20.12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/commist": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/commist/-/commist-3.2.0.tgz", + "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "node_modules/dayjs": { + "version": "1.11.18", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==" + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.211", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.211.tgz", + "integrity": "sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==" + }, + "node_modules/element-plus": { + "version": "2.2.27", + "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.27.tgz", + "integrity": "sha512-P04HDOZBYDdvlYuleuCZRULzAc5xJVOBfLDK9xWxVo0vyo8ntdaXS5sTU+/76vrNzuO3FhLn9kvrsbiJEVa1jg==", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.0.6", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.3", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esbuild-code-inspector-plugin": { + "version": "0.20.12", + "resolved": "https://registry.npmmirror.com/esbuild-code-inspector-plugin/-/esbuild-code-inspector-plugin-0.20.12.tgz", + "integrity": "sha512-vX6t7jLifL7HKsS83kVSbaEPxKBdOUyuIKzGCLvgQ+svXW5ieKwFZskizkFn+Z368bcb530H4lGbEj+i2q3csQ==", + "dependencies": { + "code-inspector-core": "0.20.12" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-unique-numbers": { + "version": "9.0.23", + "resolved": "https://registry.npmmirror.com/fast-unique-numbers/-/fast-unique-numbers-9.0.23.tgz", + "integrity": "sha512-jcRIaHo46nfvyvKRMaFSKXmez4jALQ3Qw49gxM5F4siz8HqkyKPPEexpCOYwBSJI1HovrDr4fEedM8QAJ7oX3w==", + "dependencies": { + "@babel/runtime": "^7.28.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18.2.0" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/help-me": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/help-me/-/help-me-5.0.0.tgz", + "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.1.tgz", + "integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true + }, + "node_modules/launch-ide": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/launch-ide/-/launch-ide-1.0.7.tgz", + "integrity": "sha512-wJMTq6U2sVYqxrlp544KQxtl8cHoXFfQa2ivDtKJ6ock2ARneiEHqUFce/NQsnNP1aZNg4OXB6g00oFRvni1/Q==", + "dependencies": { + "chalk": "^4.1.1", + "dotenv": "^16.1.4" + } + }, + "node_modules/lilconfig": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-2.1.0.tgz", + "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "node_modules/local-pkg": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.2.tgz", + "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", + "dev": true, + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" + }, + "node_modules/magic-string": { + "version": "0.30.18", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.18.tgz", + "integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==" + }, + "node_modules/mlly": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", + "dev": true, + "dependencies": { + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "node_modules/mqtt": { + "version": "5.14.0", + "resolved": "https://registry.npmmirror.com/mqtt/-/mqtt-5.14.0.tgz", + "integrity": "sha512-H7EmeCJhbGblbWjm6APF5sAH3SkdI7lxHw/UkblZp8fjSNl8b2MsLcdAkIaQKxvZYmiORkdAjffvKjqQWPkd6w==", + "dependencies": { + "@types/readable-stream": "^4.0.21", + "@types/ws": "^8.18.1", + "commist": "^3.2.0", + "concat-stream": "^2.0.0", + "debug": "^4.4.1", + "help-me": "^5.0.0", + "lru-cache": "^10.4.3", + "minimist": "^1.2.8", + "mqtt-packet": "^9.0.2", + "number-allocator": "^1.0.14", + "readable-stream": "^4.7.0", + "rfdc": "^1.4.1", + "socks": "^2.8.6", + "split2": "^4.2.0", + "worker-timers": "^8.0.23", + "ws": "^8.18.3" + }, + "bin": { + "mqtt": "build/bin/mqtt.js", + "mqtt_pub": "build/bin/pub.js", + "mqtt_sub": "build/bin/sub.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "9.0.2", + "resolved": "https://registry.npmmirror.com/mqtt-packet/-/mqtt-packet-9.0.2.tgz", + "integrity": "sha512-MvIY0B8/qjq7bKxdN1eD+nrljoeaai+qjLJgfRn3TiMuz0pamsIWY2bFODPZMSNmabsLANXsLl4EMoWvlaTZWA==", + "dependencies": { + "bl": "^6.0.8", + "debug": "^4.3.4", + "process-nextick-args": "^2.0.1" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmmirror.com/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmmirror.com/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==" + }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmmirror.com/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinia": { + "version": "2.0.22", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.0.22.tgz", + "integrity": "sha512-u+b8/BC+tmvo3ACbYO2w5NfxHWFOjvvw9DQnyT0dW8aUMCPRQT5QnfZ5R5W2MzZBMTeZRMQI7V/QFbafmM9QHw==", + "dependencies": { + "@vue/devtools-api": "^6.2.1", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.2.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "dev": true, + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/portfinder": { + "version": "1.0.37", + "resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.37.tgz", + "integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==", + "dependencies": { + "async": "^3.2.6", + "debug": "^4.3.6" + }, + "engines": { + "node": ">= 10.12" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.0.1.tgz", + "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz", + "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "lilconfig": "^3.0.0", + "yaml": "^2.3.4" + }, + "engines": { + "node": ">= 14" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-load-config/node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ] + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" + }, + "node_modules/rollup": { + "version": "4.50.0", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.50.0.tgz", + "integrity": "sha512-/Zl4D8zPifNmyGzJS+3kVoyXeDeT/GrsJM94sACNg9RtUE0hrHa1bNPtRSrfHTMH5HjRzce6K7rlTh3Khiw+pw==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.50.0", + "@rollup/rollup-android-arm64": "4.50.0", + "@rollup/rollup-darwin-arm64": "4.50.0", + "@rollup/rollup-darwin-x64": "4.50.0", + "@rollup/rollup-freebsd-arm64": "4.50.0", + "@rollup/rollup-freebsd-x64": "4.50.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.50.0", + "@rollup/rollup-linux-arm-musleabihf": "4.50.0", + "@rollup/rollup-linux-arm64-gnu": "4.50.0", + "@rollup/rollup-linux-arm64-musl": "4.50.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.50.0", + "@rollup/rollup-linux-ppc64-gnu": "4.50.0", + "@rollup/rollup-linux-riscv64-gnu": "4.50.0", + "@rollup/rollup-linux-riscv64-musl": "4.50.0", + "@rollup/rollup-linux-s390x-gnu": "4.50.0", + "@rollup/rollup-linux-x64-gnu": "4.50.0", + "@rollup/rollup-linux-x64-musl": "4.50.0", + "@rollup/rollup-openharmony-arm64": "4.50.0", + "@rollup/rollup-win32-arm64-msvc": "4.50.0", + "@rollup/rollup-win32-ia32-msvc": "4.50.0", + "@rollup/rollup-win32-x64-msvc": "4.50.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/sass": { + "version": "1.56.1", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.56.1.tgz", + "integrity": "sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmmirror.com/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-literal": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-3.0.0.tgz", + "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/sucrase/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/sucrase/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmmirror.com/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sucrase/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.1", + "resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.1.tgz", + "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.19.1", + "lilconfig": "^2.1.0", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.23", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.1", + "postcss-nested": "^6.0.1", + "postcss-selector-parser": "^6.0.11", + "resolve": "^1.22.2", + "sucrase": "^3.32.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true + }, + "node_modules/undici-types": { + "version": "7.10.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==" + }, + "node_modules/unimport": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/unimport/-/unimport-5.2.0.tgz", + "integrity": "sha512-bTuAMMOOqIAyjV4i4UH7P07pO+EsVxmhOzQ2YJ290J6mkLUdozNhb5I/YoOEheeNADC03ent3Qj07X0fWfUpmw==", + "dev": true, + "dependencies": { + "acorn": "^8.15.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "strip-literal": "^3.0.0", + "tinyglobby": "^0.2.14", + "unplugin": "^2.3.5", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unimport/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/unimport/node_modules/unplugin-utils": { + "version": "0.2.5", + "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.5.tgz", + "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==", + "dev": true, + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin": { + "version": "2.3.10", + "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.10.tgz", + "integrity": "sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==", + "dev": true, + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-auto-import": { + "version": "20.1.0", + "resolved": "https://registry.npmmirror.com/unplugin-auto-import/-/unplugin-auto-import-20.1.0.tgz", + "integrity": "sha512-Wa7/y3DwpbxhjyXCbuliuATCPa0/e47tstWkytJGAr55ooSNwIvbkrq0rlduqYGiCNMsZcD+C6vsN+W3AX96eA==", + "dev": true, + "dependencies": { + "local-pkg": "^1.1.2", + "magic-string": "^0.30.18", + "picomatch": "^4.0.3", + "unimport": "^5.2.0", + "unplugin": "^2.3.8", + "unplugin-utils": "^0.3.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@nuxt/kit": "^4.0.0", + "@vueuse/core": "*" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + }, + "@vueuse/core": { + "optional": true + } + } + }, + "node_modules/unplugin-utils": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.3.0.tgz", + "integrity": "sha512-JLoggz+PvLVMJo+jZt97hdIIIZ2yTzGgft9e9q8iMrC4ewufl62ekeW7mixBghonn2gVb/ICjyvlmOCUBnJLQg==", + "dev": true, + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=20.19.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/unplugin-vue-components": { + "version": "29.0.0", + "resolved": "https://registry.npmmirror.com/unplugin-vue-components/-/unplugin-vue-components-29.0.0.tgz", + "integrity": "sha512-M2DX44g4/jvBkB0V6uwqTbkTd5DMRHpeGoi/cIKwGG4HPuNxLbe8zoTStB2n12hoDiWc9I1PIRQruRWExNXHlQ==", + "dev": true, + "dependencies": { + "chokidar": "^3.6.0", + "debug": "^4.4.1", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "tinyglobby": "^0.2.14", + "unplugin": "^2.3.5", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@babel/parser": "^7.15.8", + "@nuxt/kit": "^3.2.2 || ^4.0.0", + "vue": "2 || 3" + }, + "peerDependenciesMeta": { + "@babel/parser": { + "optional": true + }, + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components/node_modules/unplugin-utils": { + "version": "0.2.5", + "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.5.tgz", + "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==", + "dev": true, + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/vite": { + "version": "5.4.19", + "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-code-inspector-plugin": { + "version": "0.20.12", + "resolved": "https://registry.npmmirror.com/vite-code-inspector-plugin/-/vite-code-inspector-plugin-0.20.12.tgz", + "integrity": "sha512-Sz33ocVjAGDfDlhFFysqEOz4zCtu5vpjShvxYmkZiKnL1OKcLKFNktOw9BH0tk8G+7VZOk4J48zH/a4zV9WBUQ==", + "dependencies": { + "code-inspector-core": "0.20.12" + } + }, + "node_modules/vue": { + "version": "3.5.20", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.20.tgz", + "integrity": "sha512-2sBz0x/wis5TkF1XZ2vH25zWq3G1bFEPOfkBcx2ikowmphoQsPH6X0V3mmPCXA2K1N/XGTnifVyDQP4GfDDeQw==", + "dependencies": { + "@vue/compiler-dom": "3.5.20", + "@vue/compiler-sfc": "3.5.20", + "@vue/runtime-dom": "3.5.20", + "@vue/server-renderer": "3.5.20", + "@vue/shared": "3.5.20" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.5.1", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/webpack-code-inspector-plugin": { + "version": "0.20.12", + "resolved": "https://registry.npmmirror.com/webpack-code-inspector-plugin/-/webpack-code-inspector-plugin-0.20.12.tgz", + "integrity": "sha512-tec0/XAzEpzOUkEOWlboUDNN7dIOTFeQw5ZHumlm/e0T9EDdq/aG8ZOCX53pnoasrUHONWmprC3RY8YKwmyNkg==", + "dependencies": { + "code-inspector-core": "0.20.12" + } + }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/worker-factory": { + "version": "7.0.45", + "resolved": "https://registry.npmmirror.com/worker-factory/-/worker-factory-7.0.45.tgz", + "integrity": "sha512-FFPCiSv7MD6ZDEfiik/ErM8IrIAWajaXhezLyCo3v0FjhUWud6GXnG2BiTE91jLywXGAVCT8IF48Hhr+D/omMw==", + "dependencies": { + "@babel/runtime": "^7.28.3", + "fast-unique-numbers": "^9.0.23", + "tslib": "^2.8.1" + } + }, + "node_modules/worker-timers": { + "version": "8.0.24", + "resolved": "https://registry.npmmirror.com/worker-timers/-/worker-timers-8.0.24.tgz", + "integrity": "sha512-Ydu/7TRHlxIRjYSGDge1F92L7y9kzInpwR4CkocRVObPE0eRqC6d+0GFh52Hm+m520RHVKiytOERtCUu5sQDVQ==", + "dependencies": { + "@babel/runtime": "^7.28.3", + "tslib": "^2.8.1", + "worker-timers-broker": "^8.0.10", + "worker-timers-worker": "^9.0.10" + } + }, + "node_modules/worker-timers-broker": { + "version": "8.0.10", + "resolved": "https://registry.npmmirror.com/worker-timers-broker/-/worker-timers-broker-8.0.10.tgz", + "integrity": "sha512-xvo/9GiuduENbJNdWnvZtkriIkjBKKVbMyw7GXvrBu3n1JHemzZgxqaCcCBNlpfXnRXXF4ekqvXWLh1gb65b8w==", + "dependencies": { + "@babel/runtime": "^7.28.3", + "broker-factory": "^3.1.9", + "fast-unique-numbers": "^9.0.23", + "tslib": "^2.8.1", + "worker-timers-worker": "^9.0.10" + } + }, + "node_modules/worker-timers-worker": { + "version": "9.0.10", + "resolved": "https://registry.npmmirror.com/worker-timers-worker/-/worker-timers-worker-9.0.10.tgz", + "integrity": "sha512-cfCmAkuoN+nGGJShta/g7CQVP3h7rvQA642EQg72fOHCWP5S2P83rLxDiaGv811Hd+19Cgdqt/tpRBIZ5kj/dw==", + "dependencies": { + "@babel/runtime": "^7.28.3", + "tslib": "^2.8.1", + "worker-factory": "^7.0.45" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..4d3ec57 --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "tabula-rase-project", + "version": "0.0.0", + "private": true, + "license": "MIT", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@element-plus/icons-vue": "^2.0.10", + "autoprefixer": "^10.4.21", + "axios": "^0.27.2", + "code-inspector-plugin": "^0.20.12", + "element-plus": "^2.2.27", + "js-cookie": "^3.0.1", + "mitt": "^3.0.0", + "mqtt": "^5.14.0", + "pinia": "^2.0.22", + "postcss": "^8.5.6", + "tailwindcss": "^3.4.1", + "uuid": "^11.1.0", + "vue": "^3.5.12", + "vue-router": "^4.4.5" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.1.4", + "sass": "^1.56.1", + "unplugin-auto-import": "^20.1.0", + "unplugin-vue-components": "^29.0.0", + "vite": "^5.4.10" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..397a98f --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,15 @@ +// postcss.config.js +module.exports = { + plugins: [ + { + postcssPlugin: "internal:charset-removal", + AtRule: { + charset: (atRule) => { + if (atRule.name === "charset") atRule.remove(); + } + } + }, + require('tailwindcss'), + require('autoprefixer') + ] +} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..df36fcf 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..cf15f63 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,10 @@ + + + + + diff --git a/src/api/login.js b/src/api/login.js new file mode 100644 index 0000000..adc2381 --- /dev/null +++ b/src/api/login.js @@ -0,0 +1,36 @@ +import request from '@/utils/request' +// import request from '@/views/custom/Meter/public/request.js' + +// 登录方法 +export function login(username, password) { + const params = { + username, + password + } + return request({ + url: '/api/v1/auth/login', + headers: { + isToken: false + }, + method: 'post', + data: params, + }) +} + + + +// 获取用户详细信息 +export function getInfo(userUid) { + return request({ + url: `/api/v1/auth/user/${userUid}`, + method: 'get' + }) +} + +// 退出方法 +export function logout() { + return request({ + url: '/api/v1/auth/logout', + method: 'post' + }) +} diff --git a/src/assets/401_images/401.gif b/src/assets/401_images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/src/assets/401_images/401.gif differ diff --git a/src/assets/404_images/404.png b/src/assets/404_images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/assets/404_images/404.png differ diff --git a/src/assets/404_images/404_cloud.png b/src/assets/404_images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/src/assets/404_images/404_cloud.png differ diff --git a/src/assets/editor/edgecontrol.svg b/src/assets/editor/edgecontrol.svg new file mode 100644 index 0000000..8fe63b6 --- /dev/null +++ b/src/assets/editor/edgecontrol.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/assets/editor/eraser-cursor.png b/src/assets/editor/eraser-cursor.png new file mode 100644 index 0000000..0b41099 Binary files /dev/null and b/src/assets/editor/eraser-cursor.png differ diff --git a/src/assets/editor/middlecontrol.svg b/src/assets/editor/middlecontrol.svg new file mode 100644 index 0000000..53fb5b5 --- /dev/null +++ b/src/assets/editor/middlecontrol.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/assets/editor/middlecontrolhoz.svg b/src/assets/editor/middlecontrolhoz.svg new file mode 100644 index 0000000..ba05d9a --- /dev/null +++ b/src/assets/editor/middlecontrolhoz.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/src/assets/editor/pencil-cursor.png b/src/assets/editor/pencil-cursor.png new file mode 100644 index 0000000..b032151 Binary files /dev/null and b/src/assets/editor/pencil-cursor.png differ diff --git a/src/assets/editor/rotateicon.svg b/src/assets/editor/rotateicon.svg new file mode 100644 index 0000000..7b1d4db --- /dev/null +++ b/src/assets/editor/rotateicon.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/editor/selector-cursor.png b/src/assets/editor/selector-cursor.png new file mode 100644 index 0000000..3c14ce8 Binary files /dev/null and b/src/assets/editor/selector-cursor.png differ diff --git a/src/assets/editor/shape-cursor.svg b/src/assets/editor/shape-cursor.svg new file mode 100644 index 0000000..965169c --- /dev/null +++ b/src/assets/editor/shape-cursor.svg @@ -0,0 +1,30 @@ + + + + shape-cursor + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/editor/text-cursor.svg b/src/assets/editor/text-cursor.svg new file mode 100644 index 0000000..089e4eb --- /dev/null +++ b/src/assets/editor/text-cursor.svg @@ -0,0 +1,27 @@ + + + + text-cursor + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/images/loginBg.png b/src/assets/images/loginBg.png new file mode 100644 index 0000000..3736dff Binary files /dev/null and b/src/assets/images/loginBg.png differ diff --git a/src/assets/logo.svg b/src/assets/logo.svg new file mode 100644 index 0000000..7565660 --- /dev/null +++ b/src/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/styles/btn.scss b/src/assets/styles/btn.scss new file mode 100644 index 0000000..3590d8d --- /dev/null +++ b/src/assets/styles/btn.scss @@ -0,0 +1,99 @@ +@import './variables.module.scss'; + +@mixin colorBtn($color) { + background: $color; + + &:hover { + color: $color; + + &:before, + &:after { + background: $color; + } + } +} + +.blue-btn { + @include colorBtn($blue) +} + +.light-blue-btn { + @include colorBtn($light-blue) +} + +.red-btn { + @include colorBtn($red) +} + +.pink-btn { + @include colorBtn($pink) +} + +.green-btn { + @include colorBtn($green) +} + +.tiffany-btn { + @include colorBtn($tiffany) +} + +.yellow-btn { + @include colorBtn($yellow) +} + +.pan-btn { + font-size: 14px; + color: #fff; + padding: 14px 36px; + border-radius: 8px; + border: none; + outline: none; + transition: 600ms ease all; + position: relative; + display: inline-block; + + &:hover { + background: #fff; + + &:before, + &:after { + width: 100%; + transition: 600ms ease all; + } + } + + &:before, + &:after { + content: ''; + position: absolute; + top: 0; + right: 0; + height: 2px; + width: 0; + transition: 400ms ease all; + } + + &::after { + right: inherit; + top: inherit; + left: 0; + bottom: 0; + } +} + +.custom-button { + display: inline-block; + line-height: 1; + white-space: nowrap; + cursor: pointer; + background: #fff; + color: #fff; + -webkit-appearance: none; + text-align: center; + box-sizing: border-box; + outline: 0; + margin: 0; + padding: 10px 15px; + font-size: 14px; + border-radius: 4px; +} diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss new file mode 100644 index 0000000..5209f8f --- /dev/null +++ b/src/assets/styles/element-ui.scss @@ -0,0 +1,154 @@ +.el-collapse { + .collapse__title { + font-weight: 600; + padding: 0 8px; + font-size: 1.2em; + line-height: 1.1em; + } + + .el-collapse-item__content { + padding: 0 8px; + } +} + +.el-divider--horizontal { + margin-bottom: 10px; + margin-top: 10px; +} + +.el-breadcrumb__inner, +.el-breadcrumb__inner a { + font-weight: 400 !important; +} + +.el-upload { + input[type='file'] { + display: none !important; + } +} + +.el-upload__input { + display: none; +} + +.cell { + .el-tag { + margin-right: 0px; + } +} + +.small-padding { + .cell { + padding-left: 5px; + padding-right: 5px; + } +} + +.fixed-width { + .el-button--mini { + padding: 7px 10px; + width: 60px; + } +} + +.status-col { + .cell { + padding: 0 10px; + text-align: center; + + .el-tag { + margin-right: 0px; + } + } +} + +/*-------------Dialog-------------**/ +.el-overlay { + overflow: hidden; + + .el-overlay-dialog { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + + .el-dialog { + margin: 0 auto !important; + + .el-dialog__body { + padding: 15px !important; + } + + .el-dialog__header { + padding: 16px 16px 8px 16px; + box-sizing: border-box; + border-bottom: 1px solid var(--el-color-primary); + margin-right: 0; + } + } + } +} + +.el-dialog__body { + max-height: calc(90vh - 111px) !important; + overflow-y: auto; + overflow-x: hidden; +} + +// refine element ui upload +.upload-container { + .el-upload { + width: 100%; + + .el-upload-dragger { + width: 100%; + height: 200px; + } + } +} + +// dropdown +.el-dropdown-menu { + a { + display: block; + } +} + +// fix date-picker ui bug in filter-item +.el-range-editor.el-input__inner { + display: inline-flex !important; +} + +// to fix el-date-picker css style +.el-range-separator { + box-sizing: content-box; +} + +.el-menu--collapse > div > .el-submenu > .el-submenu__title .el-submenu__icon-arrow { + display: none; +} + +.el-dropdown .el-dropdown-link { + color: var(--el-color-primary) !important; +} + +/* 当 el-form 的 inline 属性为 true 时 */ +/* 设置 label 的宽度默认为 68px */ +.el-form--inline .el-form-item__label { + width: 68px; +} + +/* 设置 el-select 的宽度默认为 240px */ +.el-form--inline .el-select { + width: 240px; +} + +/* 设置 el-input 的宽度默认为 240px */ +.el-form--inline .el-input { + width: 240px; +} + +//.el-button:hover { +// background-color: red; +//} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss new file mode 100644 index 0000000..d52a54e --- /dev/null +++ b/src/assets/styles/index.scss @@ -0,0 +1,434 @@ +@import "./variables.module.scss"; +@import "./mixin.scss"; +@import "./transition.scss"; +@import "./element-ui.scss"; +@import "./sidebar.scss"; +@import "./btn.scss"; +@import "./ruoyi.scss"; +@import 'element-plus/theme-chalk/index.css'; + +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + height: 100%; + margin: 0; + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, + Microsoft YaHei, Arial, sans-serif; +} + + + +label { + font-weight: 700; +} + +html { + height: 100%; + box-sizing: border-box; +} + +#app { + height: 100%; +} + +*, +*:before, +*:after { + box-sizing: inherit; +} + +.no-padding { + padding: 0px !important; +} + +.padding-content { + padding: 4px 0; +} + +a:focus, +a:active { + outline: none; +} + +a, +a:focus, +a:hover { + cursor: pointer; + color: inherit; + text-decoration: none; +} + +div:focus { + outline: none; +} + +.fr { + float: right; +} + +.fl { + float: left; +} + +.pr-5 { + padding-right: 5px; +} + +.pl-5 { + padding-left: 5px; +} + +.block { + display: block; +} + +.pointer { + cursor: pointer; +} + +.inlineBlock { + display: block; +} + +.clearfix { + &:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; + } +} + +aside { + background: #eef1f6; + padding: 8px 24px; + margin-bottom: 20px; + border-radius: 2px; + display: block; + line-height: 32px; + font-size: 16px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, + Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + color: #2c3e50; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + + a { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } + } +} + +//main-container全局样式 +.app-container { + background-color: white; + padding: 30px; + position: relative; + box-shadow: var(--el-box-shadow-light); +} + +.components-container { + margin: 30px 50px; + position: relative; +} + +// .pagination-container { +// margin-top: 30px; +// } + +.text-center { + text-align: center; +} + +.sub-navbar { + height: 50px; + line-height: 50px; + position: relative; + width: 100%; + text-align: right; + padding-right: 20px; + transition: 600ms ease position; + background: linear-gradient(90deg, + rgba(32, 182, 249, 1) 0%, + rgba(32, 182, 249, 1) 0%, + rgba(33, 120, 241, 1) 100%, + rgba(33, 120, 241, 1) 100%); + + .subtitle { + font-size: 20px; + color: #fff; + } + + &.draft { + background: #d0d0d0; + } + + &.deleted { + background: #d0d0d0; + } +} + +.link-type, +.link-type:focus { + color: #337ab7; + cursor: pointer; + + &:hover { + color: rgb(32, 160, 255); + } +} + +.filter-container { + padding-bottom: 10px; + + .filter-item { + display: inline-block; + vertical-align: middle; + margin-bottom: 10px; + } +} + +// form样式修改 +.el-form-item--default .el-form-item__label { + position: relative; + line-height: 1.4 !important; + text-align: left; + padding-left: 10px; + display: flex; + align-items: center; + justify-content: flex-start; +} + +.el-form-item--default .el-form-item__label::before { + position: absolute; + left: 0; +} + +// form-item全局配置 +.form-100 { + width: 100%; + margin-right: 0 !important; + + .el-select { + width: 100%; + } + + .el-input-number { + width: 100%; + } +} + +.form-50 { + width: 50%; + margin-right: 0 !important; + + .el-select { + width: 100%; + } + + .el-input-number { + width: 100%; + } +} + +// 详情展示表格 + +.agency-detail-massage-cont { + display: flex; + justify-content: space-between; + flex-wrap: wrap; + width: 100%; + // border-top: solid 1px rgb(235,238,245); + // border-right: solid 1px rgb(235,238,245); +} + +.agency-detail-cont-title { + width: 100%; + font-size: 20px; + color: #333; + font-weight: 900; + margin-bottom: 10px; +} + +// 如果item是单数需要手动加一个空item 暂时未有解决方法 +.agency-detail-cont-item { + display: flex; + justify-content: space-between; + align-items: center; + width: 50%; + // border-bottom: solid 1px rgb(235,238,245); +} + +.agency-detail-item-title { + flex: 3; + display: inline-flex; + justify-content: flex-start; + align-items: center; + width: 20%; + height: calc(100%); + padding: 15px 0; + padding-left: 23px; + flex-shrink: 0; + color: #333; + font-size: 16px; + font-weight: 600; + // border-left: solid 1px rgb(235,238,245); + // background-color: rgb(248,248,249); +} + +.agency-detail-item-content { + flex: 7; + display: inline-flex; + justify-content: flex-start; + align-items: center; + width: 70%; + height: calc(100%); + padding: 8px 0 8px; + padding-left: 23px; + color: #333; + font-size: 16px; + font-weight: 400; + // border-left: solid 1px rgb(235,238,245); +} + +.agency-detail-item-img { + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: flex-start; +} + +// 单行文本超出隐藏 +.text-out-of-hiding-1 { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +// 两行文本超出隐藏 +.text-out-of-hiding-2 { + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; +} + +.el-table .el-table__header-wrapper th, +.el-table .el-table__fixed-header-wrapper th { + background-color: #ededed !important; +} + +// ======================================================================== app/components list class + +.container-application { + box-sizing: border-box; + padding: 0 20px 8px; + + .liation-checkbox { + display: flex; + position: absolute; + left: 20px; + top: 20px; + height: 34px !important; + z-index: 10; + } + + .application-list { + line-height: 0; + margin-top: 20px; + height: auto; + box-shadow: 0 1px 10px -1px #999999; + border-radius: 6px; + overflow: hidden; + position: relative; + padding: 15px; + padding-bottom: 0; + + .application-img { + position: relative; + width: 100%; + // overflow: hidden; + } + + .application-img::before { + content: ""; + display: block; + padding-top: 100%; + } + + .application-img-value { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + + .application-icon { + position: absolute; + left: 16px; + top: 18px; + display: flex; + font-size: 30px; + z-index: 10; + cursor: pointer; + + .application-icon-img { + display: flex; + width: 30px; + height: 30px; + margin-top: 2px; + margin-left: 4px; + } + } + + .list-icon { + width: 34px; + height: 34px; + position: absolute; + right: 20px; + top: 20px; + z-index: 10; + cursor: pointer; + } + + .list-text { + width: 100%; + height: 45px; + margin-top: 10px; + line-height: 45px; + font-size: 17px; + color: rgb(38, 38, 38); + font-weight: 700; + } + + .list-content { + width: 100%; + height: 50px; + + .list-content-text { + line-height: 1.2; + font-size: 14px; + color: rgb(96, 98, 102); + } + } + } +} + +.application-list-selectitem-icon { + width: 14px; + height: 14px; + margin-right: 5px; +} \ No newline at end of file diff --git a/src/assets/styles/mixin.scss b/src/assets/styles/mixin.scss new file mode 100644 index 0000000..06fa061 --- /dev/null +++ b/src/assets/styles/mixin.scss @@ -0,0 +1,66 @@ +@mixin clearfix { + &:after { + content: ""; + display: table; + clear: both; + } +} + +@mixin scrollBar { + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } +} + +@mixin relative { + position: relative; + width: 100%; + height: 100%; +} + +@mixin pct($pct) { + width: #{$pct}; + position: relative; + margin: 0 auto; +} + +@mixin triangle($width, $height, $color, $direction) { + $width: $width/2; + $color-border-style: $height solid $color; + $transparent-border-style: $width solid transparent; + height: 0; + width: 0; + + @if $direction==up { + border-bottom: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==right { + border-left: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } + + @else if $direction==down { + border-top: $color-border-style; + border-left: $transparent-border-style; + border-right: $transparent-border-style; + } + + @else if $direction==left { + border-right: $color-border-style; + border-top: $transparent-border-style; + border-bottom: $transparent-border-style; + } +} diff --git a/src/assets/styles/ruoyi.scss b/src/assets/styles/ruoyi.scss new file mode 100644 index 0000000..a32bafa --- /dev/null +++ b/src/assets/styles/ruoyi.scss @@ -0,0 +1,309 @@ +/** + * 通用css样式布局处理 + * Copyright (c) 2019 + */ + +/** 基础通用 **/ +.pt5 { + padding-top: 5px; +} + +.pr5 { + padding-right: 5px; +} + +.pb5 { + padding-bottom: 5px; +} + +.mt5 { + margin-top: 5px; +} + +.mr5 { + margin-right: 5px; +} + +.mb5 { + margin-bottom: 5px; +} + +.mb8 { + margin-bottom: 8px; +} + +.ml5 { + margin-left: 5px; +} + +.mt10 { + margin-top: 10px; +} + +.mr10 { + margin-right: 10px; +} + +.mb10 { + margin-bottom: 10px; +} + +.ml10 { + margin-left: 10px; +} + +.mt20 { + margin-top: 20px; +} + +.mr20 { + margin-right: 20px; +} + +.mb20 { + margin-bottom: 20px; +} + +.ml20 { + margin-left: 20px; +} + +.h1, +.h2, +.h3, +.h4, +.h5, +.h6, +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} + +.el-form .el-form-item__label { + font-weight: 700; +} + +.el-dialog:not(.is-fullscreen) { + margin-top: 6vh !important; +} + +.el-dialog.scrollbar .el-dialog__body { + overflow: auto; + overflow-x: hidden; + max-height: 70vh; + padding: 10px 20px 0; +} + +.el-table { + + .el-table__header-wrapper, + .el-table__fixed-header-wrapper { + th { + word-break: break-word; + background-color: #f8f8f9 !important; + color: #515a6e; + height: 40px !important; + font-size: 13px; + } + } + + .el-table__body-wrapper { + .el-button [class*="el-icon-"]+span { + margin-left: 1px; + } + } +} + +/** 表单布局 **/ +.form-header { + font-size: 15px; + color: #6379bb; + border-bottom: 1px solid #ddd; + margin: 8px 10px 25px 10px; + padding-bottom: 5px; +} + +/** 表格布局 **/ +.pagination-container { + // position: relative; + height: 25px; + margin-bottom: 10px; + margin-top: 15px; + padding: 10px 20px !important; +} + +/* tree border */ +.tree-border { + margin-top: 5px; + border: 1px solid #e5e6e7; + background: #ffffff none; + border-radius: 4px; + width: 100%; +} + +.pagination-container .el-pagination { + right: 0; + position: absolute; +} + +@media (max-width: 768px) { + .pagination-container .el-pagination>.el-pagination__jump { + display: none !important; + } + + .pagination-container .el-pagination>.el-pagination__sizes { + display: none !important; + } +} + +.el-table .fixed-width .el-button--small { + padding-left: 0; + padding-right: 0; + width: inherit; +} + +/** 表格更多操作下拉样式 */ +.el-table .el-dropdown-link { + cursor: pointer; + color: #409eff; + margin-left: 10px; +} + +.el-table .el-dropdown, +.el-icon-arrow-down { + font-size: 12px; +} + +.el-tree-node__content>.el-checkbox { + margin-right: 8px; +} + +.list-group-striped>.list-group-item { + border-left: 0; + border-right: 0; + border-radius: 0; + padding-left: 0; + padding-right: 0; +} + +.list-group { + padding-left: 0px; + list-style: none; +} + +.list-group-item { + border-bottom: 1px solid #e7eaec; + border-top: 1px solid #e7eaec; + margin-bottom: -1px; + padding: 11px 0px; + font-size: 13px; +} + +.pull-right { + float: right !important; +} + +.el-card__header { + padding: 14px 15px 7px !important; + min-height: 40px; +} + +.el-card__body { + padding: 15px 20px 20px 20px !important; +} + +.card-box { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 10px; +} + +/* button color */ +.el-button--cyan.is-active, +.el-button--cyan:active { + background: #20b2aa; + border-color: #20b2aa; + color: #ffffff; +} + +.el-button--cyan:focus, +.el-button--cyan:hover { + background: #48d1cc; + border-color: #48d1cc; + color: #ffffff; +} + +.el-button--cyan { + background-color: #20b2aa; + border-color: #20b2aa; + color: #ffffff; +} + +/* text color */ +.text-navy { + color: #1ab394; +} + +.text-primary { + color: inherit; +} + +.text-success { + color: #1c84c6; +} + +.text-info { + color: #23c6c8; +} + +.text-warning { + color: #f8ac59; +} + +.text-danger { + color: #ed5565; +} + +.text-muted { + color: #888888; +} + +/* image */ +.img-circle { + border-radius: 50%; +} + +.img-lg { + width: 120px; + height: 120px; +} + +.avatar-upload-preview { + position: absolute; + top: 50%; + transform: translate(50%, -50%); + width: 200px; + height: 200px; + border-radius: 50%; + box-shadow: 0 0 4px #ccc; + overflow: hidden; +} + +/* 拖拽列样式 */ +.sortable-ghost { + opacity: 0.8; + color: #fff !important; + background: #42b983 !important; +} + +/* 表格右侧工具栏样式 */ +.top-right-btn { + margin-left: auto; +} \ No newline at end of file diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss new file mode 100644 index 0000000..823bc4d --- /dev/null +++ b/src/assets/styles/sidebar.scss @@ -0,0 +1,265 @@ +$menu-bg-color: #8290f0; +#app { + + .main-container { + min-height: 100%; + transition: margin-left .28s; + // margin-left: $base-sidebar-width; + position: relative; + } + + .sidebarHide { + margin-left: 0 !important; + } + + // @media screen and (max-width: 995px) { + // .sidebar-container { + // position: fixed !important; + // } + // } + + .sidebar-container { + -webkit-transition: width .28s; + transition: width 0.28s; + width: $base-sidebar-width !important; + background-color: $base-menu-background; + height: 100%; + position: relative; + font-size: 0px; + top: 0; + bottom: 0; + left: 0; + z-index: 1000; + overflow: hidden; + + // reset element-ui css + .horizontal-collapse-transition { + transition: 0s width ease-in-out, 0s padding-left ease-in-out, 0s padding-right ease-in-out; + } + + .scrollbar-wrapper { + overflow-x: hidden !important; + } + + .el-scrollbar__bar.is-vertical { + right: 0px; + } + + .el-scrollbar { + height: 100%; + } + + &.has-logo { + .el-scrollbar { + height: calc(100% - 50px); + } + } + + .is-horizontal { + display: none; + } + + a { + display: inline-block; + width: 100%; + overflow: hidden; + } + + .el-menu { + border: none; + height: 100%; + width: 100% !important; + } + + .el-menu-item, + .menu-title { + overflow: hidden !important; + text-overflow: ellipsis !important; + white-space: nowrap !important; + } + + .menu-title { + margin-left: 10px; + } + + .el-menu-item .el-menu-tooltip__trigger { + display: flex; + align-items: center; + justify-content: center; + } + + // menu hover + .sub-menu-title-noDropdown, + .el-sub-menu__title { + &:hover { + background-color: #c4cbf3 !important; + } + } + + .el-menu-item:hover { + background-color: #c4cbf3 !important; + } + + & .theme-dark .is-active>.el-sub-menu__title { + color: $base-menu-color-active !important; + } + + & .nest-menu .el-sub-menu>.el-sub-menu__title, + & .el-sub-menu .el-menu-item { + min-width: $base-sidebar-width !important; + + &:hover { + background-color: #c4cbf3 !important; + } + } + + & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title, + & .theme-dark .el-sub-menu .el-menu-item { + background-color: $base-sub-menu-background !important; + + &:hover { + background-color: $base-sub-menu-hover !important; + } + } + + & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title, + & .theme-dark .el-sub-menu .el-menu-item.is-active { + color: #ffffff !important; + background-color: #{$menu-bg-color} !important; // 点击菜单的颜色 + } + + .el-menu-item.is-active { + color: #ffffff !important; + background-color: #{$menu-bg-color} !important; // 点击菜单的颜色 + } + + } + + .hideSidebar { + .sidebar-container { + // width: 54px !important; + height: calc(100vh - 50px); + background-color: red; + + } + + .main-container { + margin-left: 0; + } + + .sub-menu-title-noDropdown { + padding: 0 !important; + position: relative; + + .el-tooltip { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + } + } + + .el-sub-menu { + overflow: hidden; + + &>.el-sub-menu__title { + padding: 0 !important; + + .svg-icon { + margin-left: 20px; + } + } + } + + // .el-menu--collapse { + // .el-sub-menu { + // &>.el-sub-menu__title { + // &>span { + // height: 0; + // width: 0; + // overflow: hidden; + // visibility: hidden; + // display: inline-block; + // } + + // &>i { + // height: 0; + // width: 0; + // overflow: hidden; + // visibility: hidden; + // display: inline-block; + // } + // } + // } + // } + } + + .el-menu--collapse .el-menu .el-sub-menu { + min-width: $base-sidebar-width !important; + } + + // mobile responsive + .mobile { + .main-container { + margin-left: 0px; + } + + .sidebar-container { + transition: transform .28s; + width: $base-sidebar-width !important; + } + + // &.hideSidebar { + // .sidebar-container { + // pointer-events: none; + // transition-duration: 0.3s; + // transform: translate3d(-$base-sidebar-width, 0, 0); + // } + // } + } + + .withoutAnimation { + + .main-container, + .sidebar-container { + transition: none; + } + } +} + +// when menu collapsed +.el-menu--vertical { + &>.el-menu { + .svg-icon { + margin-right: 16px; + } + } + + .nest-menu .el-sub-menu>.el-sub-menu__title, + .el-menu-item { + &:hover { + // you can use $sub-menuHover + background-color: FF7B5D !important; + } + } + + // the scroll bar appears when the sub-menu is too long + >.el-menu--popup { + max-height: 100vh; + overflow-y: auto; + + &::-webkit-scrollbar-track-piece { + background: #d3dce6; + } + + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-thumb { + background: #99a9bf; + border-radius: 20px; + } + } +} \ No newline at end of file diff --git a/src/assets/styles/transition.scss b/src/assets/styles/transition.scss new file mode 100644 index 0000000..073f8c6 --- /dev/null +++ b/src/assets/styles/transition.scss @@ -0,0 +1,49 @@ +// global transition css + +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.28s; +} + +.fade-enter, +.fade-leave-active { + opacity: 0; +} + +/* fade-transform */ +.fade-transform--move, +.fade-transform-leave-active, +.fade-transform-enter-active { + transition: all .5s; +} + +.fade-transform-enter { + opacity: 0; + transform: translateX(-30px); +} + +.fade-transform-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* breadcrumb transition */ +.breadcrumb-enter-active, +.breadcrumb-leave-active { + transition: all .5s; +} + +.breadcrumb-enter, +.breadcrumb-leave-active { + opacity: 0; + transform: translateX(20px); +} + +.breadcrumb-move { + transition: all .5s; +} + +.breadcrumb-leave-active { + position: absolute; +} diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss new file mode 100644 index 0000000..9beb77b --- /dev/null +++ b/src/assets/styles/variables.module.scss @@ -0,0 +1,65 @@ +// base color +$blue: #324157; +$light-blue: #3A71A8; +$red: #C03639; +$pink: #E65D6E; +$green: #30B08F; +$tiffany: #4AB7BD; +$yellow: #FEC171; +$panGreen: #30B08F; + +// 默认菜单主题风格 +$base-menu-color: #000; +$base-menu-color-active: #000; +$base-menu-background: #fff; +$base-logo-title-color: #ffffff; + +$base-menu-light-color: rgba(0, 0, 0, 0.7); +$base-menu-light-background: #ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background: #fff; +$base-sub-menu-hover: #c4cbf3; + +// 自定义暗色菜单风格 +/** +$base-menu-color:hsla(0,0%,100%,.65); +$base-menu-color-active:#fff; +$base-menu-background:#001529; +$base-logo-title-color: #ffffff; + +$base-menu-light-color:rgba(0,0,0,.70); +$base-menu-light-background:#ffffff; +$base-logo-light-title-color: #001529; + +$base-sub-menu-background:#000c17; +$base-sub-menu-hover:#001528; +*/ + +$--color-primary: #409EFF; +$--color-success: #67C23A; +$--color-warning: #E6A23C; +$--color-danger: #F56C6C; +$--color-info: #909399; + +$base-sidebar-width: 200px; + +// the :export directive is the magic sauce for webpack +// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass +:export { + menuColor: $base-menu-color; + menuLightColor: $base-menu-light-color; + menuColorActive: $base-menu-color-active; + menuBackground: $base-menu-background; + menuLightBackground: $base-menu-light-background; + subMenuBackground: $base-sub-menu-background; + subMenuHover: $base-sub-menu-hover; + sideBarWidth: $base-sidebar-width; + logoTitleColor: $base-logo-title-color; + logoLightTitleColor: $base-logo-light-title-color; + primaryColor: $--color-primary; + successColor: $--color-success; + dangerColor: $--color-danger; + infoColor: $--color-info; + warningColor: $--color-warning; +} \ No newline at end of file diff --git a/src/components/Login/index.vue b/src/components/Login/index.vue new file mode 100644 index 0000000..409908f --- /dev/null +++ b/src/components/Login/index.vue @@ -0,0 +1,206 @@ + + + + diff --git a/src/components/ToolBox/image/arrow-active.svg b/src/components/ToolBox/image/arrow-active.svg new file mode 100644 index 0000000..2e8e8f9 --- /dev/null +++ b/src/components/ToolBox/image/arrow-active.svg @@ -0,0 +1,12 @@ + + + 矩形备份 24 + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/arrow.svg b/src/components/ToolBox/image/arrow.svg new file mode 100644 index 0000000..c6a8280 --- /dev/null +++ b/src/components/ToolBox/image/arrow.svg @@ -0,0 +1,12 @@ + + + 矩形备份 24 + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/brushSize-active.svg b/src/components/ToolBox/image/brushSize-active.svg new file mode 100644 index 0000000..0376633 --- /dev/null +++ b/src/components/ToolBox/image/brushSize-active.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/ToolBox/image/brushSize.svg b/src/components/ToolBox/image/brushSize.svg new file mode 100644 index 0000000..a2913ce --- /dev/null +++ b/src/components/ToolBox/image/brushSize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/ToolBox/image/clear-active.svg b/src/components/ToolBox/image/clear-active.svg new file mode 100644 index 0000000..51ebc22 --- /dev/null +++ b/src/components/ToolBox/image/clear-active.svg @@ -0,0 +1,15 @@ + + + 编组 + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/clear.svg b/src/components/ToolBox/image/clear.svg new file mode 100644 index 0000000..510a1ab --- /dev/null +++ b/src/components/ToolBox/image/clear.svg @@ -0,0 +1,17 @@ + + + 编组 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/click-active.svg b/src/components/ToolBox/image/click-active.svg new file mode 100644 index 0000000..a51a34a --- /dev/null +++ b/src/components/ToolBox/image/click-active.svg @@ -0,0 +1,12 @@ + + + click_p@1x + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/click.svg b/src/components/ToolBox/image/click.svg new file mode 100644 index 0000000..9d5ae1f --- /dev/null +++ b/src/components/ToolBox/image/click.svg @@ -0,0 +1,12 @@ + + + click@1x + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/colorSelector-active.svg b/src/components/ToolBox/image/colorSelector-active.svg new file mode 100644 index 0000000..69b147f --- /dev/null +++ b/src/components/ToolBox/image/colorSelector-active.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/ToolBox/image/colorSelector.svg b/src/components/ToolBox/image/colorSelector.svg new file mode 100644 index 0000000..d38d378 --- /dev/null +++ b/src/components/ToolBox/image/colorSelector.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/ToolBox/image/ellipse-active.svg b/src/components/ToolBox/image/ellipse-active.svg new file mode 100644 index 0000000..f710f48 --- /dev/null +++ b/src/components/ToolBox/image/ellipse-active.svg @@ -0,0 +1,11 @@ + + + folder备份 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/ellipse.svg b/src/components/ToolBox/image/ellipse.svg new file mode 100644 index 0000000..18a2c81 --- /dev/null +++ b/src/components/ToolBox/image/ellipse.svg @@ -0,0 +1,11 @@ + + + folder备份 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/eraser-active.svg b/src/components/ToolBox/image/eraser-active.svg new file mode 100644 index 0000000..9afa92f --- /dev/null +++ b/src/components/ToolBox/image/eraser-active.svg @@ -0,0 +1,12 @@ + + + 矩形备份 25 + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/eraser.svg b/src/components/ToolBox/image/eraser.svg new file mode 100644 index 0000000..918c175 --- /dev/null +++ b/src/components/ToolBox/image/eraser.svg @@ -0,0 +1,12 @@ + + + 矩形备份 25 + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/hand-active.svg b/src/components/ToolBox/image/hand-active.svg new file mode 100644 index 0000000..7fae04f --- /dev/null +++ b/src/components/ToolBox/image/hand-active.svg @@ -0,0 +1,11 @@ + + + 矩形备份 24 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/hand.svg b/src/components/ToolBox/image/hand.svg new file mode 100644 index 0000000..bcc70f5 --- /dev/null +++ b/src/components/ToolBox/image/hand.svg @@ -0,0 +1,11 @@ + + + 矩形备份 24 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/laserPointer-active.svg b/src/components/ToolBox/image/laserPointer-active.svg new file mode 100644 index 0000000..e553a04 --- /dev/null +++ b/src/components/ToolBox/image/laserPointer-active.svg @@ -0,0 +1,19 @@ + + + 矩形备份 25 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/laserPointer.svg b/src/components/ToolBox/image/laserPointer.svg new file mode 100644 index 0000000..570ed4b --- /dev/null +++ b/src/components/ToolBox/image/laserPointer.svg @@ -0,0 +1,19 @@ + + + 矩形备份 25 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/mask.svg b/src/components/ToolBox/image/mask.svg new file mode 100644 index 0000000..1da4451 --- /dev/null +++ b/src/components/ToolBox/image/mask.svg @@ -0,0 +1,11 @@ + + + + mask (1) + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/pencil-active.svg b/src/components/ToolBox/image/pencil-active.svg new file mode 100644 index 0000000..7c77b7b --- /dev/null +++ b/src/components/ToolBox/image/pencil-active.svg @@ -0,0 +1,11 @@ + + + follow备份 3 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/pencil.svg b/src/components/ToolBox/image/pencil.svg new file mode 100644 index 0000000..8ec1f25 --- /dev/null +++ b/src/components/ToolBox/image/pencil.svg @@ -0,0 +1,11 @@ + + + follow备份 3 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/pentagram-active.svg b/src/components/ToolBox/image/pentagram-active.svg new file mode 100644 index 0000000..7f23c49 --- /dev/null +++ b/src/components/ToolBox/image/pentagram-active.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/pentagram.svg b/src/components/ToolBox/image/pentagram.svg new file mode 100644 index 0000000..acb87e7 --- /dev/null +++ b/src/components/ToolBox/image/pentagram.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/rectangle-active.svg b/src/components/ToolBox/image/rectangle-active.svg new file mode 100644 index 0000000..3308c50 --- /dev/null +++ b/src/components/ToolBox/image/rectangle-active.svg @@ -0,0 +1,11 @@ + + + folder备份 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/rectangle.svg b/src/components/ToolBox/image/rectangle.svg new file mode 100644 index 0000000..1ba7ce4 --- /dev/null +++ b/src/components/ToolBox/image/rectangle.svg @@ -0,0 +1,11 @@ + + + folder备份 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/rhombus-active.svg b/src/components/ToolBox/image/rhombus-active.svg new file mode 100644 index 0000000..3e5bcef --- /dev/null +++ b/src/components/ToolBox/image/rhombus-active.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/rhombus.svg b/src/components/ToolBox/image/rhombus.svg new file mode 100644 index 0000000..94d78ec --- /dev/null +++ b/src/components/ToolBox/image/rhombus.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/selector-active.svg b/src/components/ToolBox/image/selector-active.svg new file mode 100644 index 0000000..017c163 --- /dev/null +++ b/src/components/ToolBox/image/selector-active.svg @@ -0,0 +1,12 @@ + + + + selector + Created with Sketch. + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/selector.svg b/src/components/ToolBox/image/selector.svg new file mode 100644 index 0000000..e522066 --- /dev/null +++ b/src/components/ToolBox/image/selector.svg @@ -0,0 +1,14 @@ + + + follow备份 14 + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/speechBalloon-active.svg b/src/components/ToolBox/image/speechBalloon-active.svg new file mode 100644 index 0000000..462753b --- /dev/null +++ b/src/components/ToolBox/image/speechBalloon-active.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/speechBalloon.svg b/src/components/ToolBox/image/speechBalloon.svg new file mode 100644 index 0000000..d9ff814 --- /dev/null +++ b/src/components/ToolBox/image/speechBalloon.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/straight-active.svg b/src/components/ToolBox/image/straight-active.svg new file mode 100644 index 0000000..fc20a80 --- /dev/null +++ b/src/components/ToolBox/image/straight-active.svg @@ -0,0 +1,11 @@ + + + follow备份 7 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/straight.svg b/src/components/ToolBox/image/straight.svg new file mode 100644 index 0000000..a7c45f4 --- /dev/null +++ b/src/components/ToolBox/image/straight.svg @@ -0,0 +1,11 @@ + + + follow备份 5 + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/subscript-active.svg b/src/components/ToolBox/image/subscript-active.svg new file mode 100644 index 0000000..3d208c2 --- /dev/null +++ b/src/components/ToolBox/image/subscript-active.svg @@ -0,0 +1,9 @@ + + + + 矩形 + Created with Sketch. + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/subscript.svg b/src/components/ToolBox/image/subscript.svg new file mode 100644 index 0000000..cc3562a --- /dev/null +++ b/src/components/ToolBox/image/subscript.svg @@ -0,0 +1,9 @@ + + + + 矩形 + Created with Sketch. + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/text-active.svg b/src/components/ToolBox/image/text-active.svg new file mode 100644 index 0000000..48642f0 --- /dev/null +++ b/src/components/ToolBox/image/text-active.svg @@ -0,0 +1,14 @@ + + + 矩形备份 25 + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/text.svg b/src/components/ToolBox/image/text.svg new file mode 100644 index 0000000..0a39a91 --- /dev/null +++ b/src/components/ToolBox/image/text.svg @@ -0,0 +1,14 @@ + + + 矩形备份 25 + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/triangle-active.svg b/src/components/ToolBox/image/triangle-active.svg new file mode 100644 index 0000000..cefa15f --- /dev/null +++ b/src/components/ToolBox/image/triangle-active.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/triangle.svg b/src/components/ToolBox/image/triangle.svg new file mode 100644 index 0000000..7123847 --- /dev/null +++ b/src/components/ToolBox/image/triangle.svg @@ -0,0 +1,13 @@ + + + 矩形备份 25 + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/image/upload-active.svg b/src/components/ToolBox/image/upload-active.svg new file mode 100644 index 0000000..76eea7d --- /dev/null +++ b/src/components/ToolBox/image/upload-active.svg @@ -0,0 +1,16 @@ + + + + upload-pressed + Created with Sketch. + + + + + + + + + + + diff --git a/src/components/ToolBox/image/upload.svg b/src/components/ToolBox/image/upload.svg new file mode 100644 index 0000000..66ace4d --- /dev/null +++ b/src/components/ToolBox/image/upload.svg @@ -0,0 +1,16 @@ + + + + upload + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/src/components/ToolBox/index.vue b/src/components/ToolBox/index.vue new file mode 100644 index 0000000..ff4737e --- /dev/null +++ b/src/components/ToolBox/index.vue @@ -0,0 +1,228 @@ + + + + + \ No newline at end of file diff --git a/src/components/icons/IconCommunity.vue b/src/components/icons/IconCommunity.vue new file mode 100644 index 0000000..2dc8b05 --- /dev/null +++ b/src/components/icons/IconCommunity.vue @@ -0,0 +1,7 @@ + diff --git a/src/components/icons/IconDocumentation.vue b/src/components/icons/IconDocumentation.vue new file mode 100644 index 0000000..6d4791c --- /dev/null +++ b/src/components/icons/IconDocumentation.vue @@ -0,0 +1,7 @@ + diff --git a/src/components/icons/IconEcosystem.vue b/src/components/icons/IconEcosystem.vue new file mode 100644 index 0000000..c3a4f07 --- /dev/null +++ b/src/components/icons/IconEcosystem.vue @@ -0,0 +1,7 @@ + diff --git a/src/components/icons/IconSupport.vue b/src/components/icons/IconSupport.vue new file mode 100644 index 0000000..7452834 --- /dev/null +++ b/src/components/icons/IconSupport.vue @@ -0,0 +1,7 @@ + diff --git a/src/components/icons/IconTooling.vue b/src/components/icons/IconTooling.vue new file mode 100644 index 0000000..660598d --- /dev/null +++ b/src/components/icons/IconTooling.vue @@ -0,0 +1,19 @@ + + diff --git a/src/core/index.js b/src/core/index.js new file mode 100644 index 0000000..8d7bb3d --- /dev/null +++ b/src/core/index.js @@ -0,0 +1,285 @@ +import EventEmitter from "@/utils/emitter"; + +/** + * Canvas绘图类,支持多种图形绘制和多人同步 + * 使用百分比坐标系统确保跨设备一致性 + */ +class Canvas extends EventEmitter { + constructor(canvasId) { + super(); + this.canvas = document.getElementById(canvasId); + if (!this.canvas) { + throw new Error(`Canvas element with id ${canvasId} not found`); + } + + this.ctx = this.canvas.getContext('2d'); + this.shapes = []; // 所有已绘制形状 + this.currentShape = null; // 当前正在绘制的形状 + this.isDrawing = false; + this.drawingTool = 'pencil'; + this.pathOptimizationEnabled = true; + this.optimizationThreshold = 0.005; + this.currentColor = '#ffcc00'; + this.currentThickness = 2; + + this.resize(); + + // 绑定事件 + this.handleMouseDown = this.handleMouseDown.bind(this); + this.handleMouseMove = this.handleMouseMove.bind(this); + this.handleMouseUp = this.handleMouseUp.bind(this); + this.handleMouseLeave = this.handleMouseLeave.bind(this); + + this.canvas.addEventListener('mousedown', this.handleMouseDown); + this.canvas.addEventListener('mousemove', this.handleMouseMove); + this.canvas.addEventListener('mouseup', this.handleMouseUp); + this.canvas.addEventListener('mouseleave', this.handleMouseLeave); + + window.addEventListener('resize', () => this.resize()); + } + + resize() { + const parent = this.canvas.parentElement; + if (!parent) return; + + const containerWidth = parent.offsetWidth; + const containerHeight = parent.offsetHeight; + + let width = containerWidth; + let height = Math.floor((width * 9) / 16); + + if (height > containerHeight) { + height = containerHeight; + width = Math.floor((height * 16) / 9); + } + + if (this.canvas.width === width && this.canvas.height === height) return; + + this.canvas.width = width; + this.canvas.height = height; + this.canvas.style.width = width + "px"; + this.canvas.style.height = height + "px"; + + this.render(); + } + + setDrawingTool(tool) { this.drawingTool = tool; } + setColor(color) { this.currentColor = color; } + setThickness(size) { this.currentThickness = size; } + setPathOptimization(enabled) { this.pathOptimizationEnabled = enabled; } + setOptimizationThreshold(threshold) { this.optimizationThreshold = threshold; } + getShapes() { return this.shapes; } + setShapes(shapes) { this.shapes = shapes; this.render(); } + + getMouseCoordinates(e) { + const rect = this.canvas.getBoundingClientRect(); + return { + x: (e.clientX - rect.left) / this.canvas.width, + y: (e.clientY - rect.top) / this.canvas.height + }; + } + + handleMouseDown(e) { + this.isDrawing = true; + const coords = this.getMouseCoordinates(e); + + if (this.drawingTool === 'pencil') { + this.currentShape = { type: 'pencil', data: { color: this.currentColor, path: [coords], thickness: this.currentThickness } }; + } else if (this.drawingTool === 'line') { + this.currentShape = { type: 'line', data: { color: this.currentColor, start: coords, end: coords, thickness: this.currentThickness } }; + } else if (this.drawingTool === 'rectangle') { + this.currentShape = { type: 'rectangle', data: { color: this.currentColor, start: coords, end: coords, thickness: this.currentThickness, fill: false } }; + } else if (this.drawingTool === 'circle') { + this.currentShape = { type: 'circle', data: { color: this.currentColor, start: coords, end: coords, thickness: this.currentThickness, fill: false } }; + } else if (this.drawingTool === 'eraser') { + this.currentShape = { type: 'eraser', data: { color: '#ffffff', start: coords, end: coords, thickness: 3 } }; + } + + this.emit('drawingStart', this.currentShape); + } + + handleMouseMove(e) { + if (!this.isDrawing || !this.currentShape) return; + const coords = this.getMouseCoordinates(e); + + if (this.drawingTool === 'pencil') { + this.currentShape.data.path.push(coords); + } else { + this.currentShape.data.end = coords; + } + + this.render(); + this.emit('drawingUpdate', this.currentShape); + } + + handleMouseUp(e) { + if (!this.isDrawing || !this.currentShape) return; + this.isDrawing = false; + const coords = this.getMouseCoordinates(e); + if (this.drawingTool === 'pencil' && this.pathOptimizationEnabled && this.currentShape.data.path.length > 10) { + this.currentShape.data.path = this.optimizePath(this.currentShape.data.path); + } else { + this.currentShape.data.end = coords; + } + + this.shapes.push({ ...this.currentShape }); + this.emit('drawingEnd', this.currentShape); + this.currentShape = null; + this.render(); + } + + handleMouseLeave(e) { + if (this.isDrawing) this.handleMouseUp(e); + } + + optimizePath(path) { + if (path.length < 3) return path; + const optimizedPath = [path[0]]; + for (let i = 1; i < path.length - 1;) { + let a = 1; + while (i + a < path.length && this.calculateDistance(path[i], path[i + a]) < this.optimizationThreshold) a++; + optimizedPath.push(path[i]); + i += a; + } + optimizedPath.push(path[path.length - 1]); + return optimizedPath; + } + + calculateDistance(p1, p2) { + return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); + } + + addShape(shapeData) { + if (Array.isArray(shapeData)) this.shapes.push(...shapeData); + else this.shapes.push(shapeData); + this.render(); + } + + clearCanvas() { + this.shapes = []; + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + this.emit('clear'); + } + + exportToDataURL(type = 'image/png', quality = 1) { + return this.canvas.toDataURL(type, quality); + } + + render() { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + // 绘制历史形状 + this.shapes.forEach(shape => this.drawShape(shape)); + + // 绘制当前正在绘制的形状 + if (this.currentShape) this.drawShape(this.currentShape); + + // 画画布边框 + this.ctx.save(); + this.ctx.strokeStyle = "#000"; + this.ctx.lineWidth = 2; + this.ctx.strokeRect(0, 0, this.canvas.width, this.canvas.height); + this.ctx.restore(); + } + + drawShape(shape) { + switch (shape.type) { + case 'pencil': this.drawPencil(shape.data); break; + case 'line': this.drawLine(shape.data); break; + case 'rectangle': this.drawRectangle(shape.data); break; + case 'circle': this.drawCircle(shape.data); break; + case 'eraser': this.drawEraser(shape.data, shape); break; + } + } + + drawPencil(p) { + if (p.path.length < 2) return; + const path = p.path.map(pt => ({ x: pt.x * this.canvas.width, y: pt.y * this.canvas.height })); + this.ctx.beginPath(); + this.ctx.strokeStyle = p.color; + this.ctx.lineWidth = p.thickness; + this.ctx.lineCap = 'round'; + this.ctx.lineJoin = 'round'; + this.drawSmoothCurve(this.ctx, path); + this.ctx.stroke(); + } + + drawSmoothCurve(ctx, path) { + if (path.length < 3) { ctx.moveTo(path[0].x, path[0].y); for (let i = 1; i < path.length; i++) ctx.lineTo(path[i].x, path[i].y); return; } + ctx.moveTo(path[0].x, path[0].y); + const threshold = 5; + for (let i = 1; i < path.length - 2;) { + let a = 1; + while (i + a < path.length - 2 && + Math.sqrt(Math.pow(path[i].x - path[i + a].x, 2) + Math.pow(path[i].y - path[i + a].y, 2)) < threshold) a++; + const xc = (path[i].x + path[i + a].x) / 2; + const yc = (path[i].y + path[i + a].y) / 2; + ctx.quadraticCurveTo(path[i].x, path[i].y, xc, yc); + i += a; + } + ctx.lineTo(path[path.length - 1].x, path[path.length - 1].y); + } + + drawLine(l) { + const sx = l.start.x * this.canvas.width, sy = l.start.y * this.canvas.height; + const ex = l.end.x * this.canvas.width, ey = l.end.y * this.canvas.height; + this.ctx.beginPath(); + this.ctx.moveTo(sx, sy); + this.ctx.lineTo(ex, ey); + this.ctx.strokeStyle = l.color; + this.ctx.lineWidth = l.thickness; + this.ctx.stroke(); + } + + drawRectangle(r) { + const sx = r.start.x * this.canvas.width, sy = r.start.y * this.canvas.height; + const ex = r.end.x * this.canvas.width, ey = r.end.y * this.canvas.height; + const w = ex - sx, h = ey - sy; + this.ctx.beginPath(); + this.ctx.rect(sx, sy, w, h); + if (r.fill) { this.ctx.fillStyle = r.color; this.ctx.fill(); } + else { this.ctx.strokeStyle = r.color; this.ctx.lineWidth = r.thickness; this.ctx.stroke(); } + } + + drawCircle(c) { + const sx = c.start.x * this.canvas.width, sy = c.start.y * this.canvas.height; + const ex = c.end.x * this.canvas.width, ey = c.end.y * this.canvas.height; + const cx = (sx + ex) / 2, cy = (sy + ey) / 2; + const rx = Math.abs(ex - sx) / 2, ry = Math.abs(ey - sy) / 2; + this.ctx.beginPath(); + this.ctx.ellipse(cx, cy, rx, ry, 0, 0, 2 * Math.PI); + if (c.fill) { this.ctx.fillStyle = c.color; this.ctx.fill(); } + else { this.ctx.strokeStyle = c.color; this.ctx.lineWidth = c.thickness; this.ctx.stroke(); } + } + + drawEraser(e, shapeObj) { + const sx = e.start.x * this.canvas.width, sy = e.start.y * this.canvas.height; + const ex = e.end.x * this.canvas.width, ey = e.end.y * this.canvas.height; + const w = Math.abs(ex - sx), h = Math.abs(ey - sy); + const x = Math.min(sx, ex), y = Math.min(sy, ey); + + this.ctx.beginPath(); + this.ctx.rect(x, y, w, h); + this.ctx.fillStyle = 'rgba(255,255,255)'; + this.ctx.fill(); + + // 仅当前正在绘制的橡皮擦显示边框 + if (this.currentShape && shapeObj === this.currentShape) { + this.ctx.save(); + this.ctx.strokeStyle = '#000'; + this.ctx.lineWidth = 1; + this.ctx.strokeRect(x, y, w, h); + this.ctx.restore(); + } + } + + destroy() { + this.canvas.removeEventListener('mousedown', this.handleMouseDown); + this.canvas.removeEventListener('mousemove', this.handleMouseMove); + this.canvas.removeEventListener('mouseup', this.handleMouseUp); + this.canvas.removeEventListener('mouseleave', this.handleMouseLeave); + window.removeEventListener('resize', this.resize); + } +} + +export default Canvas; diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..4cf7924 --- /dev/null +++ b/src/main.js @@ -0,0 +1,28 @@ + +import { createApp } from 'vue' +import { createPinia } from 'pinia' + +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' +import "@/assets/styles/index.scss"; // global css + +import * as ElementPlusIconsVue from '@element-plus/icons-vue' +import zhCn from 'element-plus/es/locale/lang/zh-cn' + +import App from './App.vue' +import router from './router' + +const app = createApp(App) + + +for (const [key, component] of Object.entries(ElementPlusIconsVue)) { + app.component(key, component) +} + +app.use(createPinia()) +app.use(router) +app.use(ElementPlus, { + locale: zhCn, +}) + +app.mount('#app') diff --git a/src/plugins/cache.js b/src/plugins/cache.js new file mode 100644 index 0000000..6b5c00b --- /dev/null +++ b/src/plugins/cache.js @@ -0,0 +1,77 @@ +const sessionCache = { + set (key, value) { + if (!sessionStorage) { + return + } + if (key != null && value != null) { + sessionStorage.setItem(key, value) + } + }, + get (key) { + if (!sessionStorage) { + return null + } + if (key == null) { + return null + } + return sessionStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + sessionStorage.removeItem(key); + } +} +const localCache = { + set (key, value) { + if (!localStorage) { + return + } + if (key != null && value != null) { + localStorage.setItem(key, value) + } + }, + get (key) { + if (!localStorage) { + return null + } + if (key == null) { + return null + } + return localStorage.getItem(key) + }, + setJSON (key, jsonValue) { + if (jsonValue != null) { + this.set(key, JSON.stringify(jsonValue)) + } + }, + getJSON (key) { + const value = this.get(key) + if (value != null) { + return JSON.parse(value) + } + }, + remove (key) { + localStorage.removeItem(key); + } +} + +export default { + /** + * 会话级缓存 + */ + session: sessionCache, + /** + * 本地缓存 + */ + local: localCache +} diff --git a/src/router/index.js b/src/router/index.js new file mode 100644 index 0000000..d28b7d2 --- /dev/null +++ b/src/router/index.js @@ -0,0 +1,35 @@ +import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router' + + +const router = createRouter({ + history: createWebHashHistory(import.meta.env.BASE_URL), + routes: [ + // { + // path: '/', + // component: () => import("@/views/custom/tabulaRase/index.vue"), + // }, + { + path: '/', + redirect: '/login', // 这里做重定向 + }, + { + path: '/whiteboard', + component: () => import('@/views/custom/tabulaRase/index.vue'), + }, + { + path: "/login", + component: () => import("@/views/login.vue"), + }, + // 错误页面路由 + { + path: "/:pathMatch(.*)*", + component: () => import("@/views/error/404.vue"), + }, + { + path: "/401", + component: () => import("@/views/error/401.vue"), + } + ], +}) + +export default router diff --git a/src/stores/counter.js b/src/stores/counter.js new file mode 100644 index 0000000..b6757ba --- /dev/null +++ b/src/stores/counter.js @@ -0,0 +1,12 @@ +import { ref, computed } from 'vue' +import { defineStore } from 'pinia' + +export const useCounterStore = defineStore('counter', () => { + const count = ref(0) + const doubleCount = computed(() => count.value * 2) + function increment() { + count.value++ + } + + return { count, doubleCount, increment } +}) diff --git a/src/stores/index.js b/src/stores/index.js new file mode 100644 index 0000000..e69de29 diff --git a/src/stores/modules/meter.js b/src/stores/modules/meter.js new file mode 100644 index 0000000..3e7d630 --- /dev/null +++ b/src/stores/modules/meter.js @@ -0,0 +1,33 @@ +import { defineStore } from 'pinia' +import { generateUUID } from '@/utils/tools.js' + +export const useMeterStore = defineStore('meter', { + state: () => ({ + udid: '' + }), + actions: { + initUdid() { + var udid = window.localStorage.getItem('UDID') + if (!udid) { + udid = generateUUID(); + window.localStorage.setItem("UDID", udid); + } + this.setUdid(udid) + }, + setUdid(udid) { + this.udid = udid + }, + getUdid() { + return this.udid + }, + getSudid() { + var typedArray = new Uint8Array(this.udid.match(/[\da-f]{2}/gi).map(function (h) { + return parseInt(h, 16) + })); + const sudid = btoa(String.fromCharCode.apply(null, typedArray)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); + + return sudid + } + } + +}) \ No newline at end of file diff --git a/src/stores/modules/user.js b/src/stores/modules/user.js new file mode 100644 index 0000000..d8d0a51 --- /dev/null +++ b/src/stores/modules/user.js @@ -0,0 +1,72 @@ + +import { login, logout, getInfo } from '@/api/login' +import { getToken, setToken, removeToken } from '@/utils/auth' +import { defineStore } from 'pinia' + +const useUserStore = defineStore( + 'user', + { + state: () => ({ + token: getToken(), + name: '', + avatar: '', + roles: '', + }), + actions: { + // 登录 + async login(userInfo) { + try { + const { username, password } = userInfo; + const trimmedUsername = username.trim(); + + const res = await login(trimmedUsername, password); + const { token, user } = res.data; + localStorage.setItem('userData', JSON.stringify(user)); + setToken(token); + this.token = token; + + } catch (error) { + console.error('登录失败:', error); + throw error; + } + }, + // 获取用户信息 + getInfo() { + return new Promise((resolve, reject) => { + try { + const userData = localStorage.getItem('userData'); + + if (!userData) { + return reject(new Error('未找到用户数据')); + } + const parsedData = JSON.parse(userData); + if (!parsedData) { + return reject(new Error('用户数据格式无效')); + } + resolve(parsedData); + } catch (error) { + console.error('获取用户信息失败:', error); + reject(error instanceof Error ? error : new Error('解析用户数据失败')); + } + }); + }, + // 退出系统 + async logOut() { + try { + await logout(); + this.token = ''; + this.roles = ''; + removeToken(); + } catch (error) { + console.error('退出登录失败:', error); + throw error; + } + }, + //判断是否登录 + checkLogin() { + return !!getToken(); + } + } + }) + +export default useUserStore diff --git a/src/utils/auth.js b/src/utils/auth.js new file mode 100644 index 0000000..e8cd791 --- /dev/null +++ b/src/utils/auth.js @@ -0,0 +1,30 @@ + +import Cookies from "js-cookie"; + +const TokenKey = "token"; + +const ExpiresInKey = "Meta-Enterprise-Expires-In"; + +export function getToken() { + return Cookies.get(TokenKey); +} + +export function setToken(token) { + return Cookies.set(TokenKey, token); +} + +export function removeToken() { + return Cookies.remove(TokenKey); +} + +export function getExpiresIn() { + return Cookies.get(ExpiresInKey) || -1; +} + +export function setExpiresIn(time) { + return Cookies.set(ExpiresInKey, time); +} + +export function removeExpiresIn() { + return Cookies.remove(ExpiresInKey); +} diff --git a/src/utils/bigDecimal.js b/src/utils/bigDecimal.js new file mode 100644 index 0000000..9d98e22 --- /dev/null +++ b/src/utils/bigDecimal.js @@ -0,0 +1,583 @@ +var bigDecimal = (function (e) { + var n = {} + function t(r) { + if (n[r]) return n[r].exports + var i = (n[r] = { i: r, l: !1, exports: {} }) + return e[r].call(i.exports, i, i.exports, t), (i.l = !0), i.exports + } + return ( + (t.m = e), + (t.c = n), + (t.d = function (e, n, r) { + t.o(e, n) || Object.defineProperty(e, n, { enumerable: !0, get: r }) + }), + (t.r = function (e) { + 'undefined' != typeof Symbol && + Symbol.toStringTag && + Object.defineProperty(e, Symbol.toStringTag, { value: 'Module' }), + Object.defineProperty(e, '__esModule', { value: !0 }) + }), + (t.t = function (e, n) { + if ((1 & n && (e = t(e)), 8 & n)) return e + if (4 & n && 'object' == typeof e && e && e.__esModule) return e + var r = Object.create(null) + if ( + (t.r(r), + Object.defineProperty(r, 'default', { enumerable: !0, value: e }), + 2 & n && 'string' != typeof e) + ) + for (var i in e) + t.d( + r, + i, + function (n) { + return e[n] + }.bind(null, i) + ) + return r + }), + (t.n = function (e) { + var n = + e && e.__esModule + ? function () { + return e.default + } + : function () { + return e + } + return t.d(n, 'a', n), n + }), + (t.o = function (e, n) { + return Object.prototype.hasOwnProperty.call(e, n) + }), + (t.p = ''), + t((t.s = 6)) + ) +})([ + function (e, n, t) { + 'use strict' + function r(e) { + for ( + var n = '', + t = e.length, + r = e.split('.')[1], + i = r ? r.length : 0, + o = 0; + o < t; + o++ + ) + e[o] >= '0' && e[o] <= '9' ? (n += 9 - parseInt(e[o])) : (n += e[o]) + return u(n, i > 0 ? '0.' + new Array(i).join('0') + '1' : '1') + } + function i(e) { + var n = e.split('.') + for (n[0] || (n[0] = '0'); '0' == n[0][0] && n[0].length > 1;) + n[0] = n[0].substring(1) + return n[0] + (n[1] ? '.' + n[1] : '') + } + function o(e, n) { + var t = e.split('.'), + r = n.split('.'), + i = t[0].length, + o = r[0].length + return ( + i > o + ? (r[0] = + new Array(Math.abs(i - o) + 1).join('0') + (r[0] ? r[0] : '')) + : (t[0] = + new Array(Math.abs(i - o) + 1).join('0') + (t[0] ? t[0] : '')), + (i = t[1] ? t[1].length : 0), + (o = r[1] ? r[1].length : 0), + (i || o) && + (i > o + ? (r[1] = + (r[1] ? r[1] : '') + new Array(Math.abs(i - o) + 1).join('0')) + : (t[1] = + (t[1] ? t[1] : '') + new Array(Math.abs(i - o) + 1).join('0'))), + [ + (e = t[0] + (t[1] ? '.' + t[1] : '')), + (n = r[0] + (r[1] ? '.' + r[1] : '')), + ] + ) + } + function u(e, n) { + var t + ; (e = (t = o(e, n))[0]), (n = t[1]) + for (var r = '', i = 0, u = e.length - 1; u >= 0; u--) + if ('.' !== e[u]) { + var a = parseInt(e[u]) + parseInt(n[u]) + i + ; (r = (a % 10) + r), (i = Math.floor(a / 10)) + } else r = '.' + r + return i ? i.toString() + r : r + } + Object.defineProperty(n, '__esModule', { value: !0 }), + (n.pad = n.trim = n.add = void 0), + (n.add = function (e, n) { + var t + void 0 === n && (n = '0') + var a = 0, + s = -1 + '-' == e[0] && (a++, (s = 1), (e = e.substring(1)).length), + '-' == n[0] && (a++, (s = 2), (n = n.substring(1)).length), + (e = i(e)), + (n = i(n)), + (e = (t = o(i(e), i(n)))[0]), + (n = t[1]), + 1 == a && (1 == s ? (e = r(e)) : (n = r(n))) + var d = u(e, n) + return a + ? 2 == a + ? '-' + i(d) + : e.length < d.length + ? i(d.substring(1)) + : '-' + i(r(d)) + : i(d) + }), + (n.trim = i), + (n.pad = o) + }, + function (e, n, t) { + 'use strict' + Object.defineProperty(n, '__esModule', { value: !0 }), (n.roundOff = void 0) + var r = t(2) + function i(e, n, t, i) { + if (!e || e === new Array(e.length + 1).join('0')) return !1 + if ( + i === r.RoundingModes.DOWN || + (!t && i === r.RoundingModes.FLOOR) || + (t && i === r.RoundingModes.CEILING) + ) + return !1 + if ( + i === r.RoundingModes.UP || + (t && i === r.RoundingModes.FLOOR) || + (!t && i === r.RoundingModes.CEILING) + ) + return !0 + var o = '5' + new Array(e.length).join('0') + if (e > o) return !0 + if (e < o) return !1 + switch (i) { + case r.RoundingModes.HALF_DOWN: + return !1 + case r.RoundingModes.HALF_UP: + return !0 + case r.RoundingModes.HALF_EVEN: + default: + return parseInt(n[n.length - 1]) % 2 == 1 + } + } + function o(e, n) { + void 0 === n && (n = 0), + n || (n = 1), + 'number' == typeof e && e.toString() + for (var t = '', r = e.length - 1; r >= 0; r--) { + var i = parseInt(e[r]) + n + 10 == i ? ((n = 1), (i = 0)) : (n = 0), (t += i) + } + return n && (t += n), t.split('').reverse().join('') + } + n.roundOff = function e(n, t, u) { + if ( + (void 0 === t && (t = 0), + void 0 === u && (u = r.RoundingModes.HALF_EVEN), + u === r.RoundingModes.UNNECESSARY) + ) + throw new Error( + 'UNNECESSARY Rounding Mode has not yet been implemented' + ) + 'number' == typeof n && (n = n.toString()) + var a = !1 + '-' === n[0] && ((a = !0), (n = n.substring(1))) + var s = n.split('.'), + d = s[0], + l = s[1] + if (t < 0) { + if (((t = -t), d.length <= t)) return '0' + var f = d.substr(0, d.length - t) + return ( + (a ? '-' : '') + + (f = e((n = f + '.' + d.substr(d.length - t) + l), 0, u)) + + new Array(t + 1).join('0') + ) + } + if (0 == t) { + d.length + return i(s[1], d, a, u) ? (a ? '-' : '') + o(d) : (a ? '-' : '') + d + } + if (!s[1]) return (a ? '-' : '') + d + '.' + new Array(t + 1).join('0') + if (s[1].length < t) + return ( + (a ? '-' : '') + + d + + '.' + + s[1] + + new Array(t - s[1].length + 1).join('0') + ) + l = s[1].substring(0, t) + var g = s[1].substring(t) + return g && i(g, l, a, u) && (l = o(l)).length > t + ? o(d, parseInt(l[0])) + '.' + l.substring(1) + : (a ? '-' : '') + d + '.' + l + } + }, + function (e, n, t) { + 'use strict' + Object.defineProperty(n, '__esModule', { value: !0 }), + (n.RoundingModes = void 0), + (function (e) { + ; (e[(e.CEILING = 0)] = 'CEILING'), + (e[(e.DOWN = 1)] = 'DOWN'), + (e[(e.FLOOR = 2)] = 'FLOOR'), + (e[(e.HALF_DOWN = 3)] = 'HALF_DOWN'), + (e[(e.HALF_EVEN = 4)] = 'HALF_EVEN'), + (e[(e.HALF_UP = 5)] = 'HALF_UP'), + (e[(e.UNNECESSARY = 6)] = 'UNNECESSARY'), + (e[(e.UP = 7)] = 'UP') + })(n.RoundingModes || (n.RoundingModes = {})) + }, + function (e, n, t) { + 'use strict' + function r(e) { + for (; '0' == e[0];) e = e.substr(1) + if (-1 != e.indexOf('.')) + for (; '0' == e[e.length - 1];) e = e.substr(0, e.length - 1) + return ( + '' == e || '.' == e + ? (e = '0') + : '.' == e[e.length - 1] && (e = e.substr(0, e.length - 1)), + '.' == e[0] && (e = '0' + e), + e + ) + } + Object.defineProperty(n, '__esModule', { value: !0 }), + (n.multiply = void 0), + (n.multiply = function (e, n) { + ; (e = e.toString()), (n = n.toString()) + var t = 0 + '-' == e[0] && (t++, (e = e.substr(1))), + '-' == n[0] && (t++, (n = n.substr(1))), + (e = r(e)), + (n = r(n)) + var i = 0, + o = 0 + ; -1 != e.indexOf('.') && (i = e.length - e.indexOf('.') - 1), + -1 != n.indexOf('.') && (o = n.length - n.indexOf('.') - 1) + var u = i + o + if ( + ((e = r(e.replace('.', ''))), + (n = r(n.replace('.', ''))), + e.length < n.length) + ) { + var a = e + ; (e = n), (n = a) + } + if ('0' == n) return '0' + for ( + var s, d, l = n.length, f = 0, g = [], c = l - 1, v = '', p = 0; + p < l; + p++ + ) + g[p] = e.length - 1 + for (p = 0; p < 2 * e.length; p++) { + for (var h = 0, b = n.length - 1; b >= c && b >= 0; b--) + g[b] > -1 && + g[b] < e.length && + (h += parseInt(e[g[b]--]) * parseInt(n[b])) + ; (h += f), (f = Math.floor(h / 10)), (v = (h % 10) + v), c-- + } + return ( + (v = r( + ((s = v), + 0 == (d = u) + ? s + : (s = + d >= s.length + ? new Array(d - s.length + 1).join('0') + s + : s).substr(0, s.length - d) + + '.' + + s.substr(s.length - d, d)) + )), + 1 == t && (v = '-' + v), + v + ) + }) + }, + function (e, n, t) { + 'use strict' + Object.defineProperty(n, '__esModule', { value: !0 }), (n.divide = void 0) + var r = t(0), + i = t(1) + n.divide = function (e, n, t) { + if ((void 0 === t && (t = 8), 0 == n)) + throw new Error('Cannot divide by 0') + if ( + ((e = e.toString()), + (n = n.toString()), + (e = e.replace(/(\.\d*?[1-9])0+$/g, '$1').replace(/\.0+$/, '')), + (n = n.replace(/(\.\d*?[1-9])0+$/g, '$1').replace(/\.0+$/, '')), + 0 == e) + ) + return '0' + var o = 0 + '-' == n[0] && ((n = n.substring(1)), o++), + '-' == e[0] && ((e = e.substring(1)), o++) + var u = n.indexOf('.') > 0 ? n.length - n.indexOf('.') - 1 : -1 + if (((n = r.trim(n.replace('.', ''))), u >= 0)) { + var a = e.indexOf('.') > 0 ? e.length - e.indexOf('.') - 1 : -1 + if (-1 == a) e = r.trim(e + new Array(u + 1).join('0')) + else if (u > a) + (e = e.replace('.', '')), + (e = r.trim(e + new Array(u - a + 1).join('0'))) + else if (u < a) { + var s = (e = e.replace('.', '')).length - a + u + e = r.trim(e.substring(0, s) + '.' + e.substring(s)) + } else u == a && (e = r.trim(e.replace('.', ''))) + } + var d = 0, + l = n.length, + f = '', + g = + e.indexOf('.') > -1 && e.indexOf('.') < l + ? e.substring(0, l + 1) + : e.substring(0, l) + if ( + ((e = + e.indexOf('.') > -1 && e.indexOf('.') < l + ? e.substring(l + 1) + : e.substring(l)), + g.indexOf('.') > -1) + ) { + var c = g.length - g.indexOf('.') - 1 + l > (g = g.replace('.', '')).length && + ((c += l - g.length), (g += new Array(l - g.length + 1).join('0'))), + (d = c), + (f = '0.' + new Array(c).join('0')) + } + for (t += 2; d <= t;) { + for (var v = 0; parseInt(g) >= parseInt(n);) + (g = r.add(g, '-' + n)), v++ + ; (f += v), + e + ? ('.' == e[0] && ((f += '.'), d++, (e = e.substring(1))), + (g += e.substring(0, 1)), + (e = e.substring(1))) + : (d || (f += '.'), d++, (g += '0')) + } + return (1 == o ? '-' : '') + r.trim(i.roundOff(f, t - 2)) + } + }, + function (e, n, t) { + 'use strict' + Object.defineProperty(n, '__esModule', { value: !0 }), + (n.negate = n.subtract = void 0) + var r = t(0) + function i(e) { + return (e = '-' == e[0] ? e.substr(1) : '-' + e) + } + ; (n.subtract = function (e, n) { + return (e = e.toString()), (n = i((n = n.toString()))), r.add(e, n) + }), + (n.negate = i) + }, + function (e, n, t) { + 'use strict' + var r = t(0), + i = t(1), + o = t(3), + u = t(4), + a = t(7), + s = t(8), + d = t(5), + l = t(2), + f = (function () { + function e(n) { + void 0 === n && (n = '0'), (this.value = e.validate(n)) + } + return ( + (e.validate = function (e) { + if (e) { + if (((e = e.toString()), isNaN(e))) + throw Error('Parameter is not a number: ' + e) + '+' == e[0] && (e = e.substring(1)) + } else e = '0' + if (/e/i.test(e)) { + var n = e.split(/[eE]/), + t = n[0], + i = n[1] + ; (t = r.trim(t)), + (i = parseInt(i) + t.indexOf('.')), + (e = + (t = t.replace('.', '')).length < i + ? t + new Array(i - t.length + 1).join('0') + : t.length >= i && i > 0 + ? r.trim(t.substring(0, i)) + + (t.length > i ? '.' + t.substring(i) : '') + : '0.' + new Array(1 - i).join('0') + t) + } + return e + }), + (e.prototype.getValue = function () { + return this.value + }), + (e.getPrettyValue = function (n, t, r) { + if (t || r) { + if (!t || !r) + throw Error( + 'Illegal Arguments. Should pass both digits and separator or pass none' + ) + } else (t = 3), (r = ',') + var i = '-' == (n = e.validate(n)).charAt(0) + i && (n = n.substring(1)) + for ( + var o = n.indexOf('.'), u = '', a = (o = o > 0 ? o : n.length); + a > 0; + + ) + a < t ? ((t = a), (a = 0)) : (a -= t), + (u = n.substring(a, a + t) + (a < o - t && a >= 0 ? r : '') + u) + return (i ? '-' : '') + u + n.substring(o) + }), + (e.prototype.getPrettyValue = function (n, t) { + return e.getPrettyValue(this.value, n, t) + }), + (e.round = function (n, t, r) { + if ( + (void 0 === t && (t = 0), + void 0 === r && (r = l.RoundingModes.HALF_EVEN), + (n = e.validate(n)), + isNaN(t)) + ) + throw Error('Precision is not a number: ' + t) + return i.roundOff(n, t, r) + }), + (e.prototype.round = function (n, t) { + if ( + (void 0 === n && (n = 0), + void 0 === t && (t = l.RoundingModes.HALF_EVEN), + isNaN(n)) + ) + throw Error('Precision is not a number: ' + n) + return new e(i.roundOff(this.value, n, t)) + }), + (e.floor = function (n) { + return -1 === (n = e.validate(n)).indexOf('.') + ? n + : e.round(n, 0, l.RoundingModes.FLOOR) + }), + (e.prototype.floor = function () { + return -1 === this.value.indexOf('.') + ? new e(this.value) + : new e(this.value).round(0, l.RoundingModes.FLOOR) + }), + (e.ceil = function (n) { + return -1 === (n = e.validate(n)).indexOf('.') + ? n + : e.round(n, 0, l.RoundingModes.CEILING) + }), + (e.prototype.ceil = function () { + return -1 === this.value.indexOf('.') + ? new e(this.value) + : new e(this.value).round(0, l.RoundingModes.CEILING) + }), + (e.add = function (n, t) { + return (n = e.validate(n)), (t = e.validate(t)), r.add(n, t) + }), + (e.prototype.add = function (n) { + return new e(r.add(this.value, n.getValue())) + }), + (e.subtract = function (n, t) { + return (n = e.validate(n)), (t = e.validate(t)), d.subtract(n, t) + }), + (e.prototype.subtract = function (n) { + return new e(d.subtract(this.value, n.getValue())) + }), + (e.multiply = function (n, t) { + return (n = e.validate(n)), (t = e.validate(t)), o.multiply(n, t) + }), + (e.prototype.multiply = function (n) { + return new e(o.multiply(this.value, n.getValue())) + }), + (e.divide = function (n, t, r) { + return (n = e.validate(n)), (t = e.validate(t)), u.divide(n, t, r) + }), + (e.prototype.divide = function (n, t) { + return new e(u.divide(this.value, n.getValue(), t)) + }), + (e.modulus = function (n, t) { + return (n = e.validate(n)), (t = e.validate(t)), a.modulus(n, t) + }), + (e.prototype.modulus = function (n) { + return new e(a.modulus(this.value, n.getValue())) + }), + (e.compareTo = function (n, t) { + return (n = e.validate(n)), (t = e.validate(t)), s.compareTo(n, t) + }), + (e.prototype.compareTo = function (e) { + return s.compareTo(this.value, e.getValue()) + }), + (e.negate = function (n) { + return (n = e.validate(n)), d.negate(n) + }), + (e.prototype.negate = function () { + return new e(d.negate(this.value)) + }), + (e.RoundingModes = l.RoundingModes), + e + ) + })() + e.exports = f + }, + function (e, n, t) { + 'use strict' + Object.defineProperty(n, '__esModule', { value: !0 }), (n.modulus = void 0) + var r = t(4), + i = t(1), + o = t(3), + u = t(5), + a = t(2) + function s(e) { + if (-1 != e.indexOf('.')) + throw new Error('Modulus of non-integers not supported') + } + n.modulus = function (e, n) { + if (0 == n) throw new Error('Cannot divide by 0') + ; (e = e.toString()), (n = n.toString()), s(e), s(n) + var t = '' + return ( + '-' == e[0] && ((t = '-'), (e = e.substr(1))), + '-' == n[0] && (n = n.substr(1)), + t + + u.subtract( + e, + o.multiply(n, i.roundOff(r.divide(e, n), 0, a.RoundingModes.FLOOR)) + ) + ) + } + }, + function (e, n, t) { + 'use strict' + Object.defineProperty(n, '__esModule', { value: !0 }), + (n.compareTo = void 0) + var r = t(0) + n.compareTo = function (e, n) { + var t, + i = !1 + if ('-' == e[0] && '-' != n[0]) return -1 + if ('-' != e[0] && '-' == n[0]) return 1 + if ( + ('-' == e[0] && + '-' == n[0] && + ((e = e.substr(1)), (n = n.substr(1)), (i = !0)), + (e = (t = r.pad(e, n))[0]), + (n = t[1]), + 0 == e.localeCompare(n)) + ) + return 0 + for (var o = 0; o < e.length; o++) + if (e[o] != n[o]) return e[o] > n[o] ? (i ? -1 : 1) : i ? 1 : -1 + return 0 + } + }, +]) +export default bigDecimal \ No newline at end of file diff --git a/src/utils/emitter.js b/src/utils/emitter.js new file mode 100644 index 0000000..7f8f640 --- /dev/null +++ b/src/utils/emitter.js @@ -0,0 +1,25 @@ +import mitt from 'mitt'; + +class EventEmitter { + constructor() { + this.emitter = mitt(); + } + + on(eventName, handler) { + this.emitter.on(eventName, handler); + } + + off(eventName, handler) { + this.emitter.off(eventName, handler); + } + + emit(eventName, event) { + this.emitter.emit(eventName, event); + } + + removeAllListeners() { + this.emitter.all.clear(); + } +} + +export default EventEmitter; diff --git a/src/utils/errorCode.js b/src/utils/errorCode.js new file mode 100644 index 0000000..d2111ee --- /dev/null +++ b/src/utils/errorCode.js @@ -0,0 +1,6 @@ +export default { + '401': '认证失败,无法访问系统资源', + '403': '当前操作没有权限', + '404': '访问资源不存在', + 'default': '系统未知错误,请反馈给管理员' +} diff --git a/src/utils/mqtt.js b/src/utils/mqtt.js new file mode 100644 index 0000000..0bb9795 --- /dev/null +++ b/src/utils/mqtt.js @@ -0,0 +1,127 @@ +import mqtt from "mqtt" + +// MQTT 连接选项 +const options = { + clean: true, + connectTimeout: 4000, + reconnectPeriod: 1000, + qos: 1, // 默认 QoS 1 +} + +const brokerUrl = "wss://push.cnsdt.com:443/mqtt" // 你的 MQTT 服务地址 + +class MQTTClient { + constructor() { + this.client = null + this.subscriptions = new Set() + this.messageHandlers = new Map() + } + + // 连接 + connect(clientId) { + if (this.client && this.client.connected) { + return Promise.resolve() + } + + return new Promise((resolve, reject) => { + this.client = mqtt.connect(brokerUrl, { + ...options, + clientId: clientId || `client_${Math.random().toString(16).substr(2, 8)}`, + }) + + this.client.on("connect", () => resolve()) + this.client.on("error", (error) => reject(error)) + + // 消息分发 + this.client.on("message", (topic, payload) => { + try { + const message = JSON.parse(payload.toString()) + // 遍历所有订阅主题,执行通配符匹配 + this.messageHandlers.forEach((handlers, subTopic) => { + if (this.topicMatch(subTopic, topic)) { + handlers.forEach((handler) => handler(message, topic)) + } + }) + } catch (err) { + console.error("MQTT message parse error:", err) + } + }) + }) + } + + // 断开 + disconnect() { + if (this.client) { + this.client.end() + this.client = null + this.subscriptions.clear() + this.messageHandlers.clear() + } + } + + // 订阅 + subscribe(topic, handler) { + if (!this.client || !this.client.connected) { + console.error("MQTT client not connected") + return + } + + if (!this.subscriptions.has(topic)) { + this.client.subscribe(topic, { qos: 1 }, (err) => { + if (err) { + console.error("Subscription error:", err) + } else { + this.subscriptions.add(topic) + } + }) + } + + const handlers = this.messageHandlers.get(topic) || [] + handlers.push(handler) + this.messageHandlers.set(topic, handlers) + } + + // 取消订阅 + unsubscribe(topic, handler) { + if (!this.subscriptions.has(topic)) return + + if (handler) { + const handlers = this.messageHandlers.get(topic) || [] + const index = handlers.indexOf(handler) + if (index !== -1) { + handlers.splice(index, 1) + this.messageHandlers.set(topic, handlers) + } + } else { + this.client.unsubscribe(topic) + this.subscriptions.delete(topic) + this.messageHandlers.delete(topic) + } + } + + // 发布 + publish(topic, message) { + if (!this.client || !this.client.connected) { + console.error("MQTT client not connected") + return + } + this.client.publish(topic, JSON.stringify(message), { qos: 1 }) + } + + // 通配符匹配 + topicMatch(subTopic, msgTopic) { + const subLevels = subTopic.split("/") + const msgLevels = msgTopic.split("/") + + for (let i = 0; i < subLevels.length; i++) { + if (subLevels[i] === "#") return true + if (subLevels[i] === "+") continue + if (msgLevels[i] === undefined) return false + if (subLevels[i] !== msgLevels[i]) return false + } + + return subLevels.length === msgLevels.length + } +} + +export const mqttClient = new MQTTClient() diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..a71a0be --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,194 @@ +import axios from "axios"; +import { + ElNotification, + ElMessageBox, + ElMessage, +} from "element-plus"; +import { tansParams } from "@/utils/ruoyi"; +import cache from "@/plugins/cache"; +import { getToken, removeToken } from "@/utils/auth"; +import router from '@/router'; +import { useMeterStore } from '@/stores/modules/meter' + +axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8"; +const meterStore = useMeterStore() +meterStore.initUdid() +// 创建axios实例 +const service = axios.create({ + // axios中请求配置有baseURL选项,表示请求URL公共部分 + baseURL: import.meta.env.VITE_APP_BASE_API, + // 超时 + timeout: 10000, +}); + +// request拦截器 +service.interceptors.request.use( + (config) => { + + // 是否需要设置 token + const isToken = (config.headers || {}).isToken === false; + if (getToken() && !isToken) { + config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 + } + + // 是否需要防止数据重复提交 + const isRepeatSubmit = (config.headers || {}).repeatSubmit === false; + if (meterStore.getSudid()) { + config.headers["X-User-Agent"] = `gxtech/web 1.0.0: c=GxTech, udid=${meterStore.getSudid()}, sv=15.4.1, app=stt`; + } + // get请求映射params参数 + if (config.method === "get" && config.params) { + + let url = config.url + "?" + tansParams(config.params); + url = url.slice(0, -1); + config.params = {}; + config.url = url; + } + if ( + !isRepeatSubmit && + (config.method === "post" || config.method === "put") + ) { + const requestObj = { + url: config.url, + data: + typeof config.data === "object" + ? JSON.stringify(config.data) + : config.data, + time: new Date().getTime(), + }; + const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 + const limitSize = 5 * 1024 * 1024; // 限制存放数据5M + if (requestSize >= limitSize) { + console.warn( + `[${config.url}]: ` + + "请求数据大小超出允许的5M限制,无法进行防重复提交验证。" + ); + return config; + } + const sessionObj = cache.session.getJSON("sessionObj"); + if ( + sessionObj === undefined || + sessionObj === null || + sessionObj === "" + ) { + cache.session.setJSON("sessionObj", requestObj); + } else { + const s_url = sessionObj.url; // 请求地址 + const s_data = sessionObj.data; // 请求数据 + const s_time = sessionObj.time; // 请求时间 + const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交 + if ( + s_data === requestObj.data && + requestObj.time - s_time < interval && + s_url === requestObj.url + ) { + const message = "数据正在处理,请勿重复提交"; + console.warn(`[${s_url}]: ` + message); + return Promise.reject(new Error(message)); + } else { + cache.session.setJSON("sessionObj", requestObj); + } + } + } + return config; + }, + (error) => { + Promise.reject(error); + } +); + +service.interceptors.response.use( + (response) => { + // 1. 检查响应是否存在 + if (!response) { + ElMessage.error('无响应数据'); + return Promise.reject(new Error('无响应数据')); + } + // 2. 安全获取响应数据和状态码 + const responseData = response.data || {}; + const statusCode = response.status; + const businessCode = responseData.meta?.code || statusCode; + + // 3. 二进制数据直接返回 + if ( + response.request.responseType === 'blob' || + response.request.responseType === 'arraybuffer' + ) { + return responseData; + } + + // 4. 根据业务码处理不同情况 + switch (businessCode) { + case 200: + case 201: + return Promise.resolve(responseData); + + case 401: + return handleUnauthorized().then(() => { + return Promise.reject({ code: 401, message: '未授权' }); + }); + + case 500: + const serverErrorMsg = responseData.meta?.message || '服务器内部错误'; + ElMessage({ message: serverErrorMsg, type: 'error' }); + return Promise.reject({ code: 500, message: serverErrorMsg }); + + default: + const errorMsg = responseData.meta?.message || `业务错误 (${businessCode})`; + ElNotification.error({ title: errorMsg }); + return Promise.reject({ code: businessCode, message: errorMsg }); + } + }, + (error) => { + console.error('请求错误:', error); + let { message } = error; + let code = error?.response?.status || -1; + + if (message == 'Network Error') { + message = '后端接口连接异常'; + ElMessage({ message, type: 'error', duration: 5 * 1000 }); + } else if (message.includes('timeout')) { + message = '系统接口请求超时'; + ElMessage({ message, type: 'error', duration: 5 * 1000 }); + } else if (message.includes('Request failed with status code')) { + // message = '系统接口' + message.substr(message.length - 3) + '异常'; + } + + // 返回结构化错误 + return Promise.reject({ + code, + message, + raw: error // 保留原始 error + }); + } +); + +// 单独处理401未授权 +function handleUnauthorized() { + return ElMessageBox.confirm( + '认证信息已失效,您可以继续留在该页面,或者重新登录', + '系统提示', + { + confirmButtonText: '重新登录', + cancelButtonText: '取消', + type: 'warning', + } + ) + .then(() => { + removeToken() + if (router.currentRoute.path !== '/login') { + router.push({ + path: '/login', + query: { redirect: router.currentRoute.fullPath } + }); + } else { + // 如果在登录页,强制刷新以清除残留状态 + window.location.reload(); + } + }) + .catch(() => { + return Promise.reject('用户取消操作'); + }); +} + +export default service; diff --git a/src/utils/ruoyi.js b/src/utils/ruoyi.js new file mode 100644 index 0000000..abd3afc --- /dev/null +++ b/src/utils/ruoyi.js @@ -0,0 +1,718 @@ +import bigDecimal from "@/utils/bigDecimal"; + +/** + * @description 分钟转时间 + * @author + * @date + * @param + * @returns + */ +export function formatMinutes(minutes) { + let tiemInfo = Number(minutes); + var time = []; + var day = parseInt(tiemInfo / 60 / 24); + var hour = parseInt((tiemInfo / 60) % 24); + var min = parseInt(tiemInfo % 60); + time[0] = day > 0 ? day : 0; + time[1] = hour > 0 ? hour : 0; + time[2] = min > 0 ? parseFloat(min) : 0; + return time; +} +/** + * @description 时间转分钟 + * @author + * @date + * @param + * @returns + */ +export function totalMinutes(day, hour, minute) { + return day * 1440 + hour * 60 + minute; +} +/** + * @description 数组指定必填项判断校验 + * @author // arr要判断的数组 data要判断里面那些不能为空的字段 + * @date + * @param + * @returns + */ +export function everyI(arr, data, text) { + let flag = arr.flatMap((item) => { + let flag1 = data.flatMap((key) => { + if (text == "不校验零") { + if (item[key] || item[key] == 0) { + return true; + } else { + false; + } + } else { + if (item[key]) { + return true; + } else { + false; + } + } + }); + return flag1; + }); + // 如果不只条的时候全部都要填写 every只要有一个不满足就不让走 smoe只要有一个满足就可以走 + let info = flag.every((val) => val); + return info; +} +/** + * @description 找下对应的字段显示上去 arr1枚举表 arr2对比数组 text取出的字段 + * @author cl + * @date 2022-2-17 + * @param + * @returns + */ +export function getArr(arr1, arr2, text) { + let arrInfo = []; + if (!arr2) return; + arr1.map((item) => { + arr2.split(",").map((n) => { + if (n == item.value) { + arrInfo.push(item[text]); + } + }); + }); + return arrInfo.join(","); +} +/** + * @description + * @author cl + * @date 2022-2-18 + * @param arr要计算的数组数据 Array + * @param num2要计算的价格字段 string + * @param arr2要合并计算总价的数据 string + * @param currency优惠券的币种字段 Array + * @param currency要减去的优惠券币种字段 string + * @param amount要减去的优惠券价格字段 string + * @returns + */ +export function getPriceI(arr, num1, num2, arr2, currency, amount) { + let arrInfo = arr2 ? arr2 : []; // 总计 + let currencyInfo = currency; // 优惠券币种 + let amountInfo = amount ? amount : 0; // 优惠价钱 + let price = { + USD: 0, + CNY: 0, + }; + arr.concat(arrInfo).flatMap((i) => { + if (i[num1] == "USD") { + price.USD = Number(bigDecimal.add(price.USD, i[num2])); + } else { + price.CNY = Number(bigDecimal.add(price.CNY, i[num2])); + } + }); + // 有优惠卷的话减去优惠间 + if (currencyInfo === "CNY") { + price.CNY = Number(bigDecimal.subtract(price.CNY, amountInfo)); + } else { + price.USD = Number(bigDecimal.subtract(price.USD, amountInfo)); + } + + let arrI = [ + price.USD > 0 ? "USD:" + format_with_array(price.USD) : "USD:0.00", + price.CNY > 0 ? "CNY:" + format_with_array(price.CNY) : "CNY:0.00", + ] + .filter((current) => { + return current !== "USD:0.00" && current !== "CNY:0.00"; + }) + .join(" + "); + return arrI; +} +/** + * @description 数组字段拼接回调法 + * @author cl + * @date 2022-12-9 + * @param + * @returns + */ +export function _getArr(arr, name, id, child) { + arr.forEach((item, index) => { + // 作为键值对 + item.label = item[name]; + item.value = item[id]; + if (item.children) { + _getArr(item.children, name, id); + } + }); + return arr; +} +/** + * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数 + * + * @param {Function} func 要执行的回调函数 + * @param {Number} wait 延时的时间 + * @param {Boolean} immediate 是否立即执行 + * @return null + */ +let timeout = null; +export function debounce(func, wait = 300, immediate = false) { + // 清除定时器 + if (timeout !== null) clearTimeout(timeout); + // 立即执行,此类情况一般用不到 + if (immediate) { + const callNow = !timeout; + timeout = setTimeout(() => { + timeout = null; + }, wait); + if (callNow) typeof func === "function" && func(); + } else { + // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法 + timeout = setTimeout(() => { + typeof func === "function" && func(); + }, wait); + } +} +/** + * @description 去重对比后去除已存在的替换 arrA已经选择的 arrB数据源 text去重的标识字段 type类型 + * @author cl + * @date 2022-12-9 + * @param + * @returns + */ +export function processI(arrA, arrB, text) { + // 缓存用于记录 + const cache = []; + for (const t of arrB) { + // 检查缓存中是否已经存在 + if (arrA.find((c) => c[text] === t[text])) { + // 已经存在说明以前记录过,现在这个就是多余的,直接忽略 + continue; + } + // 不存在就说明以前没遇到过,把它记录下来 + cache.push(t); + } + return cache; +} +/** + * @description 去重去除已存在的 typeName类型标记 + * @author cl + * @date 2022-2-17 + * @param + * @returns + */ +export function duplicate(arr1, arr2, text, typeName, type) { + arr1.map((item) => { + // 检查缓存中是否已经存在 + if (arr2.find((c) => c[text] == item[text])) { + // 已经存在说明以前记录过,现在这个就是多余的,直接忽略 + return; + } + // 不存在就说明以前没遇到过,把它记录下来 + if (typeName) { + item[typeName] = type; + arr2.push(item); + } else { + arr2.push(item); + } + }); + return arr2; +} +/** + * 手机号格式化 + * @param {string | number} mobile 手机号 + * @returns '188 8888 8888'格式的手机号 + */ + +export function formatMobile(mobile) { + const regMobile = /^1\d{10}/; + if (!regMobile.test(mobile)) { + return ""; + } + return String(mobile).replace(/(^\d{3}|\d{4}\B)/g, "$1 "); +} +/** + * @description 复制 + * @param {*} id DOM ID + */ +export function copyDomText(id) { + const node = document.getElementById(id); + if (node) { + let createRange = document.createRange(); + createRange.selectNodeContents(document.getElementById(id)); + const selection = document.getSelection(); + selection.removeAllRanges(); + selection.addRange(createRange); + document.execCommand("Copy"); + selection.removeAllRanges(); + } +} + +/** + * 金额 千分位 + * @param { number} mobile 金额 + * @returns '12,300,000' 金额格式 + */ +export function format_with_array( + number, + decimals, + dec_point, + thousands_sep, + round_tag +) { + number = (number + "").replace(/[^0-9+-Ee.]/g, ""); + decimals = decimals || 2; //默认保留2位 + dec_point = dec_point || "."; //默认是'.'; + thousands_sep = thousands_sep || ","; //默认是','; + round_tag = round_tag || "round"; //默认是四舍五入 + var n = !isFinite(+number) ? 0 : +number, + prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), + sep = typeof thousands_sep === "undefined" ? "," : thousands_sep, + dec = typeof dec_point === "undefined" ? "." : dec_point, + s = "", + toFixedFix = function (n, prec) { + var k = Math.pow(10, prec); + + return ( + "" + + parseFloat( + Math[round_tag](parseFloat((n * k).toFixed(prec * 2))).toFixed( + prec * 2 + ) + ) / + k + ); + }; + s = (prec ? toFixedFix(n, prec) : "" + Math.round(n)).split("."); + var re = /(-?\d+)(\d{3})/; + while (re.test(s[0])) { + s[0] = s[0].replace(re, "$1" + sep + "$2"); + } + if ((s[1] || "").length < prec) { + s[1] = s[1] || ""; + s[1] += new Array(prec - s[1].length + 1).join("0"); + } + return "¥" + s.join(dec); +} + +// 获取两个时间段内的所有日期/月份 日 传入 YYYY-MM , YYYY-MM (2020-09) (2020-12) 返回 YYYY-MM 数组 +export function getAllDay(start, end) { + let result = []; + let min = new Date(start); + let max = new Date(end); + let curr = min; + do { + let month = new Date(curr).getMonth() + 1; + let t = ""; + if (month < 10) { + t = "0" + month; + } else t = month; + let str = curr.getFullYear() + "-" + t; + result.push(str); + if (month == 12) { + curr.setFullYear(new Date(curr).getFullYear() + 1); + curr.setMonth(0); + } else curr.setMonth(month); + } while (curr <= max); + + return result; +} + +// 日期格式化 +export function parseTime(time, pattern) { + if (arguments.length === 0 || !time) { + return null; + } + const format = pattern || "{y}-{m}-{d} {h}:{i}:{s}"; + let date; + if (typeof time === "object") { + date = time; + } else { + if (typeof time === "string" && /^[0-9]+$/.test(time)) { + time = parseInt(time); + } else if (typeof time === "string") { + time = time + .replace(new RegExp(/-/gm), "/") + .replace("T", " ") + .replace(new RegExp(/\.[\d]{3}/gm), ""); + } + if (typeof time === "number" && time.toString().length === 10) { + time = time * 1000; + } + date = new Date(time); + } + const formatObj = { + y: date.getFullYear(), + m: date.getMonth() + 1, + d: date.getDate(), + h: date.getHours(), + i: date.getMinutes(), + s: date.getSeconds(), + a: date.getDay(), + }; + const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { + let value = formatObj[key]; + // Note: getDay() returns 0 on Sunday + if (key === "a") { + return ["日", "一", "二", "三", "四", "五", "六"][value]; + } + if (result.length > 0 && value < 10) { + value = "0" + value; + } + return value || 0; + }); + return time_str; +} + +// 表单重置 +export function resetForm(refName) { + if (this.$refs[refName]) { + this.$refs[refName].resetFields(); + } +} + +// 添加日期范围 +export function addDateRange(params, dateRange, propName) { + let search = params; + search.params = + typeof search.params === "object" && + search.params !== null && + !Array.isArray(search.params) + ? search.params + : {}; + dateRange = Array.isArray(dateRange) ? dateRange : []; + if (typeof propName === "undefined") { + search.params["beginTime"] = dateRange[0]; + search.params["endTime"] = dateRange[1]; + } else { + search.params["begin" + propName] = dateRange[0]; + search.params["end" + propName] = dateRange[1]; + } + return search; +} + +// 回显数据字典 +export function selectDictLabel(datas, value) { + if (value === undefined) { + return ""; + } + var actions = []; + Object.keys(datas).some((key) => { + if (datas[key].value == "" + value) { + actions.push(datas[key].label); + return true; + } + }); + if (actions.length === 0) { + actions.push(value); + } + return actions.join(""); +} + +// 回显数据字典(字符串数组) +export function selectDictLabels(datas, value, separator) { + if (value === undefined || value.length === 0) { + return ""; + } + if (Array.isArray(value)) { + value = value.join(","); + } + var actions = []; + var currentSeparator = undefined === separator ? "," : separator; + var temp = value.split(currentSeparator); + Object.keys(value.split(currentSeparator)).some((val) => { + var match = false; + Object.keys(datas).some((key) => { + if (datas[key].value == "" + temp[val]) { + actions.push(datas[key].label + currentSeparator); + match = true; + } + }); + if (!match) { + actions.push(temp[val] + currentSeparator); + } + }); + return actions.join("").substring(0, actions.join("").length - 1); +} + +// 字符串格式化(%s ) +export function sprintf(str) { + var args = arguments, + flag = true, + i = 1; + str = str.replace(/%s/g, function () { + var arg = args[i++]; + if (typeof arg === "undefined") { + flag = false; + return ""; + } + return arg; + }); + return flag ? str : ""; +} + +// 转换字符串,undefined,null等转化为"" +export function parseStrEmpty(str) { + if (!str || str == "undefined" || str == "null") { + return ""; + } + return str; +} + +// 数据合并 +export function mergeRecursive(source, target) { + for (var p in target) { + try { + if (target[p].constructor == Object) { + source[p] = mergeRecursive(source[p], target[p]); + } else { + source[p] = target[p]; + } + } catch (e) { + source[p] = target[p]; + } + } + return source; +} + +/** + * 构造树型结构数据 + * @param {*} data 数据源 + * @param {*} id id字段 默认 'id' + * @param {*} parentId 父节点字段 默认 'parentId' + * @param {*} children 孩子节点字段 默认 'children' + */ +export function handleTree(data, id, parentId, children) { + let config = { + id: id || "id", + parentId: parentId || "parentId", + childrenList: children || "children", + }; + + var childrenListMap = {}; + var nodeIds = {}; + var tree = []; + + for (let d of data) { + let parentId = d[config.parentId]; + if (childrenListMap[parentId] == null) { + childrenListMap[parentId] = []; + } + nodeIds[d[config.id]] = d; + childrenListMap[parentId].push(d); + } + + for (let d of data) { + let parentId = d[config.parentId]; + if (nodeIds[parentId] == null) { + tree.push(d); + } + } + + for (let t of tree) { + adaptToChildrenList(t); + } + + function adaptToChildrenList(o) { + if (childrenListMap[o[config.id]] !== null) { + o[config.childrenList] = childrenListMap[o[config.id]]; + } + if (o[config.childrenList]) { + for (let c of o[config.childrenList]) { + adaptToChildrenList(c); + } + } + } + return tree; +} + +/** + * 参数处理 + * @param {*} params 参数 + */ +export function tansParams(params) { + let result = ""; + for (const propName of Object.keys(params)) { + const value = params[propName]; + var part = encodeURIComponent(propName) + "="; + if (value !== null && value !== "" && typeof value !== "undefined") { + if (typeof value === "object") { + for (const key of Object.keys(value)) { + if ( + value[key] !== null && + value[key] !== "" && + typeof value[key] !== "undefined" + ) { + let params = propName + "[" + key + "]"; + var subPart = encodeURIComponent(params) + "="; + result += subPart + encodeURIComponent(value[key]) + "&"; + } + } + } else { + result += part + encodeURIComponent(value) + "&"; + } + } + } + return result; +} + +// 返回项目路径 +export function getNormalPath(p) { + if (p.length === 0 || !p || p == "undefined") { + return p; + } + let res = p.replace("//", "/"); + if (res[res.length - 1] === "/") { + return res.slice(0, res.length - 1); + } + return res; +} + +// 验证是否为blob格式 +export function blobValidate(data) { + return data.type !== "application/json"; +} + +// 处理图片格式 +export function disposeImage(primary, type = false) { + if (primary && (primary.length || !Array.isArray(primary))) { + let imgValue = null; + if (Array.isArray(primary)) { + imgValue = []; + primary.forEach((item) => { + if ( + (typeof item == "string" && type) || + (item.url && item.uuid && !type) + ) { + imgValue.push(item); + } else { + if (type) { + if (item.prefix && item.path) { + imgValue.push(item.prefix + item.path); + } else { + imgValue.push(item.url); + } + } else { + imgValue.push({ + name: item.name, + url: item.prefix + item.path, + uuid: item.fileId, + }); + } + } + }); + } else { + if ( + (typeof primary == "string" && type) || + (primary.url && primary.uuid && !type) + ) { + imgValue = primary; + } else { + if (type) { + if (primary.prefix && primary.path) { + imgValue = primary.prefix + primary.path; + } else { + imgValue = primary.url; + } + } else { + imgValue = { + name: primary.name, + url: primary.prefix + primary.path, + uuid: primary.fileId, + }; + } + } + } + return imgValue; + } else { + return []; + } +} + +// 处理图片格式 +export function getImage(primary) { + if (primary && primary.length) { + let imgArr = []; + primary.forEach((item) => { + imgArr.push(item.uuid); + }); + return imgArr.toString(); + } else { + return ""; + } +} + +export function getUrl(url) { + return new Promise((resolve, reject) => { + getFileMessage({ fileId: url }) + .then((res) => { + resolve(disposeImage(res.data)); + }) + .catch((row) => { + ElMessage({ + message: "图片获取错误" + row, + type: "error", + duration: 5 * 1000, + }); + reject(false); + }); + }); +} + +// 获取图片详情 +export async function getImageMessage(url, type = false) { + if (!url || (Array.isArray(url) && !url.length)) { + } else { + let uuidList = null; + if (typeof url == "string" || typeof url == "number") { + uuidList = url.toString().split(","); + } else if (Array.isArray(url)) { + uuidList = url; + } + let imgurl = []; + for (const item in uuidList) { + const url = await getUrl(uuidList[item]); + if (url) { + if (type) { + imgurl.push(url); + } else { + imgurl.push(url.url); + } + } else { + imgurl.push(img); + } + } + return imgurl; + } +} + +// 克隆 +export function deepClone(obj) { + if (obj === null || typeof obj !== "object") { + // 如果 obj 是 null 或不是对象,则直接返回 obj + return obj; + } + + if (Array.isArray(obj)) { + // 如果 obj 是数组 + const clonedArray = []; + for (let i = 0; i < obj.length; i++) { + // 递归克隆数组中的每个元素 + clonedArray[i] = deepClone(obj[i]); + } + return clonedArray; + } + + // 如果 obj 是普通对象 + const clonedObj = {}; + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + // 递归克隆对象的每个属性 + clonedObj[key] = deepClone(obj[key]); + } + } + return clonedObj; +} + +// 数组去重 +export function removeDuplicate(arr) { + const newArr = []; + arr.forEach((item) => { + if (newArr.indexOf(item) === -1) { + newArr.push(item); + } + }); + return newArr; // 返回一个新数组 +} diff --git a/src/utils/tools.js b/src/utils/tools.js new file mode 100644 index 0000000..a492d92 --- /dev/null +++ b/src/utils/tools.js @@ -0,0 +1,160 @@ +// 获取uuid +export function generateUUID() { + var d = new Date().getTime(); + var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now() * 1000)) || 0; + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = Math.random() * 16; + if (d > 0) { + r = (d + r) % 16 | 0; + d = Math.floor(d / 16); + } else { + r = (d2 + r) % 16 | 0; + d2 = Math.floor(d2 / 16); + } + return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); + }); +} + +/** + * 过滤掉可信度(confidence)小于0.6的数据项 + * @param {Array} data - 要过滤的数组,数组项应包含confidence属性 + * @returns {Array} 过滤后的新数组 + */ +export function filteConfidence(data) { + // 检查输入是否为数组 + if (!Array.isArray(data)) { + console.warn('filteConfidence: 输入参数不是数组'); + return []; + } + + // 过滤并返回新数组 + return data.filter(item => { + return item && typeof item === 'object' && + 'confidence' in item && + Number(item.confidence) >= 0.6; + }); +} + +/** + * 根据检测结果截取图片中的多个区域 + * @param {HTMLImageElement|String} image - 图片元素或图片URL + * @param {Array} detectionResults - 检测结果数组,包含box坐标 + * @param {Object} options - 可选配置 + * @param {Number} options.minConfidence - 最小置信度阈值,默认0.5 + * @param {String} options.outputFormat - 输出格式,默认'image/png' + * @param {Number} options.outputQuality - 输出质量(0-1),默认0.92 + * @returns {Promise>} 返回截取图片和相关数据的数组 + */ +export async function cropDetectedRegions(image, detectionResults, options = {}) { + // 合并默认配置 + const { + minConfidence = 0.6, + outputFormat = 'image/png', + outputQuality = 0.92 + } = options; + + // 如果传入的是URL字符串,先加载图片 + const img = typeof image === 'string' + ? await loadImage(image) + : image; + + // 创建画布 + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + + // 存储所有截取结果 + const croppedResults = []; + + // 遍历所有检测结果 + for (const result of detectionResults) { + // 检查置信度是否达标 + if (result.confidence < minConfidence) { + console.log(`跳过置信度低于阈值(${minConfidence})的检测结果:`, result); + continue; + } + + const { x1, y1, x2, y2 } = result.box; + const width = x2 - x1; + const height = y2 - y1; + + // 检查坐标是否有效 + if (!isValidBox(x1, y1, x2, y2, img.width, img.height)) { + console.warn('无效的坐标区域:', result.box); + continue; + } + + // 设置画布尺寸 + canvas.width = width; + canvas.height = height; + + // 清空画布 + ctx.clearRect(0, 0, width, height); + + // 绘制截取区域 + ctx.drawImage( + img, + x1, y1, // 源图像裁剪起始坐标 + width, height, // 源图像裁剪宽高 + 0, 0, // 画布起始坐标 + width, height // 画布绘制宽高 + ); + + // 将画布内容转为Blob对象 + const blob = await new Promise((resolve) => { + canvas.toBlob( + (blob) => resolve(blob), + outputFormat, + outputQuality + ); + }); + + // 保存结果及相关数据 + croppedResults.push({ + blob, + data: { + ...result, + cropInfo: { + x: x1, + y: y1, + width, + height + } + } + }); + } + + return croppedResults; +} + +/** + * 加载图片 + * @param {String} url - 图片URL + * @returns {Promise} + */ +export function loadImage(url) { + return new Promise((resolve, reject) => { + const img = new Image(); + img.crossOrigin = 'Anonymous'; // 处理跨域问题 + img.onload = () => resolve(img); + img.onerror = reject; + img.src = url; + }); +} + +/** + * 检查坐标框是否有效 + * @param {Number} x1 - 左上角x坐标 + * @param {Number} y1 - 左上角y坐标 + * @param {Number} x2 - 右下角x坐标 + * @param {Number} y2 - 右下角y坐标 + * @param {Number} imgWidth - 图片宽度 + * @param {Number} imgHeight - 图片高度 + * @returns {Boolean} + */ +function isValidBox(x1, y1, x2, y2, imgWidth, imgHeight) { + return ( + x1 >= 0 && y1 >= 0 && + x2 > x1 && y2 > y1 && + x2 <= imgWidth && y2 <= imgHeight + ); +} \ No newline at end of file diff --git a/src/utils/whiteboardSync.js b/src/utils/whiteboardSync.js new file mode 100644 index 0000000..590df84 --- /dev/null +++ b/src/utils/whiteboardSync.js @@ -0,0 +1,98 @@ +import { mqttClient } from "./mqtt"; +import { getWhiteboardShapes, getWhiteboardHistory } from "@/views/custom/api"; +import { useMeterStore } from '@/stores/modules/meter'; + +const meterStore = useMeterStore(); +meterStore.initUdid(); + +let isRemote = false; +let canvasInstance = null; + +// 获取本地缓存 userData +function getLocalUserData() { + const dataStr = localStorage.getItem('userData'); + if (!dataStr) return null; + try { + return JSON.parse(dataStr); + } catch (e) { + console.error("解析 userData 失败:", e); + return null; + } +} + +export const WhiteboardSync = { + async init(canvas, roomUid) { + if (!canvas || !roomUid) return; + console.log('初始化多人同步:', roomUid); + canvasInstance = canvas; + + const localUser = getLocalUserData(); + const localUid = localUser?.user?.uid; + + try { + // 先连接 MQTT + await mqttClient.connect(meterStore.getSudid()); + console.log("✅ MQTT 已连接"); + + // 获取历史数据 + const res = await getWhiteboardHistory({ after_timestamp: 0 }, roomUid); + if (res.meta.code === 200 && res.data.shapes.length > 0) { + canvasInstance.addShape(res.data.shapes); + } + + // 订阅当前房间 + const topic = `xSynergy/ROOM/${roomUid}/whiteboard/#`; + mqttClient.subscribe(topic, async (shapeData) => { + try { + isRemote = true; + // 如果 shape 来自本地用户,则跳过 + if (shapeData.user_uid === localUid) return; + const res = await getWhiteboardHistory({ after_timestamp: shapeData.created_at }, roomUid); + if (res.meta.code === 200) { + canvasInstance.addShape(res.data.shapes); + } else { + console.error("获取历史数据失败"); + } + } catch (e) { + console.error("处理MQTT数据失败:", e); + } finally { + isRemote = false; + } + }); + + console.log("✅ 已订阅:", topic); + } catch (err) { + console.log("初始化多人同步失败:",err) + // console.error("❌ 连接或订阅失败:", err); + } + + // 监听画布事件:新增图形 + canvas.on('drawingEnd', async (shape) => { + // 如果来自远程,或不是需要同步的类型,跳过 + if (isRemote || !['pencil', 'line', 'rectangle', 'circle', 'eraser'].includes(shape.type)) return; + + // 如果是本地用户自己的 shape,则不调用接口 + if (shape.user_uid && shape.user_uid === localUid) return; + + shape.room_uid = roomUid; + + try { + await getWhiteboardShapes(shape, roomUid); + } catch (err) { + console.error("提交形状失败:", err); + } + }); + + // 监听画布事件:清空 + canvas.on('clear', async () => { + if (!isRemote) { + try { + // TODO: 调用接口,后端再发 MQTT + // await clearWhiteboard(roomUid); + } catch (err) { + console.error("提交清空失败:", err); + } + } + }); + }, +}; diff --git a/src/views/custom/api/index.js b/src/views/custom/api/index.js new file mode 100644 index 0000000..3000959 --- /dev/null +++ b/src/views/custom/api/index.js @@ -0,0 +1,28 @@ +import request from "@/utils/request.js"; + +// 上传绘制数据 +export const getWhiteboardShapes = (data, room_uid) => { + return request({ + url: `/api/v1/whiteboard/rooms/${room_uid}/shapes`, + method: "put", + data: data + }); +}; + +// 获取以往绘制数据 +export const getWhiteboardHistory = (data, room_uid) => { + return request({ + url: `/api/v1/whiteboard/rooms/${room_uid}/history`, + method: "get", + params: data + }); +}; + +//获取用户信息 +// export const getWhiteboardHistory = (data, room_uid) => { +// return request({ +// url: `/api/v1/user/self`, +// method: "get", +// params: data +// }); +// }; diff --git a/src/views/custom/tabulaRase/index.vue b/src/views/custom/tabulaRase/index.vue new file mode 100644 index 0000000..9f044e3 --- /dev/null +++ b/src/views/custom/tabulaRase/index.vue @@ -0,0 +1,186 @@ + + + + + + \ No newline at end of file diff --git a/src/views/error/401.vue b/src/views/error/401.vue new file mode 100644 index 0000000..a1dc6ef --- /dev/null +++ b/src/views/error/401.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/views/error/404.vue b/src/views/error/404.vue new file mode 100644 index 0000000..f205303 --- /dev/null +++ b/src/views/error/404.vue @@ -0,0 +1,227 @@ + + + + + diff --git a/src/views/login.vue b/src/views/login.vue new file mode 100644 index 0000000..3200bf7 --- /dev/null +++ b/src/views/login.vue @@ -0,0 +1,480 @@ + + + + + diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..72e63d0 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + './index.html', + './src/**/*.{vue,js,ts,jsx,tsx,scss}', + "./src/**/*.html", + ], + theme: { + extend: {}, + }, + plugins: [], +} \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..d389a04 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,38 @@ +import { fileURLToPath, URL } from 'node:url' +import path from "path"; +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import { codeInspectorPlugin } from 'code-inspector-plugin' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + codeInspectorPlugin({ + bundler: 'vite', // 使用 vite + showSwitch: true, + }), + ], + server: { + port: 3000, + open: true, + hmr: { overlay: false }, + proxy: { + '/dev-api': { + target: 'https://xsynergy.gxtech.ltd', // 从环境变量读取 + changeOrigin: true, + ws: true, + rewrite: (path) => + path.replace(new RegExp(`^/dev-api`), '') + } + } + }, + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + }, + }, + css: { + postcss: './postcss.config.js' // 纯外部配置 + }, +})