commit c44fc36fd505c31dc63d221b67d4f37fc6fb92db Author: Juan Felipe Zapata Moreno Date: Mon Nov 10 10:44:28 2025 -0600 Initial commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..2e4ec3a --- /dev/null +++ b/.env.example @@ -0,0 +1,20 @@ +VITE_APP_NAME=GOLSCONTROL +VITE_APP_URL=http://frontend.golscontrol.test +VITE_APP_LANG=es-MX +VITE_APP_PORT=3000 +VITE_PAGINATION=25 + +VITE_APP_API=http://localhost:8080 #Colocar http://localhost:8080 con el puerto del backend / http://backend.golscontrol.test +VITE_APP_API_SECURE=false + +VITE_MICROSERVICE_STOCK=http://localhost:3000/api +VITE_APP_NOTIFICATIONS=false + +VITE_REVERB_APP_ID= +VITE_REVERB_APP_KEY= +VITE_REVERB_APP_SECRET= +VITE_REVERB_HOST="backend.golscontrol.test" +VITE_REVERB_PORT=8080 +VITE_REVERB_SCHEME=http + +APP_PORT=3001 # Puerto para la aplicación frontend \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ef7218 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local +.env +colors.css +notes.md + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a7cea0b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["Vue.volar"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..1511959 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Vue 3 + Vite + +This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 ` + + + \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..96438df --- /dev/null +++ b/install.sh @@ -0,0 +1,13 @@ +#! /bin/bash + +if [ ! -f .env ]; then + cp .env.example .env +fi + +if [ ! -f colors.json ]; then + cp colors.json.example colors.json +fi + +exec "$@" + +echo "Done!" \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6a950ab --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3716 @@ +{ + "name": "notsoweb.frontend", + "version": "0.9.10", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "notsoweb.frontend", + "version": "0.9.10", + "dependencies": { + "@tailwindcss/postcss": "^4.0.9", + "@tailwindcss/vite": "^4.0.9", + "@vitejs/plugin-vue": "^5.2.1", + "axios": "^1.8.1", + "laravel-echo": "^2.0.2", + "luxon": "^3.5.0", + "pinia": "^3.0.1", + "pusher-js": "^8.4.0", + "tailwindcss": "^4.0", + "toastr": "^2.1.4", + "uuid": "^11.1.0", + "vite": "^6.2.0", + "vue": "^3.5.13", + "vue-i18n": "^11.1.1", + "vue-multiselect": "^3.2.0", + "vue-router": "^4.5.0", + "ziggy-js": "^2.5.2" + }, + "devDependencies": { + "autoprefixer": "^10.4.20", + "vite-plugin-html": "^3.2.2" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", + "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", + "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@intlify/core-base": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.1.3.tgz", + "integrity": "sha512-cMuHunYO7LE80azTitcvEbs1KJmtd6g7I5pxlApV3Jo547zdO3h31/0uXpqHc+Y3RKt1wo2y68RGSx77Z1klyA==", + "license": "MIT", + "dependencies": { + "@intlify/message-compiler": "11.1.3", + "@intlify/shared": "11.1.3" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.1.3.tgz", + "integrity": "sha512-7rbqqpo2f5+tIcwZTAG/Ooy9C8NDVwfDkvSeDPWUPQW+Dyzfw2o9H103N5lKBxO7wxX9dgCDjQ8Umz73uYw3hw==", + "license": "MIT", + "dependencies": { + "@intlify/shared": "11.1.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.1.3.tgz", + "integrity": "sha512-pTFBgqa/99JRA2H1qfyqv97MKWJrYngXBA/I0elZcYxvJgcCw3mApAoPW3mJ7vx3j+Ti0FyKUFZ4hWxdjKaxvA==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "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.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "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.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.0.tgz", + "integrity": "sha512-KxN+zCjOYHGwCl4UCtSfZ6jrq/qi88JDUtiEFk8LELEHq2Egfc/FgW+jItZiOLRuQfb/3xJSgFuNPC9jzggX+A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.0.tgz", + "integrity": "sha512-yDvqx3lWlcugozax3DItKJI5j05B0d4Kvnjx+5mwiUpWramVvmAByYigMplaoAQ3pvdprGCTCE03eduqE/8mPQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.0.tgz", + "integrity": "sha512-2KOU574vD3gzcPSjxO0eyR5iWlnxxtmW1F5CkNOHmMlueKNCQkxR6+ekgWyVnz6zaZihpUNkGxjsYrkTJKhkaw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.0.tgz", + "integrity": "sha512-gE5ACNSxHcEZyP2BA9TuTakfZvULEW4YAOtxl/A/YDbIir/wPKukde0BNPlnBiP88ecaN4BJI2TtAd+HKuZPQQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.0.tgz", + "integrity": "sha512-GSxU6r5HnWij7FoSo7cZg3l5GPg4HFLkzsFFh0N/b16q5buW1NAWuCJ+HMtIdUEi6XF0qH+hN0TEd78laRp7Dg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.0.tgz", + "integrity": "sha512-KGiGKGDg8qLRyOWmk6IeiHJzsN/OYxO6nSbT0Vj4MwjS2XQy/5emsmtoqLAabqrohbgLWJ5GV3s/ljdrIr8Qjg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.0.tgz", + "integrity": "sha512-46OzWeqEVQyX3N2/QdiU/CMXYDH/lSHpgfBkuhl3igpZiaB3ZIfSjKuOnybFVBQzjsLwkus2mjaESy8H41SzvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.0.tgz", + "integrity": "sha512-lfgW3KtQP4YauqdPpcUZHPcqQXmTmH4nYU0cplNeW583CMkAGjtImw4PKli09NFi2iQgChk4e9erkwlfYem6Lg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.0.tgz", + "integrity": "sha512-nn8mEyzMbdEJzT7cwxgObuwviMx6kPRxzYiOl6o/o+ChQq23gfdlZcUNnt89lPhhz3BYsZ72rp0rxNqBSfqlqw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.0.tgz", + "integrity": "sha512-l+QK99je2zUKGd31Gh+45c4pGDAqZSuWQiuRFCdHYC2CSiO47qUWsCcenrI6p22hvHZrDje9QjwSMAFL3iwXwQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.0.tgz", + "integrity": "sha512-WbnJaxPv1gPIm6S8O/Wg+wfE/OzGSXlBMbOe4ie+zMyykMOeqmgD1BhPxZQuDqwUN+0T/xOFtL2RUWBspnZj3w==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.0.tgz", + "integrity": "sha512-eRDWR5t67/b2g8Q/S8XPi0YdbKcCs4WQ8vklNnUYLaSWF+Cbv2axZsp4jni6/j7eKvMLYCYdcsv8dcU+a6QNFg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.0.tgz", + "integrity": "sha512-TWrZb6GF5jsEKG7T1IHwlLMDRy2f3DPqYldmIhnA2DVqvvhY2Ai184vZGgahRrg8k9UBWoSlHv+suRfTN7Ua4A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.0.tgz", + "integrity": "sha512-ieQljaZKuJpmWvd8gW87ZmSFwid6AxMDk5bhONJ57U8zT77zpZ/TPKkU9HpnnFrM4zsgr4kiGuzbIbZTGi7u9A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.0.tgz", + "integrity": "sha512-/L3pW48SxrWAlVsKCN0dGLB2bi8Nv8pr5S5ocSM+S0XCn5RCVCXqi8GVtHFsOBBCSeR+u9brV2zno5+mg3S4Aw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.0.tgz", + "integrity": "sha512-XMLeKjyH8NsEDCRptf6LO8lJk23o9wvB+dJwcXMaH6ZQbbkHu2dbGIUindbMtRN6ux1xKi16iXWu6q9mu7gDhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.0.tgz", + "integrity": "sha512-m/P7LycHZTvSQeXhFmgmdqEiTqSV80zn6xHaQ1JSqwCtD1YGtwEK515Qmy9DcB2HK4dOUVypQxvhVSy06cJPEg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.0.tgz", + "integrity": "sha512-4yodtcOrFHpbomJGVEqZ8fzD4kfBeCbpsUy5Pqk4RluXOdsWdjLnjhiKy2w3qzcASWd04fp52Xz7JKarVJ5BTg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.0.tgz", + "integrity": "sha512-tmazCrAsKzdkXssEc65zIE1oC6xPHwfy9d5Ta25SRCDOZS+I6RypVVShWALNuU9bxIfGA0aqrmzlzoM5wO5SPQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.0.tgz", + "integrity": "sha512-h1J+Yzjo/X+0EAvR2kIXJDuTuyT7drc+t2ALY0nIcGPbTatNOf0VWdhEA2Z4AAjv6X1NJV7SYo5oCTYRJhSlVA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT", + "peer": true + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.7.tgz", + "integrity": "sha512-9rsOpdY9idRI2NH6CL4wORFY0+Q6fnx9XP9Ju+iq/0wJwGD5IByIgFmwVbyy4ymuyprj8Qh4ErxMKTUL4uNh3g==", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.7" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.7.tgz", + "integrity": "sha512-5SF95Ctm9DFiUyjUPnDGkoKItPX/k+xifcQhcqX5RA85m50jw1pT/KzjdvlqxRja45Y52nR4MR9fD1JYd7f8NQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.7", + "@tailwindcss/oxide-darwin-arm64": "4.1.7", + "@tailwindcss/oxide-darwin-x64": "4.1.7", + "@tailwindcss/oxide-freebsd-x64": "4.1.7", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.7", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.7", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.7", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.7", + "@tailwindcss/oxide-linux-x64-musl": "4.1.7", + "@tailwindcss/oxide-wasm32-wasi": "4.1.7", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.7", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.7" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.7.tgz", + "integrity": "sha512-IWA410JZ8fF7kACus6BrUwY2Z1t1hm0+ZWNEzykKmMNM09wQooOcN/VXr0p/WJdtHZ90PvJf2AIBS/Ceqx1emg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.7.tgz", + "integrity": "sha512-81jUw9To7fimGGkuJ2W5h3/oGonTOZKZ8C2ghm/TTxbwvfSiFSDPd6/A/KE2N7Jp4mv3Ps9OFqg2fEKgZFfsvg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.7.tgz", + "integrity": "sha512-q77rWjEyGHV4PdDBtrzO0tgBBPlQWKY7wZK0cUok/HaGgbNKecegNxCGikuPJn5wFAlIywC3v+WMBt0PEBtwGw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.7.tgz", + "integrity": "sha512-RfmdbbK6G6ptgF4qqbzoxmH+PKfP4KSVs7SRlTwcbRgBwezJkAO3Qta/7gDy10Q2DcUVkKxFLXUQO6J3CRvBGw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.7.tgz", + "integrity": "sha512-OZqsGvpwOa13lVd1z6JVwQXadEobmesxQ4AxhrwRiPuE04quvZHWn/LnihMg7/XkN+dTioXp/VMu/p6A5eZP3g==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.7.tgz", + "integrity": "sha512-voMvBTnJSfKecJxGkoeAyW/2XRToLZ227LxswLAwKY7YslG/Xkw9/tJNH+3IVh5bdYzYE7DfiaPbRkSHFxY1xA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.7.tgz", + "integrity": "sha512-PjGuNNmJeKHnP58M7XyjJyla8LPo+RmwHQpBI+W/OxqrwojyuCQ+GUtygu7jUqTEexejZHr/z3nBc/gTiXBj4A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.7.tgz", + "integrity": "sha512-HMs+Va+ZR3gC3mLZE00gXxtBo3JoSQxtu9lobbZd+DmfkIxR54NO7Z+UQNPsa0P/ITn1TevtFxXTpsRU7qEvWg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.7.tgz", + "integrity": "sha512-MHZ6jyNlutdHH8rd+YTdr3QbXrHXqwIhHw9e7yXEBcQdluGwhpQY2Eku8UZK6ReLaWtQ4gijIv5QoM5eE+qlsA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.7.tgz", + "integrity": "sha512-ANaSKt74ZRzE2TvJmUcbFQ8zS201cIPxUDm5qez5rLEwWkie2SkGtA4P+GPTj+u8N6JbPrC8MtY8RmJA35Oo+A==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@emnapi/wasi-threads": "^1.0.2", + "@napi-rs/wasm-runtime": "^0.2.9", + "@tybys/wasm-util": "^0.9.0", + "tslib": "^2.8.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.7.tgz", + "integrity": "sha512-HUiSiXQ9gLJBAPCMVRk2RT1ZrBjto7WvqsPBwUrNK2BcdSxMnk19h4pjZjI7zgPhDxlAbJSumTC4ljeA9y0tEw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.7.tgz", + "integrity": "sha512-rYHGmvoHiLJ8hWucSfSOEmdCBIGZIq7SpkPRSqLsH2Ab2YUNgKeAPT1Fi2cx3+hnYOrAb0jp9cRyode3bBW4mQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.7.tgz", + "integrity": "sha512-88g3qmNZn7jDgrrcp3ZXEQfp9CVox7xjP1HN2TFKI03CltPVd/c61ydn5qJJL8FYunn0OqBaW5HNUga0kmPVvw==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.7", + "@tailwindcss/oxide": "4.1.7", + "postcss": "^8.4.41", + "tailwindcss": "4.1.7" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.7.tgz", + "integrity": "sha512-tYa2fO3zDe41I7WqijyVbRd8oWT0aEID1Eokz5hMT6wShLIHj3yvwj9XbfuloHP9glZ6H+aG2AN/+ZrxJ1Y5RQ==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.7", + "@tailwindcss/oxide": "4.1.7", + "tailwindcss": "4.1.7" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6" + } + }, + "node_modules/@types/estree": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "license": "MIT" + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", + "license": "MIT", + "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.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.14.tgz", + "integrity": "sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.2", + "@vue/shared": "3.5.14", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-core/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.14.tgz", + "integrity": "sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.14", + "@vue/shared": "3.5.14" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.14.tgz", + "integrity": "sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.27.2", + "@vue/compiler-core": "3.5.14", + "@vue/compiler-dom": "3.5.14", + "@vue/compiler-ssr": "3.5.14", + "@vue/shared": "3.5.14", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.17", + "postcss": "^8.5.3", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.14.tgz", + "integrity": "sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.14", + "@vue/shared": "3.5.14" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.6.tgz", + "integrity": "sha512-b2Xx0KvXZObePpXPYHvBRRJLDQn5nhKjXh7vUhMEtWxz1AYNFOVIsh5+HLP8xDGL7sy+Q7hXeUxPHB/KgbtsPw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.6" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.6.tgz", + "integrity": "sha512-geu7ds7tem2Y7Wz+WgbnbZ6T5eadOvozHZ23Atk/8tksHMFOFylKi1xgGlQlVn0wlkEf4hu+vd5ctj1G4kFtwA==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.6", + "birpc": "^2.3.0", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.2" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.7.6", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.6.tgz", + "integrity": "sha512-yFEgJZ/WblEsojQQceuyK6FzpFDx4kqrz2ohInxNj5/DnhoX023upTv4OD6lNPLAA5LLkbwPVb10o/7b+Y4FVA==", + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.14.tgz", + "integrity": "sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.14" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.14.tgz", + "integrity": "sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.14", + "@vue/shared": "3.5.14" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.14.tgz", + "integrity": "sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.14", + "@vue/runtime-core": "3.5.14", + "@vue/shared": "3.5.14", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.14.tgz", + "integrity": "sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.14", + "@vue/shared": "3.5.14" + }, + "peerDependencies": { + "vue": "3.5.14" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.14.tgz", + "integrity": "sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "devOptional": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "dev": true, + "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" + } + ], + "license": "MIT", + "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": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/birpc": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.3.0.tgz", + "integrity": "sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz", + "integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==", + "dev": true, + "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" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001716", + "electron-to-chromium": "^1.5.149", + "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-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001718", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz", + "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==", + "dev": true, + "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" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "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/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/clean-css": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", + "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "peer": true, + "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.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dotenv": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-8.0.3.tgz", + "integrity": "sha512-SErOMvge0ZUyWd5B0NXMQlDkN+8r+HhVUsxgOO7IoPDOdDRD2JjExpN6y3KnFR66jsJMwSn1pqIivhU5rcJiNg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.157", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.157.tgz", + "integrity": "sha512-/0ybgsQd1muo8QlnuTpKwtl0oX5YMlUGbm8xyqgDU00motRkKFFbUJySAQBWcY79rVqNLWIWa87BGVGClwAB2w==", + "dev": true, + "license": "ISC" + }, + "node_modules/engine.io-client": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.3.tgz", + "integrity": "sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==", + "license": "MIT", + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "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.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "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/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "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.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "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.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "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.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "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.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/laravel-echo": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/laravel-echo/-/laravel-echo-2.1.4.tgz", + "integrity": "sha512-+xkI04C7mqPSsp/610i2/6g5wnfnY0BbO4+UvQ55Ryn6H7TPDYloFMg3KF+EfYhtPhHLrTSTbnM/wj8REgMvTw==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "pusher-js": "*", + "socket.io-client": "*" + } + }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/luxon": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz", + "integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "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.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT", + "peer": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-html-parser": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-5.4.2.tgz", + "integrity": "sha512-RaBPP3+51hPne/OolXxcz89iYvQvKOydaqoePpOgXcrOKZhjVIzmpKZz+Hd/RBO2/zN2q6CNJhQzucVz+u3Jyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-select": "^4.2.1", + "he": "1.2.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pathe": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz", + "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinia": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.2.tgz", + "integrity": "sha512-sH2JK3wNY809JOeiiURUR0wehJ9/gd9qFN2Y828jCbxEzKEmEt0pzCXwqiSTfuRsK9vQsOflSdnbdBOGrhtn+g==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^7.7.2" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pusher-js": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-8.4.0.tgz", + "integrity": "sha512-wp3HqIIUc1GRyu1XrP6m2dgyE9MoCsXVsWNlohj0rjSkLf+a0jLvEyVubdg58oMk7bhjBWnFClgp8jfAa6Ak4Q==", + "license": "MIT", + "dependencies": { + "tweetnacl": "^1.0.3" + } + }, + "node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.0.tgz", + "integrity": "sha512-HqMFpUbWlf/tvcxBFNKnJyzc7Lk+XO3FGc3pbNBLqEbOz0gPLRgcrlS3UF4MfUrVlstOaP/q0kM6GVvi+LrLRg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.7" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.41.0", + "@rollup/rollup-android-arm64": "4.41.0", + "@rollup/rollup-darwin-arm64": "4.41.0", + "@rollup/rollup-darwin-x64": "4.41.0", + "@rollup/rollup-freebsd-arm64": "4.41.0", + "@rollup/rollup-freebsd-x64": "4.41.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.41.0", + "@rollup/rollup-linux-arm-musleabihf": "4.41.0", + "@rollup/rollup-linux-arm64-gnu": "4.41.0", + "@rollup/rollup-linux-arm64-musl": "4.41.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.41.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.41.0", + "@rollup/rollup-linux-riscv64-gnu": "4.41.0", + "@rollup/rollup-linux-riscv64-musl": "4.41.0", + "@rollup/rollup-linux-s390x-gnu": "4.41.0", + "@rollup/rollup-linux-x64-gnu": "4.41.0", + "@rollup/rollup-linux-x64-musl": "4.41.0", + "@rollup/rollup-win32-arm64-msvc": "4.41.0", + "@rollup/rollup-win32-ia32-msvc": "4.41.0", + "@rollup/rollup-win32-x64-msvc": "4.41.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/socket.io-client": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.1.tgz", + "integrity": "sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "peer": true, + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "devOptional": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.7.tgz", + "integrity": "sha512-kr1o/ErIdNhTz8uzAYL7TpaUuzKIE6QPQ4qmSdxnoX/lo+5wmUHQA6h3L5yIqEImSRnAAURDirLu/BgiXGPAhg==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/terser": { + "version": "5.39.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz", + "integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==", + "devOptional": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "license": "MIT", + "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.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toastr": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/toastr/-/toastr-2.1.4.tgz", + "integrity": "sha512-LIy77F5n+sz4tefMmFOntcJ6HL0Fv3k1TDnNmFZ0bU/GcvIIfy6eG2v7zQmMiYgaalAiUv75ttFrPn5s0gyqlA==", + "dependencies": { + "jquery": ">=1.12.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "devOptional": true, + "license": "0BSD" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/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" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.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 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-html": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vite-plugin-html/-/vite-plugin-html-3.2.2.tgz", + "integrity": "sha512-vb9C9kcdzcIo/Oc3CLZVS03dL5pDlOFuhGlZYDCJ840BhWl/0nGeZWf3Qy7NlOayscY4Cm/QRgULCQkEZige5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^4.2.0", + "colorette": "^2.0.16", + "connect-history-api-fallback": "^1.6.0", + "consola": "^2.15.3", + "dotenv": "^16.0.0", + "dotenv-expand": "^8.0.2", + "ejs": "^3.1.6", + "fast-glob": "^3.2.11", + "fs-extra": "^10.0.1", + "html-minifier-terser": "^6.1.0", + "node-html-parser": "^5.3.3", + "pathe": "^0.2.0" + }, + "peerDependencies": { + "vite": ">=2.0.0" + } + }, + "node_modules/vue": { + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.14.tgz", + "integrity": "sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.14", + "@vue/compiler-sfc": "3.5.14", + "@vue/runtime-dom": "3.5.14", + "@vue/server-renderer": "3.5.14", + "@vue/shared": "3.5.14" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-i18n": { + "version": "11.1.3", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.1.3.tgz", + "integrity": "sha512-Pcylh9z9S5+CJAqgbRZ3EKxFIBIrtY5YUppU722GIT65+Nukm0TCqiQegZnNLCZkXGthxe0cpqj0AoM51H+6Gw==", + "license": "MIT", + "dependencies": { + "@intlify/core-base": "11.1.3", + "@intlify/shared": "11.1.3", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/vue-i18n/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/vue-multiselect": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-3.2.0.tgz", + "integrity": "sha512-ExI+IPvSbILbtaHrU0CgbBmfbD6yBpIWJKsGLPmuQMC7VWK8Nj1XSAI9eIt3n9/e+LSFYdt8VgfHxeS1O1OeVA==", + "license": "MIT", + "engines": { + "node": ">= 14.18.1", + "npm": ">= 6.14.15" + } + }, + "node_modules/vue-router": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.5.1.tgz", + "integrity": "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "peer": true, + "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/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/ziggy-js": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/ziggy-js/-/ziggy-js-2.5.3.tgz", + "integrity": "sha512-fdlGmRpG6I7yqGicIm6xYXhfbYZHjjb5fPHF5xekK6RLQRgOgLXzEg1R6GUgmF3qPAuKTHhAJ3EUfZ86LyMGeg==", + "license": "MIT", + "dependencies": { + "@types/qs": "^6.9.17", + "qs": "~6.9.7" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..aa208d1 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "notsoweb.frontend", + "copyright": "Notsoweb Software Inc.", + "private": true, + "version": "0.9.10", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "@tailwindcss/postcss": "^4.0.9", + "@tailwindcss/vite": "^4.0.9", + "@vitejs/plugin-vue": "^5.2.1", + "axios": "^1.8.1", + "laravel-echo": "^2.0.2", + "luxon": "^3.5.0", + "pinia": "^3.0.1", + "pusher-js": "^8.4.0", + "tailwindcss": "^4.0", + "toastr": "^2.1.4", + "uuid": "^11.1.0", + "vite": "^6.2.0", + "vue": "^3.5.13", + "vue-i18n": "^11.1.1", + "vue-multiselect": "^3.2.0", + "vue-router": "^4.5.0", + "ziggy-js": "^2.5.2" + }, + "devDependencies": { + "autoprefixer": "^10.4.20", + "vite-plugin-html": "^3.2.2" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..fb05b56 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,5 @@ +export default { + plugins: { + "@tailwindcss/postcss": {}, + }, +} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/vue.svg b/src/assets/vue.svg new file mode 100644 index 0000000..770e9d3 --- /dev/null +++ b/src/assets/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/App.vue b/src/components/App.vue new file mode 100644 index 0000000..2cb333f --- /dev/null +++ b/src/components/App.vue @@ -0,0 +1,23 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/ActionSection.vue b/src/components/Holos/ActionSection.vue new file mode 100644 index 0000000..80ce2ee --- /dev/null +++ b/src/components/Holos/ActionSection.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/Holos/Button/Danger.vue b/src/components/Holos/Button/Danger.vue new file mode 100644 index 0000000..a10f212 --- /dev/null +++ b/src/components/Holos/Button/Danger.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/Holos/Button/Icon.vue b/src/components/Holos/Button/Icon.vue new file mode 100644 index 0000000..4b4ed9a --- /dev/null +++ b/src/components/Holos/Button/Icon.vue @@ -0,0 +1,32 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Button/Primary.vue b/src/components/Holos/Button/Primary.vue new file mode 100644 index 0000000..ffc1fa1 --- /dev/null +++ b/src/components/Holos/Button/Primary.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/Holos/Button/Secondary.vue b/src/components/Holos/Button/Secondary.vue new file mode 100644 index 0000000..a02d599 --- /dev/null +++ b/src/components/Holos/Button/Secondary.vue @@ -0,0 +1,18 @@ + + + diff --git a/src/components/Holos/Card/Indicator.vue b/src/components/Holos/Card/Indicator.vue new file mode 100644 index 0000000..3c0227c --- /dev/null +++ b/src/components/Holos/Card/Indicator.vue @@ -0,0 +1,34 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Card/Simple.vue b/src/components/Holos/Card/Simple.vue new file mode 100644 index 0000000..d427ce5 --- /dev/null +++ b/src/components/Holos/Card/Simple.vue @@ -0,0 +1,19 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Checkbox.vue b/src/components/Holos/Checkbox.vue new file mode 100644 index 0000000..3c9bb12 --- /dev/null +++ b/src/components/Holos/Checkbox.vue @@ -0,0 +1,36 @@ + + + + diff --git a/src/components/Holos/ConfirmsPassword.vue b/src/components/Holos/ConfirmsPassword.vue new file mode 100644 index 0000000..4e90e82 --- /dev/null +++ b/src/components/Holos/ConfirmsPassword.vue @@ -0,0 +1,99 @@ + + + diff --git a/src/components/Holos/DialogModal.vue b/src/components/Holos/DialogModal.vue new file mode 100644 index 0000000..e67dca6 --- /dev/null +++ b/src/components/Holos/DialogModal.vue @@ -0,0 +1,45 @@ + + + diff --git a/src/components/Holos/Dropdown.vue b/src/components/Holos/Dropdown.vue new file mode 100644 index 0000000..a794f48 --- /dev/null +++ b/src/components/Holos/Dropdown.vue @@ -0,0 +1,104 @@ + + + diff --git a/src/components/Holos/DropdownLink.vue b/src/components/Holos/DropdownLink.vue new file mode 100644 index 0000000..5aa3e22 --- /dev/null +++ b/src/components/Holos/DropdownLink.vue @@ -0,0 +1,39 @@ + + + diff --git a/src/components/Holos/Form/Checkbox.vue b/src/components/Holos/Form/Checkbox.vue new file mode 100644 index 0000000..51b4db3 --- /dev/null +++ b/src/components/Holos/Form/Checkbox.vue @@ -0,0 +1,44 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/Elements/Error.vue b/src/components/Holos/Form/Elements/Error.vue new file mode 100644 index 0000000..97cf7c6 --- /dev/null +++ b/src/components/Holos/Form/Elements/Error.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/components/Holos/Form/Elements/Label.vue b/src/components/Holos/Form/Elements/Label.vue new file mode 100644 index 0000000..c03836e --- /dev/null +++ b/src/components/Holos/Form/Elements/Label.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/Holos/Form/Image.vue b/src/components/Holos/Form/Image.vue new file mode 100644 index 0000000..7843df4 --- /dev/null +++ b/src/components/Holos/Form/Image.vue @@ -0,0 +1,107 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/Input.vue b/src/components/Holos/Form/Input.vue new file mode 100644 index 0000000..943de04 --- /dev/null +++ b/src/components/Holos/Form/Input.vue @@ -0,0 +1,88 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/InputWithIcon.vue b/src/components/Holos/Form/InputWithIcon.vue new file mode 100644 index 0000000..94c382a --- /dev/null +++ b/src/components/Holos/Form/InputWithIcon.vue @@ -0,0 +1,88 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/Selectable.vue b/src/components/Holos/Form/Selectable.vue new file mode 100644 index 0000000..68a0a7c --- /dev/null +++ b/src/components/Holos/Form/Selectable.vue @@ -0,0 +1,89 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/SingleFile.vue b/src/components/Holos/Form/SingleFile.vue new file mode 100644 index 0000000..f1aee71 --- /dev/null +++ b/src/components/Holos/Form/SingleFile.vue @@ -0,0 +1,103 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/Switch.vue b/src/components/Holos/Form/Switch.vue new file mode 100644 index 0000000..cb8fad6 --- /dev/null +++ b/src/components/Holos/Form/Switch.vue @@ -0,0 +1,67 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/Textarea.vue b/src/components/Holos/Form/Textarea.vue new file mode 100644 index 0000000..ab02f37 --- /dev/null +++ b/src/components/Holos/Form/Textarea.vue @@ -0,0 +1,80 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Form/Todo/ItemWithForm.vue b/src/components/Holos/Form/Todo/ItemWithForm.vue new file mode 100644 index 0000000..b42664c --- /dev/null +++ b/src/components/Holos/Form/Todo/ItemWithForm.vue @@ -0,0 +1,166 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/FormSection.vue b/src/components/Holos/FormSection.vue new file mode 100644 index 0000000..98892ac --- /dev/null +++ b/src/components/Holos/FormSection.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/components/Holos/Inbox.vue b/src/components/Holos/Inbox.vue new file mode 100755 index 0000000..2d5ef60 --- /dev/null +++ b/src/components/Holos/Inbox.vue @@ -0,0 +1,172 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Inbox/Item.vue b/src/components/Holos/Inbox/Item.vue new file mode 100755 index 0000000..a4d5ea3 --- /dev/null +++ b/src/components/Holos/Inbox/Item.vue @@ -0,0 +1,69 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Inbox/ItemTitle.vue b/src/components/Holos/Inbox/ItemTitle.vue new file mode 100755 index 0000000..bfceb2b --- /dev/null +++ b/src/components/Holos/Inbox/ItemTitle.vue @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/src/components/Holos/Inbox/Menu/Item.vue b/src/components/Holos/Inbox/Menu/Item.vue new file mode 100755 index 0000000..f8850a2 --- /dev/null +++ b/src/components/Holos/Inbox/Menu/Item.vue @@ -0,0 +1,51 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Inbox/Menu/Static.vue b/src/components/Holos/Inbox/Menu/Static.vue new file mode 100755 index 0000000..04cf041 --- /dev/null +++ b/src/components/Holos/Inbox/Menu/Static.vue @@ -0,0 +1,42 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/InputLabel.vue b/src/components/Holos/InputLabel.vue new file mode 100644 index 0000000..9967f17 --- /dev/null +++ b/src/components/Holos/InputLabel.vue @@ -0,0 +1,12 @@ + + + diff --git a/src/components/Holos/Layout/App.vue b/src/components/Holos/Layout/App.vue new file mode 100644 index 0000000..fa9e702 --- /dev/null +++ b/src/components/Holos/Layout/App.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/components/Holos/Layout/Auth.vue b/src/components/Holos/Layout/Auth.vue new file mode 100644 index 0000000..f629431 --- /dev/null +++ b/src/components/Holos/Layout/Auth.vue @@ -0,0 +1,69 @@ + + + diff --git a/src/components/Holos/Layout/TermsLayout.vue b/src/components/Holos/Layout/TermsLayout.vue new file mode 100644 index 0000000..83040d9 --- /dev/null +++ b/src/components/Holos/Layout/TermsLayout.vue @@ -0,0 +1,69 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Logo.vue b/src/components/Holos/Logo.vue new file mode 100644 index 0000000..f6b176c --- /dev/null +++ b/src/components/Holos/Logo.vue @@ -0,0 +1,24 @@ + + \ No newline at end of file diff --git a/src/components/Holos/Modal.vue b/src/components/Holos/Modal.vue new file mode 100644 index 0000000..828cf0b --- /dev/null +++ b/src/components/Holos/Modal.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/components/Holos/Modal/Destroy.vue b/src/components/Holos/Modal/Destroy.vue new file mode 100644 index 0000000..a384edf --- /dev/null +++ b/src/components/Holos/Modal/Destroy.vue @@ -0,0 +1,57 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Modal/Edit.vue b/src/components/Holos/Modal/Edit.vue new file mode 100644 index 0000000..30417b7 --- /dev/null +++ b/src/components/Holos/Modal/Edit.vue @@ -0,0 +1,51 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Modal/Elements/Header.vue b/src/components/Holos/Modal/Elements/Header.vue new file mode 100644 index 0000000..7105ad9 --- /dev/null +++ b/src/components/Holos/Modal/Elements/Header.vue @@ -0,0 +1,21 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Modal/Show.vue b/src/components/Holos/Modal/Show.vue new file mode 100644 index 0000000..c5cd931 --- /dev/null +++ b/src/components/Holos/Modal/Show.vue @@ -0,0 +1,49 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Modal/Template/Destroy.vue b/src/components/Holos/Modal/Template/Destroy.vue new file mode 100644 index 0000000..7645473 --- /dev/null +++ b/src/components/Holos/Modal/Template/Destroy.vue @@ -0,0 +1,53 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/PageHeader.vue b/src/components/Holos/PageHeader.vue new file mode 100644 index 0000000..69df0d2 --- /dev/null +++ b/src/components/Holos/PageHeader.vue @@ -0,0 +1,32 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Paginable.vue b/src/components/Holos/Paginable.vue new file mode 100644 index 0000000..1c71344 --- /dev/null +++ b/src/components/Holos/Paginable.vue @@ -0,0 +1,87 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Searcher.vue b/src/components/Holos/Searcher.vue new file mode 100644 index 0000000..6085ef9 --- /dev/null +++ b/src/components/Holos/Searcher.vue @@ -0,0 +1,82 @@ + + \ No newline at end of file diff --git a/src/components/Holos/SectionBorder.vue b/src/components/Holos/SectionBorder.vue new file mode 100644 index 0000000..baec25d --- /dev/null +++ b/src/components/Holos/SectionBorder.vue @@ -0,0 +1,9 @@ + diff --git a/src/components/Holos/SectionTitle.vue b/src/components/Holos/SectionTitle.vue new file mode 100644 index 0000000..1b0b91e --- /dev/null +++ b/src/components/Holos/SectionTitle.vue @@ -0,0 +1,17 @@ + diff --git a/src/components/Holos/Skeleton/Header.vue b/src/components/Holos/Skeleton/Header.vue new file mode 100644 index 0000000..5dc2abe --- /dev/null +++ b/src/components/Holos/Skeleton/Header.vue @@ -0,0 +1,123 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Skeleton/Sidebar/Left.vue b/src/components/Holos/Skeleton/Sidebar/Left.vue new file mode 100644 index 0000000..3ed0363 --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Left.vue @@ -0,0 +1,60 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Skeleton/Sidebar/Link.vue b/src/components/Holos/Skeleton/Sidebar/Link.vue new file mode 100644 index 0000000..d2c206a --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Link.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/components/Holos/Skeleton/Sidebar/Notification.vue b/src/components/Holos/Skeleton/Sidebar/Notification.vue new file mode 100644 index 0000000..86df13e --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Notification.vue @@ -0,0 +1,93 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Skeleton/Sidebar/Notification/Item.vue b/src/components/Holos/Skeleton/Sidebar/Notification/Item.vue new file mode 100644 index 0000000..8dd316e --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Notification/Item.vue @@ -0,0 +1,79 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Skeleton/Sidebar/Notification/Show.vue b/src/components/Holos/Skeleton/Sidebar/Notification/Show.vue new file mode 100644 index 0000000..0ae1e34 --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Notification/Show.vue @@ -0,0 +1,74 @@ + + \ No newline at end of file diff --git a/src/components/Holos/Skeleton/Sidebar/Right.vue b/src/components/Holos/Skeleton/Sidebar/Right.vue new file mode 100644 index 0000000..8187374 --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Right.vue @@ -0,0 +1,36 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Skeleton/Sidebar/Section.vue b/src/components/Holos/Skeleton/Sidebar/Section.vue new file mode 100644 index 0000000..7a6cc53 --- /dev/null +++ b/src/components/Holos/Skeleton/Sidebar/Section.vue @@ -0,0 +1,19 @@ + + + diff --git a/src/components/Holos/Table.vue b/src/components/Holos/Table.vue new file mode 100644 index 0000000..435bbe3 --- /dev/null +++ b/src/components/Holos/Table.vue @@ -0,0 +1,106 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/TableSimple.vue b/src/components/Holos/TableSimple.vue new file mode 100644 index 0000000..1c9f92b --- /dev/null +++ b/src/components/Holos/TableSimple.vue @@ -0,0 +1,33 @@ + + + \ No newline at end of file diff --git a/src/components/Holos/Timeline/Item.vue b/src/components/Holos/Timeline/Item.vue new file mode 100644 index 0000000..b6df0f6 --- /dev/null +++ b/src/components/Holos/Timeline/Item.vue @@ -0,0 +1,94 @@ + + + \ No newline at end of file diff --git a/src/components/Shared/GoogleIcon.vue b/src/components/Shared/GoogleIcon.vue new file mode 100644 index 0000000..df9093e --- /dev/null +++ b/src/components/Shared/GoogleIcon.vue @@ -0,0 +1,30 @@ + + + \ No newline at end of file diff --git a/src/components/Shared/Loader.vue b/src/components/Shared/Loader.vue new file mode 100644 index 0000000..1ab8724 --- /dev/null +++ b/src/components/Shared/Loader.vue @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..24a1e61 --- /dev/null +++ b/src/config.js @@ -0,0 +1,11 @@ +import config from '../package.json' + +const APP_COPYRIGHT = config.copyright +const APP_NAME = import.meta.env.VITE_APP_NAME +const APP_VERSION = config.version + +export { + APP_NAME, + APP_VERSION, + APP_COPYRIGHT +} \ No newline at end of file diff --git a/src/controllers/DateController.js b/src/controllers/DateController.js new file mode 100644 index 0000000..02f96f2 --- /dev/null +++ b/src/controllers/DateController.js @@ -0,0 +1,34 @@ +import { DateTime } from "luxon"; + +// Obtener fecha en formato deseado +function getDate(value = null) { + const date = (value) + ? DateTime.fromISO(value) + : DateTime.now(); + + return date.toLocaleString(DateTime.DATE_MED); +} + +// Obtener hora en formato deseado +function getTime(value = null) { + const date = (value) + ? DateTime.fromISO(value) + : DateTime.now(); + + return date.toLocaleString(DateTime.TIME_24_SIMPLE); +} + +// Obtener fecha y hora +function getDateTime(value) { + const date = (value) + ? DateTime.fromISO(value) + : DateTime.now(); + + return date.toLocaleString(DateTime.DATETIME_SHORT); +} + +export { + getDate, + getDateTime, + getTime +} \ No newline at end of file diff --git a/src/controllers/InboxController.js b/src/controllers/InboxController.js new file mode 100644 index 0000000..3b24549 --- /dev/null +++ b/src/controllers/InboxController.js @@ -0,0 +1,102 @@ +import { ref } from 'vue'; + +/** + * Controlador simple de las bandejas + */ +class InboxController +{ + inboxIdSelected = ref([]); + inboxNumberSelected = ref([]); + selectAll = ref(false); + + constructor() {} + + /** + * Selecciona todas las opciones visibles + */ + onSelectAll = (elements) => { + this.inboxIdSelected.value = []; + this.inboxNumberSelected.value = []; + + this.selectAll.value = !this.selectAll.value; + + if(this.selectAll.value) { + elements.data.forEach(element => { + this.inboxIdSelected.value.push(element.id); + this.inboxNumberSelected.value.push(element.number); + }); + } + } + + /** + * Selecciona solo una opcion + */ + onSelectOne = (invoice) => { + this.inboxIdSelected.value.push(invoice.id); + this.inboxNumberSelected.value.push(invoice.number); + } + + /** + * Permite que siempresea solo una opcion seleccionada + */ + onlyOne = (invoice) => { + this.clear(); + this.onSelectOne(invoice); + } + + /** + * Quita la seleccion + */ + onUnselectOne = (invoice) => { + this.inboxIdSelected.value = this.inboxIdSelected.value.filter(element => { + return element !== invoice.id; + }); + + this.inboxNumberSelected.value = this.inboxNumberSelected.value.filter(element => { + return element !== invoice.number; + }); + } + + /** + * Retorna todos los IDs de los elementos seleccionados + */ + getIdSelections = () => { + return this.inboxIdSelected.value; + } + + /** + * Trata al ID como si fueran muchos + * + * Si no se pasa mimgun ID, se devolveran todos los elementos seleccionados almacenados + */ + getAsMany = (id) => { + return (id) ? [ id ] : this.getIdSelections(); + } + + /** + * Retorna todos los numeros de las facturas/seleccionadas + */ + getNumberSelections = () => { + return this.inboxNumberSelected.value; + } + + /** + * Limpia los valores seleccionados + */ + clear = () => { + this.inboxIdSelected.value = []; + this.inboxNumberSelected.value = []; + this.selectAll.value = false; + } + + /** + * Limpia los valores seleccionados con una notificacion de exito + */ + clearWithSuccess = (message) => { + this.clear(); + + Notify.success(message); + } +} + +export default InboxController; \ No newline at end of file diff --git a/src/controllers/ModalController.js b/src/controllers/ModalController.js new file mode 100644 index 0000000..501c060 --- /dev/null +++ b/src/controllers/ModalController.js @@ -0,0 +1,92 @@ +import { ref } from 'vue'; + +/** + * Controlador simple de las bandejas + */ +class ModalController +{ + // Modals + confirmModal = ref(false); + destroyModal = ref(false); + editModal = ref(false); + noteModal = ref(false); + manyNotesModal = ref(false); + showModal = ref(false); + importModal = ref(false); + + // Models + modelModal = ref({}); + + constructor() {} + + /** + * Controla el cambio entre show y edit + */ + switchShowEditModal = () => { + this.showModal.value = !this.showModal.value + this.editModal.value = !this.editModal.value + }; + + /** + * Controla el switch de eliminar + */ + switchShowModal = (model) => { + this._setModel(model); + this.showModal.value = !this.showModal.value + }; + + /** + * Controla el switch de importar + */ + switchImportModal = () => { + this.importModal.value = !this.importModal.value + }; + + /** + * Controla el switch de eliminar + */ + switchEditModal = (model) => { + this._setModel(model); + this.editModal.value = !this.editModal.value + }; + + /** + * Controla el switch de eliminar + */ + switchDestroyModal = (model) => { + this._setModel(model); + this.destroyModal.value = !this.destroyModal.value + }; + + /** + * Controla el switch de nota + */ + switchNoteModal = () => { + this.noteModal.value = !this.noteModal.value + }; + + /** + * Controla el switch de notas aplicadas a muchos + */ + switchManyNotesModal = () => { + this.manyNotesModal.value = !this.manyNotesModal.value + }; + + /** + * Controla el switch de nota + */ + switchConfirmModal = () => { + this.confirmModal.value = !this.confirmModal.value + }; + + /** + * Guarda el modelo + */ + _setModel = (model) => { + if(model) { + this.modelModal.value = model; + } + } +} + +export default ModalController; \ No newline at end of file diff --git a/src/controllers/PrintController.js b/src/controllers/PrintController.js new file mode 100755 index 0000000..e88739b --- /dev/null +++ b/src/controllers/PrintController.js @@ -0,0 +1,51 @@ +import { ref } from 'vue'; + +/** + * Controla la generación de impresiones + */ +class PrintController +{ + invoices = ref(false); + + constructor({route, meta, params = {}, name = "Comprobante", type='pdf'}) { + this.route = route; + this.meta = meta; + this.params = params; + this.name = name; + this.type = type; + } + + /** + * Manda la orden de impresión y descarga + */ + + download = (data = {}) => { + Notify.info('Generando archivo, espere ...'); + + axios({ + url: route(this.route, this.params), + method: 'POST', + data: { + meta: this.meta, + data: data + }, + responseType: 'blob' + }).then((response) => { + const href = URL.createObjectURL(response.data); + + const link = document.createElement('a'); + link.href = href; + link.setAttribute('download', `${this.name}.${this.type}`); + document.body.appendChild(link); + link.click(); + + document.body.removeChild(link); + URL.revokeObjectURL(href); + Notify.info('Archivo generado'); + }).catch(err => { + Notify.error('Error al generar'); + }); + } +} + +export default PrintController; \ No newline at end of file diff --git a/src/css/app.css b/src/css/app.css new file mode 100644 index 0000000..b4f9467 --- /dev/null +++ b/src/css/app.css @@ -0,0 +1,87 @@ +@import "tailwindcss"; +@import "../../colors.css"; +@custom-variant dark (&:where(.dark, .dark *)); + +@theme { + --font-google-icon-outlined: "Material Symbols Outlined"; + --font-google-icon-outlined-fill: "Material Symbols Outlined Fill"; + --font-google-icon-rounded: "Material Symbols Rounded"; + --font-google-icon-rounded-fill: "Material Symbols rounded-sm Fill"; + --font-google-icon-sharp: "Material Symbols Sharp"; + --font-google-icon-sharp-fill: "Material Symbols Sharp Fill"; +} + +.app-bg-light { + @apply bg-primary +} + +.app-bg-dark { + @apply bg-primary-d +} + +.btn { + @apply inline-flex justify-center items-center w-fit px-1.5 py-1.5 rounded-sm font-medium border border-transparent text-xs text-white uppercase tracking-widest hover:opacity-90 focus:outline-hidden active:saturate-150 disabled:opacity-25 cursor-pointer transition; +} + +.btn-primary { + @apply bg-primary dark:bg-primary-d text-primary-t dark:text-primary-dt hover:bg-secondary dark:hover:bg-secondary-d hover:text-secondary-t dark:hover:text-secondary-dt; +} + +.btn-secondary { + @apply bg-secondary dark:bg-secondary-d text-secondary-t dark:text-secondary-dt hover:bg-secondary dark:hover:bg-secondary-d hover:text-secondary-t dark:hover:text-secondary-dt; +} + +.btn-success { + @apply bg-success dark:bg-success-d text-success-t dark:text-success-dt hover:bg-success dark:hover:bg-success hover:text-success-t dark:hover:text-success-dt; +} + +.btn-danger { + @apply bg-danger dark:bg-danger-d text-danger-t dark:text-danger-dt hover:bg-danger dark:hover:bg-danger hover:text-danger-t dark:hover:text-danger-dt; +} + +.btn-warning { + @apply bg-warning dark:bg-warning-d text-warning-t dark:text-warning-dt hover:bg-warning dark:hover:bg-warning hover:text-warning-t dark:hover:text-warning-dt; +} + +.btn-icon { + @apply flex w-fit min-h-6 px-1.5 py-1.5 rounded-sm font-medium bg-primary dark:bg-primary-d text-primary-t dark:text-primary-dt hover:bg-secondary dark:hover:bg-secondary-d hover:text-secondary-t dark:hover:text-secondary-dt cursor-pointer; +} + +.input-primary { + @apply w-full p-[6.5px] border-b border-page-t/50 dark:border-page-dt/50 bg-primary/5 rounded-sm outline-0 +} + +.nav-item { + @apply p-1 +} + +.table-row { + @apply hover:bg-secondary/10 dark:hover:bg-secondary-d/10 transition-colors duration-100 +} + +.table-cell { + @apply px-2 py-0.5 text-sm border border-primary/30 dark:border-primary-dt/30; +} + +.table-actions { + @apply flex justify-center items-center space-x-1; +} + +nav a.router-link-active { + @apply bg-secondary/30 dark:bg-secondary-d/30 border-secondary dark:border-secondary-d +} + +.with-transition { + @apply transition-all duration-300 +} + +/** + * Switch + */ +.toggle-checkbox:checked { + @apply right-0 border-slate-500 +} + +.toggle-checkbox:checked + .toggle-label { + @apply bg-slate-500 +} \ No newline at end of file diff --git a/src/css/base.css b/src/css/base.css new file mode 100644 index 0000000..f2c8fdd --- /dev/null +++ b/src/css/base.css @@ -0,0 +1,5 @@ +@import './app.css'; +@import './icons.css'; +@import './notifications.css'; +@import "vue-multiselect/dist/vue-multiselect.css"; +@import './multiselect.css'; \ No newline at end of file diff --git a/src/css/icons.css b/src/css/icons.css new file mode 100644 index 0000000..e673e8f --- /dev/null +++ b/src/css/icons.css @@ -0,0 +1,77 @@ +/* +* Outlined +* +* https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0 +* https://fonts.gstatic.com/s/materialsymbolsoutlined/v170/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 +*/ +@font-face { + font-family: 'Material Symbols Outlined'; + font-style: normal; + font-weight: 400; + src: url(./icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2) format('woff2'); +} + +/** +* Outlined fill +* +* https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,1,0 +* https://fonts.gstatic.com/s/materialsymbolsoutlined/v170/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 +*/ +@font-face { + font-family: 'Material Symbols Outlined Fill'; + font-style: normal; + font-weight: 400; + src: url(./icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2) format('woff2'); +} + +/** +* Rounded +* +* https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0 +* https://fonts.gstatic.com/s/materialsymbolsrounded/v168/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 +*/ +@font-face { + font-family: 'Material Symbols Rounded'; + font-style: normal; + font-weight: 400; + src: url(./icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2) format('woff2'); +} + +/** +* rounded-sm fill +* +* https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,1,0 +* https://fonts.gstatic.com/s/materialsymbolsrounded/v168/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDJ_vb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 +*/ +@font-face { + font-family: 'Material Symbols rounded-sm Fill'; + font-style: normal; + font-weight: 400; + src: url(./icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDJ_vb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2) format('woff2'); +} + +/** +* Sharp +* +* https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@24,400,0,0 +* https://fonts.gstatic.com/s/materialsymbolssharp/v166/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 +*/ +@font-face { + font-family: 'Material Symbols Sharp'; + font-style: normal; + font-weight: 400; + src: url(./icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2) format('woff2'); +} + +/** +* Sharp fill +* +* https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp:opsz,wght,FILL,GRAD@24,400,1,0 +* https://fonts.gstatic.com/s/materialsymbolssharp/v166/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReYU3rHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 +*/ +@font-face { + font-family: 'Material Symbols Sharp Fill'; + font-style: normal; + font-weight: 400; + src: url(./icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReYU3rHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2) format('woff2'); +} diff --git a/src/css/icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReYU3rHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 b/src/css/icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReYU3rHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 new file mode 100644 index 0000000..d4912be Binary files /dev/null and b/src/css/icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReYU3rHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 differ diff --git a/src/css/icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 b/src/css/icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 new file mode 100644 index 0000000..d6f770d Binary files /dev/null and b/src/css/icons/google/gNNBW2J8Roq16WD5tFNRaeLQk6-SHQ_R00k4c2_whPnoY9ruReaU4bHmz74m0ZkGH-VBYe1x0TV6x4yFH8F-H5OdzEL3sVTgJtfbYxOLojCL.woff2 differ diff --git a/src/css/icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 b/src/css/icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 new file mode 100644 index 0000000..5b2397e Binary files /dev/null and b/src/css/icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 differ diff --git a/src/css/icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 b/src/css/icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 new file mode 100644 index 0000000..f46d871 Binary files /dev/null and b/src/css/icons/google/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzazHD_dY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2 differ diff --git a/src/css/icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 b/src/css/icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 new file mode 100644 index 0000000..03d95f1 Binary files /dev/null and b/src/css/icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 differ diff --git a/src/css/icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDJ_vb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 b/src/css/icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDJ_vb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 new file mode 100644 index 0000000..9d8bf82 Binary files /dev/null and b/src/css/icons/google/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDJ_vb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOcbTCVpeRL2w5rwZu2rIelXxc.woff2 differ diff --git a/src/css/multiselect.css b/src/css/multiselect.css new file mode 100644 index 0000000..3a3fcb6 --- /dev/null +++ b/src/css/multiselect.css @@ -0,0 +1,57 @@ +.multiselect { + @apply dark:text-white min-h-8; + } + +.multiselect__input, +.multiselect__single { + @apply bg-white dark:bg-transparent dark:text-white +} + +.multiselect__input::placeholder { + @apply text-gray-300; +} + +.multiselect__tag { + @apply bg-success dark:bg-success-d; +} + +.multiselect__tag-icon::after { + @apply text-gray-300; +} + +.multiselect__tag-icon:focus::after, +.multiselect__tag-icon:hover::after { + @apply text-white; +} + +.multiselect__tags { + @apply bg-primary/5 dark:bg-primary-d/5 min-h-8 border-0 border-b border-page-t/50 dark:border-page-dt/50 pt-1; +} + +.multiselect__option--highlight { + @apply dark:bg-green-900 dark:text-white outline-0; +} + +.multiselect__option--highlight::after { + @apply dark:bg-green-800 dark:text-white; +} + +.multiselect__option--selected.multiselect__option--highlight { + @apply bg-red-500 dark:bg-red-600 text-white; + } + + .multiselect__option--selected.multiselect__option--highlight::after { + @apply bg-red-400 dark:bg-red-500 text-white; + } + +.multiselect__content-wrapper { + @apply bg-page dark:bg-page-d; + } + + + .multiselect--disabled, + .multiselect--disabled .multiselect__select, + .multiselect--disabled .multiselect__current, + .multiselect__option--disabled.multiselect__option--highlight{ + background: none; + } \ No newline at end of file diff --git a/src/css/notifications.css b/src/css/notifications.css new file mode 100644 index 0000000..6f1dd57 --- /dev/null +++ b/src/css/notifications.css @@ -0,0 +1,234 @@ +.toast-title { + font-weight: bold; + } + .toast-message { + -ms-word-wrap: break-word; + word-wrap: break-word; + } + .toast-message a, + .toast-message label { + color: #FFFFFF; + } + .toast-message a:hover { + color: #CCCCCC; + text-decoration: none; + } + .toast-close-button { + position: relative; + right: -0.3em; + top: -0.3em; + float: right; + font-size: 20px; + font-weight: bold; + color: #FFFFFF; + -webkit-text-shadow: 0 1px 0 #ffffff; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.8; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); + filter: alpha(opacity=80); + line-height: 1; + } + .toast-close-button:hover, + .toast-close-button:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); + filter: alpha(opacity=40); + } + .rtl .toast-close-button { + left: -0.3em; + float: left; + right: 0.3em; + } + /*Additional properties for button version + iOS requires the button element instead of an anchor tag. + If you want the anchor version, it requires `href="#"`.*/ + button.toast-close-button { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; + } + .toast-top-center { + top: 0; + right: 0; + width: 100%; + } + .toast-bottom-center { + bottom: 0; + right: 0; + width: 100%; + } + .toast-top-full-width { + top: 0; + right: 0; + width: 100%; + } + .toast-bottom-full-width { + bottom: 0; + right: 0; + width: 100%; + } + .toast-top-left { + top: 12px; + left: 12px; + } + .toast-top-right { + top: 12px; + right: 12px; + } + .toast-bottom-right { + right: 12px; + bottom: 12px; + } + .toast-bottom-left { + bottom: 12px; + left: 12px; + } + #toast-container { + position: fixed; + z-index: 999999; + pointer-events: none; + /*overrides*/ + } + #toast-container * { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + } + #toast-container > div { + position: relative; + pointer-events: auto; + overflow: hidden; + margin: 0 0 6px; + padding: 15px 15px 15px 50px; + width: 300px; + -moz-border-radius: 3px 3px 3px 3px; + -webkit-border-radius: 3px 3px 3px 3px; + border-radius: 3px 3px 3px 3px; + background-position: 15px center; + background-repeat: no-repeat; + -moz-box-shadow: 0 0 12px #999999; + -webkit-box-shadow: 0 0 12px #999999; + box-shadow: 0 0 12px #999999; + color: #FFFFFF; + opacity: 0.8; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80); + filter: alpha(opacity=80); + } + #toast-container > div.rtl { + direction: rtl; + padding: 15px 50px 15px 15px; + background-position: right 15px center; + } + #toast-container > div:hover { + -moz-box-shadow: 0 0 12px #000000; + -webkit-box-shadow: 0 0 12px #000000; + box-shadow: 0 0 12px #000000; + opacity: 1; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); + filter: alpha(opacity=100); + cursor: pointer; + } + #toast-container > .toast-info { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important; + } + #toast-container > .toast-error { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important; + } + #toast-container > .toast-success { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important; + } + #toast-container > .toast-warning { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important; + } + #toast-container.toast-top-center > div, + #toast-container.toast-bottom-center > div { + width: 300px; + margin-left: auto; + margin-right: auto; + } + #toast-container.toast-top-full-width > div, + #toast-container.toast-bottom-full-width > div { + width: 96%; + margin-left: auto; + margin-right: auto; + } + .toast { + background-color: #030303; + } + + .toast-success { + @apply bg-success dark:bg-success-d; + } + + .toast-error { + @apply bg-danger dark:bg-danger-d; + } + + .toast-info { + @apply bg-primary-info dark:bg-primary-info-d; + } + + .toast-warning { + @apply bg-warning dark:bg-warning-d; + } + + .toast-progress { + position: absolute; + left: 0; + bottom: 0; + height: 4px; + background-color: #000000; + opacity: 0.4; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40); + filter: alpha(opacity=40); + } + /*Responsive Design*/ + @media all and (max-width: 240px) { + #toast-container > div { + padding: 8px 8px 8px 50px; + width: 11em; + } + #toast-container > div.rtl { + padding: 8px 50px 8px 8px; + } + #toast-container .toast-close-button { + right: -0.2em; + top: -0.2em; + } + #toast-container .rtl .toast-close-button { + left: -0.2em; + right: 0.2em; + } + } + @media all and (min-width: 241px) and (max-width: 480px) { + #toast-container > div { + padding: 8px 8px 8px 50px; + width: 18em; + } + #toast-container > div.rtl { + padding: 8px 50px 8px 8px; + } + #toast-container .toast-close-button { + right: -0.2em; + top: -0.2em; + } + #toast-container .rtl .toast-close-button { + left: -0.2em; + right: 0.2em; + } + } + @media all and (min-width: 481px) and (max-width: 768px) { + #toast-container > div { + padding: 15px 15px 15px 50px; + width: 25em; + } + #toast-container > div.rtl { + padding: 15px 50px 15px 15px; + } + } + \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..2bef60a --- /dev/null +++ b/src/index.js @@ -0,0 +1,74 @@ +import './css/base.css' + +import axios from 'axios'; +import { createPinia } from 'pinia' +import { createApp } from 'vue' +import { useRoute, ZiggyVue } from 'ziggy-js'; +import { i18n, lang } from '@Lang/i18n.js'; +import router from '@Router/Index' +import Notify from '@Plugins/Notify' +import { bootPermissions, bootRoles } from '@Plugins/RolePermission'; +import TailwindScreen from '@Plugins/TailwindScreen' +import { pagePlugin } from '@Services/Page'; +import { defineApp, reloadApp, view } from '@Services/Page'; +import { apiURL } from '@Services/Api'; + +import App from '@Components/App.vue' +import Error503 from '@Pages/Errors/503.vue' +import { hasToken } from './services/Api'; + +// Configurar axios +axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; + +// Elementos globales +window.axios = axios; +window.Lang = lang; +window.Notify = new Notify(); +window.TwScreen = new TailwindScreen(); + +async function boot() { + let initRoutes = false; + + // Iniciar rutas + try { + const routes = await axios.get(apiURL('resources/routes')); + const appData = await axios.get(apiURL('resources/app')); + + window.Ziggy = routes.data; + defineApp(appData.data); + window.route = useRoute(); + window.view = view; + initRoutes = true; + } catch (error) { + window.Notify.error(window.Lang('server.api.noAvailable')); + } + + if(initRoutes) { + // Iniciar permisos + if(hasToken()) { + await bootPermissions(); + await bootRoles(); + + // Iniciar broadcast + if(import.meta.env.VITE_REVERB_ACTIVE === 'true') { + await import('@Services/Broadcast') + } + } + + reloadApp(); + + createApp(App) + .use(createPinia()) + .use(i18n) + .use(pagePlugin) + .use(router) + .use(ZiggyVue) + .mount('#app'); + } else { + createApp(Error503) + .mount('#app'); + } +} + +// Iniciar aplicación +boot(); diff --git a/src/lang/en.js b/src/lang/en.js new file mode 100644 index 0000000..e29c383 --- /dev/null +++ b/src/lang/en.js @@ -0,0 +1,205 @@ +export default { + '&':'and', + account: { + delete: { + confirm:'Are you sure you want to delete your account? Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.', + description: 'Permanently delete your account.', + onDelete:'Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.', + title:'Delete Account', + }, + email: { + notifySendVerification:'A new verification link has been sent to your email address.', + sendVerification:'Click here to re-send the verification email', + unverify: 'Your email address is unverified.', + }, + manage:'Manage Account', + password: { + description:'Ensure your account is using a long, random password to stay secure.', + new:'New password', + reset:'Reset password', + secure:'This is a secure area of the application. Please confirm your password before continuing.', + update: 'Update Password', + verify:'For your security, please confirm your password to continue.', + }, + profile: { + description:'Update your account\'s profile information and email address.', + title:'Profile Information', + }, + sessions: { + confirm:'Please enter your password to confirm you would like to log out of your other browser sessions across all of your devices.', + description: 'Manage and log out your active sessions on other browsers and devices.', + last:'Last active', + logout:'Log Out Other Browser Sessions', + onLogout:'If necessary, you may log out of all of your other browser sessions across all of your devices. Some of your recent sessions are listed below; however, this list may not be exhaustive. If you feel your account has been compromised, you should also update your password.', + this: 'This device', + title: 'Browser Sessions', + }, + twoFactor: { + codes:{ + regenerate:'Regenerate Recovery Codes', + show:'Show Recovery Codes', + store:'Store these recovery codes in a secure password manager. They can be used to recover access to your account if your two factor authentication device is lost.', + }, + description:'Add additional security to your account using two factor authentication.', + isEnable:'You have enabled two factor authentication.', + isNotEnable:{ + title:'You have not enabled two factor authentication.', + description:'When two factor authentication is enabled, you will be prompted for a secure, random token during authentication. You may retrieve this token from your phone\'s Google Authenticator application.', + }, + key:'Setup Key', + login: { + onAuth: 'Please confirm access to your account by entering the authentication code provided by your authenticator application.', + onRecovery: 'Please confirm access to your account by entering one of your emergency recovery codes.', + }, + onFinish:'Finish enabling two factor authentication.', + qr: { + isConfirmed: 'Two factor authentication is now enabled. Scan the following QR code using your phone\'s authenticator application or enter the setup key.', + onConfirmed: 'To finish enabling two factor authentication, scan the following QR code using your phone\'s authenticator application or enter the setup key and provide the generated OTP code.', + }, + recovery: { + code: 'Recovery code', + useAuth: 'Use an authentication code', + useCode: 'Use a recovery code', + }, + title:'Two Factor Authentication', + }, + }, + actions:'Actions', + auth: { + forgotPassword: { + ask: 'Forgot your password?', + description: 'Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.', + sendLink: 'Email Password Reset Link', + title: 'Forgot Password', + }, + login: 'Log In', + logout: 'Log Out', + register: { + already: 'Already registered?', + me: 'Register me', + }, + remember: 'Remember me', + }, + code:'Code', + cancel:'Cancel', + changelogs: { + title:'Changelogs', + description: 'List of changes made to the system.', + }, + close:"Close", + confirm:'Confirm', + copyright:'All rights reserved.', + contact:'Contact', + description:'Description', + date:'Date', + delete: { + confirm:"By pressing DELETE the record will be permanently deleted and cannot be recovered.", + title:'Deleted', + }, + deleted:'Deleted', + details:'Details', + disable:'Disable', + disabled:'Disable', + done:'Done.', + edit:'Edit', + email:'Email', + enable:'Enable', + endDate:'End date', + event:'Event', + help: { + description:'The following is a list of iconography to understand how the system works.', + home: 'Back to home page.', + title:'Help', + }, + history: { + title:'Stock history', + description:'History of actions performed by users in chronological order.', + }, + home:'Home', + hour:'Hour', + icon:'Icon', + maternal:'Mother\'s last name', + name:'Name', + noRecords:'No records', + notifications: { + deleted:'Notification deleted', + description:'User notifications', + notFound:'Notification not found', + title:'Notifications', + }, + password:'Password', + passwordConfirmation:'Confirm Password', + passwordCurrent:'Current Password', + paternal:'Paternal surname', + phone:'Phone Number', + photo: { + new: 'Select A New Photo', + remove:'Remove Photo', + title:'Photo', + }, + profile:'Profile', + readed:'Readed', + register: { + agree:'I agree to the', + privacy:'Privacy Policy', + signUp:'Sign Up', + terms:'Terms of Service', + }, + role:'Role', + roles:{ + create: { + title: 'Create role', + description: 'These roles will be used to give permissions in the system.', + onSuccess: 'Role successfully created', + onError: 'Error when creating the role', + }, + deleted:'Role deleted', + title: 'Roles', + }, + save:'Save', + saved:'Saved!', + search:'Search', + show: { + all:'Show All', + title:'Show', + }, + startDate:'Start date', + status:'Status', + terms: { + agree:'I agree to the', + privacy:'Privacy Policy', + service:'Terms of Service', + }, + unknown:'Unknown', + update:'Update', + updated:'Updated', + updateFail:'Error while updating', + unreaded:'Unreaded', + user:'User', + users:{ + create:{ + title:'Create user', + description:'Allows you to create new users. Don\'t forget to give them roles so that they can access the desired parts of the system.', + onSuccess:'User created', + onError:'An error occurred while creating the user', + }, + deleted:'User deleted', + notFount:'User not found', + password: { + description:'Allows users\' passwords to be updated', + title:'Update password', + }, + roles: { + description:'Updates user roles, allowing or denying access to certain areas.', + error:{ + min:'Select at least one role' + }, + title:'Roles', + }, + select:'Select a user', + settings:'User setting', + system:'System users', + title:'Users', + }, + version:'Version', +} \ No newline at end of file diff --git a/src/lang/es.js b/src/lang/es.js new file mode 100644 index 0000000..bc0039a --- /dev/null +++ b/src/lang/es.js @@ -0,0 +1,452 @@ +import { success } from "toastr"; + +export default { + '&':'y', + account: { + delete: { + confirm:'¿Está seguro de que quiere eliminar su cuenta? Una vez eliminada su cuenta, todos sus recursos y datos se borrarán permanentemente. Por favor, introduzca su contraseña para confirmar que desea eliminar permanentemente su cuenta.', + description:'Eliminar permanentemente su cuenta.', + onDelete:'Una vez eliminada su cuenta, todos sus recursos y datos se borrarán permanentemente. Antes de eliminar su cuenta, descargue los datos o la información que desee conservar.', + title:'Eliminar cuenta', + }, + email: { + notifySendVerification:'Se ha enviado un nuevo enlace de verificación a su dirección de correo electrónico.', + sendVerification:'Haga clic aquí para volver a enviar el correo electrónico de verificación.', + unverify: 'Su dirección de correo electrónico no está verificada.', + }, + manage:'Administrar cuenta', + password: { + description:'Asegúrese de que su cuenta utiliza una contraseña larga y aleatoria para estar seguro.', + new:'Nueva contraseña', + reset:'Restaurar contraseña', + secure:'Esta es una zona segura de la aplicación. Confirme su contraseña antes de continuar.', + update: 'Actualizar contraseña', + updated:'Contraseña actualizada', + verify:'Por su seguridad, confirme su contraseña para continuar.', + }, + profile: { + description:'Actualice la información del perfil de su cuenta y su dirección de correo electrónico.', + title:'Información del perfil', + updated:'Perfil actualizado', + }, + sessions: { + confirm:'Por favor, introduzca su contraseña para confirmar que desea salir de sus otras sesiones de navegación en todos sus dispositivos.', + description: 'Gestiona y cierra tus sesiones activas en otros navegadores y dispositivos.', + last:'Último activo', + logout:'Cerrar otras sesiones del navegador', + done:'Sesiones cerradas', + onLogout:'Si es necesario, puede cerrar la sesión de todos sus otros navegadores en todos sus dispositivos. A continuación se enumeran algunas de sus sesiones recientes; sin embargo, esta lista puede no ser exhaustiva. Si crees que tu cuenta ha sido comprometida, también deberías actualizar tu contraseña.', + this: 'Dispositivo actual', + title: 'Sesiones del navegador', + }, + twoFactor: { + codes:{ + regenerate:'Regenerar los códigos de recuperación', + show:'Mostrar códigos de recuperación', + store:'Guarde estos códigos de recuperación en un gestor de contraseñas seguro. Pueden utilizarse para recuperar el acceso a su cuenta si se pierde su dispositivo de autenticación de dos factores.', + }, + description:'Añada seguridad adicional a su cuenta mediante la autenticación de dos factores.', + isEnable:'Ha activado la autenticación de dos factores.', + isNotEnable:{ + title:'No ha activado la autenticación de dos factores.', + description:'Cuando la autenticación de dos factores está activada, se le pedirá un token seguro y aleatorio durante la autenticación. Puedes recuperar este token desde la aplicación Google Authenticator de tu teléfono.', + }, + key:'Llave de configuración', + login: { + onAuth: 'Por favor, confirme el acceso a su cuenta introduciendo el código de autentificación proporcionado por su aplicación de autentificación.', + onRecovery: 'Confirme el acceso a su cuenta introduciendo uno de sus códigos de recuperación de emergencia.', + }, + onFinish:'Termina de habilitar la autenticación de dos factores.', + qr: { + isConfirmed: 'La autenticación de dos factores ya está activada. Escanee el siguiente código QR con la aplicación de autenticación de su teléfono o introduzca la clave de configuración.', + onConfirmed: 'Para terminar de habilitar la autenticación de dos factores, escanea el siguiente código QR utilizando la aplicación de autenticación de tu teléfono o introduce la clave de configuración y proporciona el código OTP generado.', + }, + recovery: { + code: 'Código de recuperación', + useAuth: 'Utilizar un código de autentificación', + useCode: 'Utiliza un código de recuperación', + }, + title:'Autenticación de dos factores', + }, + title: 'Cuenta', + }, + actions:'Acciones', + activity:'Actividad', + add: 'Agregar', + admin: { + title: 'Administración', + activity: { + title: 'Historial de acciones', + description: 'Historial de acciones realizadas por los usuarios en orden cronológico.' + } + }, + app: { + theme: { + dark: 'Tema oscuro', + light: 'Tema claro' + } + }, + assistances: { + create: { + title: 'Generar asistencia', + description: 'Genera una instantánea del Head Count actual de los empleados, por planta y por línea de producción.', + }, + title: 'Asistencias', + }, + auth: { + confirmPassword: { + description: 'Esta es una zona segura de la aplicación. Por favor, confirma tu contraseña antes de continuar.', + title: 'Confirmar contraseña', + }, + forgotPassword: { + ask: '¿Olvidaste tu contraseña?', + description: '¿Ha olvidado su contraseña? No hay problema. Sólo tienes que indicarnos tu dirección de correo electrónico y te enviaremos un enlace para restablecer la contraseña que te permitirá elegir una nueva.', + sendLink: 'Enviar enlace de recuperación', + title: 'Contraseña olvidada', + success: 'Se ha enviado un enlace de recuperación a su dirección de correo electrónico.', + error: 'Error al enviar el enlace de recuperación, intente más tarde.', + }, + login: 'Iniciar sesión', + logout: 'Cerrar sesión', + register: { + already: '¿Ya estas registrado?', + me: 'Registrarme', + }, + reset: { + success: 'Contraseña actualizada', + title: 'Restaurar contraseña', + }, + remember: 'Recuerdame', + verifyEmail: { + beforeContinue: 'Antes de continuar, ¿podrías verificar tu correo electrónico haciendo clic en el enlace que acabamos de enviar a ti? Si no recibiste el correo electrónico, estaremos encantados de enviarte otro.', + sendLink: 'Enviar correo de verificación', + title: 'Verificación de correo electrónico', + notifySendVerification: 'Se ha enviado un nuevo enlace de verificación a su dirección de correo electrónico.', + }, + }, + author:'Autor', + code:'Código', + contracted_at: 'Fecha contratación', + cancel:'Cancelar', + changes:'Cambios', + changelogs: { + title:'Historial de cambios', + description: 'Lista de los cambios realizados al sistema.', + }, + clear: 'Limpiar', + close:"Cerrar", + confirm:'Confirmar', + copyright:'Todos los derechos reservados.', + contact:'Contacto', + create: 'Crear', + created: 'Registro creado', + created_at: 'Fecha creación', + crud: { + create: 'Nuevo registro', + edit: 'Editar registro', + destroy: 'Eliminar registro', + show: 'Más detalles', + import: 'Importación' + }, + dashboard: 'Dashboard', + date: 'Fecha', + dates: { + start: 'Fecha Inicial', + end: 'Fecha Final' + }, + days: { + title: 'Día', + monday: 'Lunes', + tuesday: 'Martes', + wednesday: 'Miércoles', + thursday: 'Jueves', + friday: 'Viernes', + saturday: 'Sábado', + sunday: 'Domingo' + }, + delete:{ + confirm: 'Al presionar ELIMINAR el registro se eliminará permanentemente y no podrá recuperarse.', + title: 'Eliminar', + }, + deleted:'Registro eliminado', + description:'Descripción', + details:'Detalles', + disable:'Deshabilitar', + disabled:'Deshabilitado', + done:'Hecho.', + edit:'Editar', + edited:'Registro creado', + email:{ + title:'Correo', + verification:'Verificar correo' + }, + employees: { + create: { + title: 'Crear empleado', + }, + edit: { + title: 'Editar empleado', + }, + title: 'Empleados' + }, + enable:'Habilitar', + enabled:'Habilitado', + endDate:'Fecha Fin', + event:'Evento', + files: { + excel: 'Archivo excel', + select: 'Seleccionar archivo' + }, + help: { + description:'A continuación se lista la iconografía para entender el funcionamiento del sistema.', + home: 'Volver a la pagina de inicio.', + title:'Ayuda', + }, + history: { + title:'Historial de acciones', + description:'Historial de acciones realizadas por los usuarios en orden cronológico.' + }, + home:'Inicio', + hour:'Hora', + icon:'Icono', + import: 'Importar', + items: 'Elementos', + maternal:'Apellido materno', + message:'Mensaje', + menu:'Menú', + name:'Nombre', + noRecords:'Sin registros', + notification:'Notificación', + notifications: { + unreadClosed:'Ocultas', + readed:'Marcar como leído', + deleted:'Notificación eliminada', + description:'Notificaciones del usuario', + notFound:'Notificación no encontrada', + title:'Notificaciones', + seeAll:'Ver todas', + }, + omitted:'Omitida', + password:'Contraseña', + passwordConfirmation:'Confirmar contraseña', + passwordCurrent:'Contraseña actual', + passwordReset:'Restaurar contraseña', + paternal:'Apellido paterno', + phone:'Teléfono', + photo: { + new: 'Seleccionar una nueva foto', + remove:'Remover foto', + title:'Foto', + }, + plant: 'Continente', + plants: { + create: { + title: 'Crear continente', + }, + edit: { + title: 'Editar continente', + }, + title: 'Continentes' + }, + 'production-line': 'Línea de producción', + 'production-lines': { + create: { + title: 'Crear línea de producción', + }, + edit: { + title: 'Editar línea de producción', + }, + title: 'Líneas de producción' + }, + profile:'Perfil', + readed:'Leído', + read_at:'Fecha leído', + refresh: 'Recargar', + register: { + create: { + onError: 'Error al crear el registro', + onSuccess: 'Registro creado', + }, + edit: { + onError: 'Error al actualizar el registro', + onSuccess: 'Registro actualizado', + }, + agree:'Estoy de acuerdo con los', + privacy:'Política de Privacidad', + signUp:'Registrarme', + terms:'Términos de Servicio', + }, + registers:{ + title:'Registros', + empty:'Sin registros', + }, + remove: 'Remover', + reports: { + description: 'Listado de reportes del sistema.', + plants: { + title: 'Reporte de empleados por continente', + description: 'Este reporte muestra el número de empleados contratados, por continente y línea de producción en función del tiempo.', + }, + productionLines: { + title: 'Reporte de empleados por línea de producción', + description: 'Este reporte muestra el número de empleados contratados, por línea de producción y continente en función del tiempo.', + }, + title: 'Reportes', + }, + return: 'Regresar', + role:'Rol', + roles:{ + create: { + title: 'Crear rol', + description: 'Este nombre sera necesario para identificar el rol en el sistema. Procura que sea algo simple.', + onSuccess: 'Rol creado exitosamente', + onError: 'Error al crear el role', + }, + deleted:'Rol eliminado', + edit: { + title: 'Editar rol', + onSuccess: 'Rol actualizado exitosamente', + onError: 'Error al actualizar el role', + }, + update: { + description: 'Si crees necesario, puedes actualizar el nombre del rol. No afecta a los permisos.', + }, + title: 'Roles', + description: 'Gestión de roles del sistema. Puedes crear los roles con los permisos que necesites.', + permissions: { + title: 'Permisos', + description: 'Permisos del rol.', + } + }, + save:'Guardar', + saved:'¡Guardado!', + search:'Buscar', + selected: 'Seleccionado', + select: 'Seleccionar', + server: { + api: { + noAvailable: 'No se encontró el servidor API.' + } + }, + session: { + closed: 'Sesión cerrada', + }, + setting: 'Configuración', + settings: { + assistances: { + snapshot: { + title: 'Captura instantánea del Head Count', + description: 'Esta captura genera un resumen del número de empleados contratados, por planta y por línea de producción en un momento específico.', + } + }, + title: 'Ajustes', + }, + sex: 'Género', + shift: 'Turno', + shifts: { + create: { + title: 'Crear turno' + }, + edit: { + title: 'Editar turno' + }, + title: 'Turnos' + }, + show: { + all:'Mostrar todo', + title:'Mostrar', + }, + startDate:'Fecha de inicio', + status:'Estado', + system:{ + title:'Núcleo de Holos', + }, + target: { + title: 'Meta', + total: 'Meta total' + }, + technology: 'Tecnología', + technologies: { + create: { + title: 'Crear tecnología', + }, + edit: { + title: 'Editar tecnología', + }, + title: 'Tecnologías' + }, + terms: { + agree:'Estoy de acuerdo con los', + privacy:'Política de privacidad', + service:'Términos de servicio', + }, + time: { + start: 'Hora inicial', + end: 'Hora final', + }, + title: 'Título', + total: 'Total', + unknown:'Desconocido', + update:'Actualizar', + updated:'Actualizado', + updated_at:'Fecha actualización', + updateFail:'Error al actualizar', + unreaded:'No leído', + user:'Usuario', + users:{ + activity: { + title: 'Actividad del usuario', + description: 'Historial de acciones realizadas por el usuario.', + }, + create:{ + title:'Crear usuario', + description:'Permite crear nuevos usuarios. No olvides otorgarle roles para que pueda acceder a las partes del sistema deseados.', + onSuccess:'Usuario creado', + onError:'Ocurrió un error al crear el usuario' + }, + deleted:'Usuario eliminado', + remove: 'Remover usuario', + edit: { + title: 'Editar usuario' + }, + update: { + description: 'Actualiza los datos del usuario.', + onError: 'Error al actualizar el usuario', + onSuccess: 'Usuario actualizado', + }, + notFount:'Usuario no encontrado', + password: { + description:'Permite actualizar las contraseñas de los usuarios sobre escribiéndola.', + title:'Actualizar contraseña', + }, + roles: { + description:'Actualiza los roles de los usuarios, permitiendo o denegando los accesos a determinadas áreas.', + error:{ + min:'Seleccionar mínimo un role' + }, + title:'Roles de usuario', + }, + online: { + description: 'Lista de usuarios conectados al sistema.', + title: 'Usuarios conectados', + count: 'Usuarios conectados.', + }, + menu:'Menú de usuario', + select:'Seleccionar un usuario', + settings:'Ajustes del usuario', + system:'Usuarios del sistema', + title:'Usuarios', + }, + version:'Versión', + welcome: 'Bienvenido', + workstation: 'Puesto de trabajo', + workstations: { + create: { + title: 'Crear puesto de trabajo', + }, + edit: { + title: 'Editar puesto de trabajo', + }, + title: 'Puestos de trabajos' + }, +} \ No newline at end of file diff --git a/src/lang/i18n.js b/src/lang/i18n.js new file mode 100644 index 0000000..dc03d28 --- /dev/null +++ b/src/lang/i18n.js @@ -0,0 +1,29 @@ +import { createI18n } from 'vue-i18n'; +import en from './en.js'; +import es from './es.js'; + +/** + * Idioma local + */ +const locale = document.documentElement.lang; + +const messages = { + en, + es +} + +const i18n = createI18n({ + legacy: false, + locale, + fallbackLocale: locale, + messages +}); + +function lang(text, params = {}) { + return i18n.global.t(text, params); +} + +export { + i18n, + lang +}; \ No newline at end of file diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue new file mode 100644 index 0000000..d33531b --- /dev/null +++ b/src/layouts/AppLayout.vue @@ -0,0 +1,71 @@ + + + diff --git a/src/pages/Admin/Activities/Index.vue b/src/pages/Admin/Activities/Index.vue new file mode 100644 index 0000000..1670f7a --- /dev/null +++ b/src/pages/Admin/Activities/Index.vue @@ -0,0 +1,151 @@ + + + + \ No newline at end of file diff --git a/src/pages/Admin/Activities/Modals/Event.vue b/src/pages/Admin/Activities/Modals/Event.vue new file mode 100644 index 0000000..feeb1ab --- /dev/null +++ b/src/pages/Admin/Activities/Modals/Event.vue @@ -0,0 +1,59 @@ + + \ No newline at end of file diff --git a/src/pages/Admin/Activities/Module.js b/src/pages/Admin/Activities/Module.js new file mode 100644 index 0000000..3d32a6e --- /dev/null +++ b/src/pages/Admin/Activities/Module.js @@ -0,0 +1,21 @@ +import { lang } from '@Lang/i18n'; +import { hasPermission } from '@Plugins/RolePermission.js'; + +// Ruta API +const apiTo = (name, params = {}) => route(`admin.activities.${name}`, params) + +// Ruta visual +const viewTo = ({ name = '', params = {}, query = {} }) => view({ name: `admin.activities.${name}`, params, query }) + +// Obtener traducción del componente +const transl = (str) => lang(`admin.activity.${str}`) + +// Determina si un usuario puede hacer algo no en base a los permisos +const can = (permission) => hasPermission(`activities.${permission}`) + +export { + can, + viewTo, + apiTo, + transl +} \ No newline at end of file diff --git a/src/pages/Admin/Roles/Create.vue b/src/pages/Admin/Roles/Create.vue new file mode 100644 index 0000000..c2eaed2 --- /dev/null +++ b/src/pages/Admin/Roles/Create.vue @@ -0,0 +1,45 @@ + + + diff --git a/src/pages/Admin/Roles/Edit.vue b/src/pages/Admin/Roles/Edit.vue new file mode 100644 index 0000000..c660f9e --- /dev/null +++ b/src/pages/Admin/Roles/Edit.vue @@ -0,0 +1,54 @@ + + + diff --git a/src/pages/Admin/Roles/Form.vue b/src/pages/Admin/Roles/Form.vue new file mode 100644 index 0000000..93ed745 --- /dev/null +++ b/src/pages/Admin/Roles/Form.vue @@ -0,0 +1,50 @@ + + + \ No newline at end of file diff --git a/src/pages/Admin/Roles/Index.vue b/src/pages/Admin/Roles/Index.vue new file mode 100644 index 0000000..a21334f --- /dev/null +++ b/src/pages/Admin/Roles/Index.vue @@ -0,0 +1,132 @@ + + + + \ No newline at end of file diff --git a/src/pages/Admin/Roles/Modals/Permissions.vue b/src/pages/Admin/Roles/Modals/Permissions.vue new file mode 100644 index 0000000..39764e7 --- /dev/null +++ b/src/pages/Admin/Roles/Modals/Permissions.vue @@ -0,0 +1,79 @@ + + \ No newline at end of file diff --git a/src/pages/Admin/Roles/Module.js b/src/pages/Admin/Roles/Module.js new file mode 100644 index 0000000..284870d --- /dev/null +++ b/src/pages/Admin/Roles/Module.js @@ -0,0 +1,21 @@ +import { lang } from '@Lang/i18n'; +import { hasPermission } from '@Plugins/RolePermission.js'; + +// Ruta API +const apiTo = (name, params = {}) => route(`admin.roles.${name}`, params) + +// Ruta visual +const viewTo = ({ name = '', params = {}, query = {} }) => view({ name: `admin.roles.${name}`, params, query }) + +// Obtener traducción del componente +const transl = (str) => lang(`roles.${str}`) + +// Determina si un usuario puede hacer algo no en base a los permisos +const can = (permission) => hasPermission(`roles.${permission}`) + +export { + can, + viewTo, + apiTo, + transl +} \ No newline at end of file diff --git a/src/pages/Admin/Users/Create.vue b/src/pages/Admin/Users/Create.vue new file mode 100644 index 0000000..f08e1ff --- /dev/null +++ b/src/pages/Admin/Users/Create.vue @@ -0,0 +1,84 @@ + + + diff --git a/src/pages/Admin/Users/Edit.vue b/src/pages/Admin/Users/Edit.vue new file mode 100644 index 0000000..058579a --- /dev/null +++ b/src/pages/Admin/Users/Edit.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/pages/Admin/Users/Form.vue b/src/pages/Admin/Users/Form.vue new file mode 100644 index 0000000..f6990cf --- /dev/null +++ b/src/pages/Admin/Users/Form.vue @@ -0,0 +1,74 @@ + + + \ No newline at end of file diff --git a/src/pages/Admin/Users/Index.vue b/src/pages/Admin/Users/Index.vue new file mode 100644 index 0000000..0101f0c --- /dev/null +++ b/src/pages/Admin/Users/Index.vue @@ -0,0 +1,185 @@ + + + + \ No newline at end of file diff --git a/src/pages/Admin/Users/Modals/Show.vue b/src/pages/Admin/Users/Modals/Show.vue new file mode 100644 index 0000000..483ec1a --- /dev/null +++ b/src/pages/Admin/Users/Modals/Show.vue @@ -0,0 +1,69 @@ + + \ No newline at end of file diff --git a/src/pages/Admin/Users/Module.js b/src/pages/Admin/Users/Module.js new file mode 100644 index 0000000..a4d4824 --- /dev/null +++ b/src/pages/Admin/Users/Module.js @@ -0,0 +1,21 @@ +import { lang } from '@Lang/i18n'; +import { hasPermission } from '@Plugins/RolePermission.js'; + +// Ruta API +const apiTo = (name, params = {}) => route(`admin.users.${name}`, params) + +// Ruta visual +const viewTo = ({ name = '', params = {}, query = {} }) => view({ name: `admin.users.${name}`, params, query }) + +// Obtener traducción del componente +const transl = (str) => lang(`users.${str}`) + +// Determina si un usuario puede hacer algo no en base a los permisos +const can = (permission) => hasPermission(`users.${permission}`) + +export { + can, + viewTo, + apiTo, + transl +} \ No newline at end of file diff --git a/src/pages/Admin/Users/Online.vue b/src/pages/Admin/Users/Online.vue new file mode 100644 index 0000000..48b45e0 --- /dev/null +++ b/src/pages/Admin/Users/Online.vue @@ -0,0 +1,145 @@ + + + + \ No newline at end of file diff --git a/src/pages/Admin/Users/Roles.vue b/src/pages/Admin/Users/Roles.vue new file mode 100644 index 0000000..838bea6 --- /dev/null +++ b/src/pages/Admin/Users/Roles.vue @@ -0,0 +1,73 @@ + + + diff --git a/src/pages/Admin/Users/Settings.vue b/src/pages/Admin/Users/Settings.vue new file mode 100644 index 0000000..d1002ae --- /dev/null +++ b/src/pages/Admin/Users/Settings.vue @@ -0,0 +1,59 @@ + + + + \ No newline at end of file diff --git a/src/pages/Admin/Users/UpdatePassword.vue b/src/pages/Admin/Users/UpdatePassword.vue new file mode 100644 index 0000000..5feac65 --- /dev/null +++ b/src/pages/Admin/Users/UpdatePassword.vue @@ -0,0 +1,69 @@ + + + \ No newline at end of file diff --git a/src/pages/Auth/ConfirmPassword.vue b/src/pages/Auth/ConfirmPassword.vue new file mode 100644 index 0000000..f498197 --- /dev/null +++ b/src/pages/Auth/ConfirmPassword.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/pages/Auth/ForgotPassword.vue b/src/pages/Auth/ForgotPassword.vue new file mode 100644 index 0000000..02e72b1 --- /dev/null +++ b/src/pages/Auth/ForgotPassword.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/pages/Auth/Login.vue b/src/pages/Auth/Login.vue new file mode 100644 index 0000000..6d162dc --- /dev/null +++ b/src/pages/Auth/Login.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/pages/Auth/Module.js b/src/pages/Auth/Module.js new file mode 100644 index 0000000..8c231e1 --- /dev/null +++ b/src/pages/Auth/Module.js @@ -0,0 +1,17 @@ + +import { lang } from '@Lang/i18n'; + +// Ruta API +const apiTo = (name, params = {}) => route(`auth.${name}`, params) + +// Ruta visual +const viewTo = ({ name = '', params = {}, query = {} }) => view({ name: `auth.${name}`, params, query }) + +// Obtener traducción del componente +const transl = (str) => lang(`auth.${str}`) + +export { + viewTo, + apiTo, + transl +} \ No newline at end of file diff --git a/src/pages/Auth/Register.vue b/src/pages/Auth/Register.vue new file mode 100644 index 0000000..c5fbdf2 --- /dev/null +++ b/src/pages/Auth/Register.vue @@ -0,0 +1,123 @@ + + + diff --git a/src/pages/Auth/ResetPassword.vue b/src/pages/Auth/ResetPassword.vue new file mode 100644 index 0000000..c246b88 --- /dev/null +++ b/src/pages/Auth/ResetPassword.vue @@ -0,0 +1,72 @@ + + + diff --git a/src/pages/Auth/TwoFactorChallenge.vue b/src/pages/Auth/TwoFactorChallenge.vue new file mode 100644 index 0000000..132772d --- /dev/null +++ b/src/pages/Auth/TwoFactorChallenge.vue @@ -0,0 +1,100 @@ + + + diff --git a/src/pages/Auth/VerifyEmail.vue b/src/pages/Auth/VerifyEmail.vue new file mode 100644 index 0000000..323f7da --- /dev/null +++ b/src/pages/Auth/VerifyEmail.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/pages/Changelogs/App.vue b/src/pages/Changelogs/App.vue new file mode 100644 index 0000000..6901b67 --- /dev/null +++ b/src/pages/Changelogs/App.vue @@ -0,0 +1,143 @@ + + + \ No newline at end of file diff --git a/src/pages/Changelogs/Core.vue b/src/pages/Changelogs/Core.vue new file mode 100644 index 0000000..8532641 --- /dev/null +++ b/src/pages/Changelogs/Core.vue @@ -0,0 +1,54 @@ + + + \ No newline at end of file diff --git a/src/pages/Dashboard/Index.vue b/src/pages/Dashboard/Index.vue new file mode 100644 index 0000000..1b0dd60 --- /dev/null +++ b/src/pages/Dashboard/Index.vue @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/src/pages/Errors/404.vue b/src/pages/Errors/404.vue new file mode 100644 index 0000000..da6ff89 --- /dev/null +++ b/src/pages/Errors/404.vue @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/src/pages/Errors/502.vue b/src/pages/Errors/502.vue new file mode 100644 index 0000000..f1b8dc8 --- /dev/null +++ b/src/pages/Errors/502.vue @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/src/pages/Errors/503.vue b/src/pages/Errors/503.vue new file mode 100644 index 0000000..b582b0b --- /dev/null +++ b/src/pages/Errors/503.vue @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/src/pages/Examples/Index.vue b/src/pages/Examples/Index.vue new file mode 100644 index 0000000..901f68f --- /dev/null +++ b/src/pages/Examples/Index.vue @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/pages/PrivacyPolicy.vue b/src/pages/PrivacyPolicy.vue new file mode 100644 index 0000000..dce98ba --- /dev/null +++ b/src/pages/PrivacyPolicy.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/pages/Profile/Notifications/Index.vue b/src/pages/Profile/Notifications/Index.vue new file mode 100644 index 0000000..76e0bb6 --- /dev/null +++ b/src/pages/Profile/Notifications/Index.vue @@ -0,0 +1,139 @@ + + + + \ No newline at end of file diff --git a/src/pages/Profile/Notifications/Module.js b/src/pages/Profile/Notifications/Module.js new file mode 100644 index 0000000..86268a9 --- /dev/null +++ b/src/pages/Profile/Notifications/Module.js @@ -0,0 +1,21 @@ +import { lang } from '@Lang/i18n'; +import { hasPermission } from '@Plugins/RolePermission.js'; + +// Ruta API +const apiTo = (name, params = {}) => route(`users.${name}`, params) + +// Ruta visual +const viewTo = ({ name = '', params = {}, query = {} }) => view({ name: `admin.users.${name}`, params, query }) + +// Obtener traducción del componente +const transl = (str) => lang(`users.${str}`) + +// Determina si un usuario puede hacer algo no en base a los permisos +const can = (permission) => hasPermission(`users.${permission}`) + +export { + can, + viewTo, + apiTo, + transl +} \ No newline at end of file diff --git a/src/pages/Profile/Partials/DeleteUserForm.vue b/src/pages/Profile/Partials/DeleteUserForm.vue new file mode 100644 index 0000000..5bb8a84 --- /dev/null +++ b/src/pages/Profile/Partials/DeleteUserForm.vue @@ -0,0 +1,105 @@ + + + diff --git a/src/pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue b/src/pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue new file mode 100644 index 0000000..11e972f --- /dev/null +++ b/src/pages/Profile/Partials/LogoutOtherBrowserSessionsForm.vue @@ -0,0 +1,138 @@ + + + diff --git a/src/pages/Profile/Partials/TwoFactorAuthenticationForm.vue b/src/pages/Profile/Partials/TwoFactorAuthenticationForm.vue new file mode 100644 index 0000000..6eeedeb --- /dev/null +++ b/src/pages/Profile/Partials/TwoFactorAuthenticationForm.vue @@ -0,0 +1,253 @@ + + + diff --git a/src/pages/Profile/Partials/UpdatePasswordForm.vue b/src/pages/Profile/Partials/UpdatePasswordForm.vue new file mode 100644 index 0000000..f763818 --- /dev/null +++ b/src/pages/Profile/Partials/UpdatePasswordForm.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/pages/Profile/Partials/UpdateProfileInformationForm.vue b/src/pages/Profile/Partials/UpdateProfileInformationForm.vue new file mode 100644 index 0000000..dfe9514 --- /dev/null +++ b/src/pages/Profile/Partials/UpdateProfileInformationForm.vue @@ -0,0 +1,192 @@ + + + diff --git a/src/pages/Profile/Show.vue b/src/pages/Profile/Show.vue new file mode 100644 index 0000000..fdaedd3 --- /dev/null +++ b/src/pages/Profile/Show.vue @@ -0,0 +1,38 @@ + + + diff --git a/src/pages/Render.vue b/src/pages/Render.vue new file mode 100644 index 0000000..a0039dd --- /dev/null +++ b/src/pages/Render.vue @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/src/pages/TermsOfService.vue b/src/pages/TermsOfService.vue new file mode 100644 index 0000000..2b7b6c8 --- /dev/null +++ b/src/pages/TermsOfService.vue @@ -0,0 +1,14 @@ + + + diff --git a/src/plugins/AuthUsers.js b/src/plugins/AuthUsers.js new file mode 100644 index 0000000..6aee26e --- /dev/null +++ b/src/plugins/AuthUsers.js @@ -0,0 +1,26 @@ +/** + * Usuarios autenticados + */ + +import { ref } from 'vue'; + +const users = ref([]); + +function boot(x) { + users.value = x; +} + +function addUser(user) { + users.value.push(user); +} + +function removeUser(user) { + users.value = users.value.filter(u => u.id !== user.id); +} + +export { + users, + boot, + addUser, + removeUser +}; \ No newline at end of file diff --git a/src/plugins/Notify.js b/src/plugins/Notify.js new file mode 100644 index 0000000..7e27263 --- /dev/null +++ b/src/plugins/Notify.js @@ -0,0 +1,65 @@ +import toastr from 'toastr'; + +class Notify { + constructor() {} + + flash({message = 'Successful registration', type = 'success', timeout = 5, title= Lang('notification')}) { + + toastr.options = { + "closeButton": true, + "debug": false, + "newestOnTop": false, + "progressBar": true, + "positionClass": "toast-bottom-right", + "preventDuplicates": false, + "onclick": null, + "showDuration": "300", + "hideDuration": "1000", + "timeOut": timeout * 1000, + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": "fadeIn", + "hideMethod": "fadeOut" + } + + toastr[type](message, title); + } + + success(message, title, timeout) { + this.flash({ + message, + title, + timeout + }); + } + + error(message, title, timeout) { + this.flash({ + message, + type:'error', + timeout, + title + }); + } + + info(message, title, timeout) { + this.flash({ + message, + type:'info', + timeout, + title + }); + } + + warning(message, title, timeout) { + this.flash({ + message, + type:'warning', + timeout, + title + }); + } +} + +export default Notify; diff --git a/src/plugins/RolePermission.js b/src/plugins/RolePermission.js new file mode 100644 index 0000000..b1da1ce --- /dev/null +++ b/src/plugins/RolePermission.js @@ -0,0 +1,145 @@ +import { ref } from 'vue'; +import { api } from '@Services/Api'; + +const permissionsInit = ref(false) +const allPermissions = ref([]) +const rolesInit = ref(false) +const allRoles = ref([]) +const allRolesIds = ref([]) + +/** + * Permite consultar si un usuario tiene un permiso especifico + */ +const hasPermission = (can) => { + let verifyPermissions = can.split('|'); + + for (let permision in verifyPermissions) { + if(allPermissions.value.indexOf(verifyPermissions[permision]) != -1) { + return true; + } + } + + return false; +} + +const hasRole = (role) => { + let verifyRoles = role.split('|'); + + for (let role in verifyRoles) { + if(allRoles.value.indexOf(verifyRoles[role]) != -1) { + return true; + } + } + + return false; +} + +const bootPermissions = () => { + return new Promise((resolve, reject) => { + if (!permissionsInit.value) { + api.get(route('user.permissions'), { + onSuccess: (res) => { + loadPermissions(res.permissions) + + resolve(true) + }, + onFinish: () => { + permissionsInit.value = true; + }, + onError: () => { + reject(false) + } + }) + } + }) +} + +const bootRoles = () => { + return new Promise((resolve, reject) => { + if (!rolesInit.value) { + api.get(route('user.roles'), { + onSuccess: (res) => { + loadRoles(res.roles) + + resolve(true) + }, + onFinish: () => { + rolesInit.value = true; + }, + onError: () => { + reject(false) + } + }) + } + }) +} + +const reloadPermissions = () => { + permissionsInit.value = false; + + bootPermissions() +} + +const reloadRoles = () => { + rolesInit.value = false; + + bootRoles() +} + +const resetPermissions = () => { + allPermissions.value = []; + permissionsInit.value = false; +} + +const resetRoles = () => { + allRoles.value = []; + rolesInit.value = false; +} + +const loadPermissions = (permissionList = []) => { + // Permisos cargados + let currentPermissions = []; + + if (permissionList.length > 0) { + permissionList.forEach(element => { + currentPermissions.push(element.name) + }); + } + + allPermissions.value = currentPermissions; +} + +const loadRoles = (roleList = []) => { + if (roleList.length > 0) { + roleList.forEach(element => { + allRoles.value.push(element.name) + allRolesIds.value.push(element.id) + }); + } +} + +const getAllPermissions = () => { + return allPermissions.value; +} + +const getAllRoles = () => { + return allRoles.value; +} + +const getAllRolesIds = () => { + return allRolesIds.value; +} + +export { + bootPermissions, + bootRoles, + hasPermission, + hasRole, + reloadPermissions, + reloadRoles, + resetPermissions, + resetRoles, + getAllPermissions, + getAllRoles, + getAllRolesIds +}; \ No newline at end of file diff --git a/src/plugins/TailwindScreen.js b/src/plugins/TailwindScreen.js new file mode 100644 index 0000000..b53f189 --- /dev/null +++ b/src/plugins/TailwindScreen.js @@ -0,0 +1,104 @@ +/** + * Calcula u obtiene el tamaño de pantalla del dispositivo actual + */ +class TailwindScreen { + constructor(){} + + isXs = () => (screen.width < 640) ? true : false; + + isSm = () => (screen.width >= 640 && screen.width < 768) ? true : false; + + isMd = () => (screen.width >= 768 && screen.width < 1024) ? true : false; + + isLg = () => (screen.width >= 1024 && screen.width < 1280) ? true : false; + + isXl = () => (screen.width >= 1280 && screen.width < 1536) ? true : false; + + is2Xl = () => (screen.width >= 1536) ? true : false; + + /** + * Obtiene el tamaño de pantalla que usa tailwind + */ + getScreen = () => { + if(this.isXs()) { + return 'xs'; + } + + if(this.isSm()) { + return 'sm'; + } + + if(this.isMd()) { + return 'md'; + } + + if(this.isLg()) { + return 'lg'; + } + + if(this.isXl()) { + return 'xl'; + } + + if(this.is2Xl()) { + return '2xl'; + } + } + + /** + * Pregunta si es un tipo de dispositivo + * + * @param {*} device Tipo de dispositivo + */ + isDevice(device) { + switch (device) { + case 'phone': + if(this.isXs() || this.isSm()) { + return true; + } + break; + case 'tablet': + if(this.isMd()) { + return true; + } + break; + case 'pc': + if(this.isLg() || this.isXl() || this.is2Xl()) { + return true; + } + break; + + default: + break; + } + + return false; + } + + /** + * Obtiene el tipo de dispositivo y la variante + */ + getDevice() { + if(this.isXs() || this.isSm()) { + return 'phone'; + } + + if(this.isMd()) { + return 'tablet'; + } + + if(this.isLg()) { + return 'pc-sm'; + } + + if(this.isXl()) { + return 'pc-md'; + } + + if(this.is2Xl()) { + return 'pc-lg'; + } + } +} + +export default TailwindScreen \ No newline at end of file diff --git a/src/router/Examples.js b/src/router/Examples.js new file mode 100644 index 0000000..6ef8581 --- /dev/null +++ b/src/router/Examples.js @@ -0,0 +1,14 @@ +/** + * Archivo de rutas de ejemplos. + * + * En producción se debe eliminar o comentar. Las vistas de ejemplo opcionalmente pueden ser eliminadas o + * dejadas como referencia. + */ + +export default [ + { + path: '/examples', + name: 'examples.index', + component: () => import('@Pages/Examples/Index.vue') + } +] \ No newline at end of file diff --git a/src/router/Index.js b/src/router/Index.js new file mode 100644 index 0000000..5fcdcb2 --- /dev/null +++ b/src/router/Index.js @@ -0,0 +1,168 @@ +import { createRouter, createWebHashHistory } from 'vue-router' +import { hasPermission } from '@Plugins/RolePermission'; + +import examples from './Examples'; + +function can(next, can) { + if (!hasPermission(can)) { + next({ name: '404' }); + } else { + next(); + } +} + +const router = createRouter({ + history: createWebHashHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + component: () => import('@Layouts/AppLayout.vue'), + children: [ + { + path: '', + name: 'index', + redirect: '/dashboard' + }, + { + path: 'dashboard', + name: 'dashboard.index', + component: () => import('@Pages/Dashboard/Index.vue') + }, + { + path: 'profile', + children: [ + { + path: '', + name: 'profile.show', + component: () => import('@Pages/Profile/Show.vue') + }, + { + path: 'notifications', + children: [ + { + path: '', + name: 'profile.notifications.index', + component: () => import('@Pages/Profile/Notifications/Index.vue') + } + ] + }, + ] + }, + ], + }, + { + path: '/admin', + component: () => import('@Layouts/AppLayout.vue'), + children: [ + { + path: 'users', + children: [ + { + path: '', + name: 'admin.users.index', + beforeEnter: (to, from, next) => can(next, 'users.index'), + component: () => import('@Pages/Admin/Users/Index.vue') + }, + { + path: 'online', + name: 'admin.users.online', + beforeEnter: (to, from, next) => can(next, 'users.online'), + component: () => import('@Pages/Admin/Users/Online.vue') + }, + { + path: 'create', + name: 'admin.users.create', + beforeEnter: (to, from, next) => can(next, 'users.create'), + component: () => import('@Pages/Admin/Users/Create.vue') + }, { + path: ':id/edit', + name: 'admin.users.edit', + beforeEnter: (to, from, next) => can(next, 'users.edit'), + component: () => import('@Pages/Admin/Users/Edit.vue') + }, { + path: ':id/settings', + name: 'admin.users.settings', + beforeEnter: (to, from, next) => can(next, 'users.settings'), + component: () => import('@Pages/Admin/Users/Settings.vue') + } + ] + }, + { + path: 'roles', + children: [ + { + path: '', + name: 'admin.roles.index', + component: () => import('@Pages/Admin/Roles/Index.vue') + }, + { + path: 'create', + name: 'admin.roles.create', + component: () => import('@Pages/Admin/Roles/Create.vue') + }, { + path: ':id/edit', + name: 'admin.roles.edit', + component: () => import('@Pages/Admin/Roles/Edit.vue') + } + ] + }, + { + path: 'activities', + children: [ + { + path: '', + name: 'admin.activities.index', + beforeEnter: (to, from, next) => can(next, 'activities.index'), + component: () => import('@Pages/Admin/Activities/Index.vue') + } + ] + } + ] + }, + { + path: '/changelogs', + component: () => import('@Layouts/AppLayout.vue'), + children: [ + { + path: '', + name: 'changelogs.app', + component: () => import('@Pages/Changelogs/App.vue') + }, + { + path: 'core', + name: 'changelogs.core', + component: () => import('@Pages/Changelogs/Core.vue') + } + ] + }, + { + path: '/auth', + component: () => import('@Holos/Layout/Auth.vue'), + children: [ + { + path: '', + name: 'auth.index', + component: () => import('@Pages/Auth/Login.vue') + }, + { + path: 'forgot-password', + name: 'auth.forgot-password', + component: () => import('@Pages/Auth/ForgotPassword.vue') + }, + { + path: 'reset-password', + name: 'auth.reset-password', + component: () => import('@Pages/Auth/ResetPassword.vue') + } + ] + }, + { + path: '/:pathMatch(.*)*', + name: '404', + component: () => import('@Pages/Errors/404.vue') + }, + ...examples, + ] +}) + +export default router diff --git a/src/services/Api.js b/src/services/Api.js new file mode 100644 index 0000000..7b7b74c --- /dev/null +++ b/src/services/Api.js @@ -0,0 +1,584 @@ +/** + * Servicio de comunicación API + * + * @author Moisés Cortés C. + * @version 1.0.0 + */ + +import axios from 'axios'; +import { reactive, ref } from 'vue'; + +axios.defaults.withXSRFToken = true; +axios.defaults.withCredentials = true; + +/** + * Códigos de falla + */ +const failCodes = [ + 400, + 409, + 422 +]; + +/** + * Servidor a utilizar + */ +const token = ref(sessionStorage.token); +const csrfToken = ref(localStorage.csrfToken); + +/** + * Define el token de la api + */ +const defineApiToken = (x) => { + token.value = x; + sessionStorage.token = x; +} + +/** + * Define CSRF token + */ +const defineCsrfToken = (x) => { + csrfToken.value = x; + localStorage.csrfToken = x; +} + +/** + * Define el token de la api + */ +const resetApiToken = () => { + token.value = undefined; + sessionStorage.removeItem('token'); +} + +/** + * Reset CSRF token + */ +const resetCsrfToken = () => { + csrfToken.value = undefined; + localStorage.removeItem('csrfToken'); +} + +/** + * Determina si el token tiene algo o no + */ +const hasToken = () => { + return token.value !== undefined; +} + +/** + * Fuerza el cierre de la sesión + */ +const closeSession = () => { + resetApiToken() + resetCsrfToken() + + Notify.info(Lang('session.closed')) +} + +/** + * Composición de llaves + * + * Utilizado para transformar llaves en FormData + */ +function composeKey(parent, key) { + return parent ? parent + '[' + key + ']' : key +} + +/** + * URL API + */ +const apiURL = (path) => { + return import.meta.env.VITE_API_URL + '/api/' + path +} + +/** + * Instancia de la API de uso directo + */ +const api = { + errors: {}, + hasErrors: false, + processing: false, + wasSuccessful: false, + async load({ + method, + url, + apiToken = token.value, + options = { + data:{}, + params:{} + } + }) { + this.errors = {}; + this.hasErrors = false; + this.processing = true; + this.wasSuccessful = false; + + try { + if(options.hasOwnProperty('onStart')) { + options.onStart(); + } + + let { data } = await axios({ + method: method, + url, + data: options.data, + params: options.params, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': `Bearer ${apiToken}` + } + }); + + if(data.status == 'success') { + this.wasSuccessful = true; + + if(options.hasOwnProperty('onSuccess')) { + options.onSuccess(data.data, data); + } + } else if(data.status == 'fail') { + if(options.hasOwnProperty('onFail')) { + options.onFail(data.data); + } + } + + if(options.hasOwnProperty('onFinish')) { + options.onFinish(data.data); + } + } catch (error) { + console.error(error) + + this.hasErrors = true; + + let { response } = error + + // Código de sesión invalida + if(response.status === 401 && response.data?.message == 'Unauthenticated.') { + Notify.error(Lang('session.expired')); + + closeSession(); + + return + } + + // Fallas + if(failCodes.includes(response.status)) { + options.hasOwnProperty('onFail') + ? options.onFail(response.data.data) + : Notify.warning(response.data.data.message); + + return + } + + if(options.hasOwnProperty('onError')) { + options.onError(response.data); + } + + if(response.data != null) { + this.errors = response.data.errors; + } + } + + this.processing = false; + }, + get(url, options) { + this.load({ + method: 'get', + url, + options + }) + }, + post(url, options) { + this.load({ + method: 'post', + url, + options + }) + }, + put(url, options) { + this.load({ + method: 'put', + url, + options + }) + }, + patch(url, options) { + this.load('patch', { + method: 'patch', + url, + options + }) + }, + delete(url, options) { + this.load({ + method: 'delete', + url, + options + }) + }, + catalog(resources, options) { + this.post(apiURL('catalogs/get'), { + ...options, + data: resources + }) + }, + download(url, file, params = {}) { + axios({ + url: url, + params: params, + method: 'GET', + responseType: 'blob', + headers: { + 'Authorization': `Bearer ${token.value}` + } + }).then((res) => { + const href = URL.createObjectURL(res.data); + const link = document.createElement('a'); + + link.href = href; + link.setAttribute('download', file); + document.body.appendChild(link); + link.click(); + + document.body.removeChild(link); + + URL.revokeObjectURL(href); + }); + }, +} + +/** + * Instancia de la API + */ +const useApi = () => reactive(api); + +/** + * Instancia de la API para formularios + */ +const useForm = (form = {}) => { + // Permite agregar datos mediante una transformación + let transform = (data) => data + + // Contador de archivos + let filesCounter = 0 + + // Procesar elementos del formulario + const append = (formData, key, value) => { + if(Array.isArray(value)) { + return Array.from(value.keys()).forEach((index) => append(formData, composeKey(key, index), value[index])); + } else if(value instanceof Date) { + return formData.append(key, value.toISOString()) + } else if(value instanceof File) { + filesCounter++ + return formData.append(key, value, value.name) + } else if (value instanceof Blob) { + return formData.append(key, value) + } else if(typeof value === 'boolean') { + return formData.append(key, value ? '1' : '0') + } else if (typeof value === 'string') { + return formData.append(key, value) + } else if (typeof value === 'number') { + return formData.append(key, `${value}`) + } else if(value === null || value === undefined) { + return formData.append(key, '') + } else if (typeof value === 'object') { + objectToFormData(formData, key, value); + } + } + + // Convertir objeto a elemento de FormData + const objectToFormData = (formData, parentKey = null, value) => { + value = value || {} + for (const key in value) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + append(formData, composeKey(parentKey, key), value[key]) + } + } + + return formData + } + + // Transforma todos los datos + const prepareData = (data) => { + let formData = new FormData(); + + for (let i in data) { + append(formData, i, data[i]); + } + + return formData; + } + + return reactive({ + ...form, + errors: {}, + hasErrors: false, + processing: false, + wasSuccessful: false, + _inputs: Object.keys(form), + _original: { + ...form + }, + reset() { + for(let i in this._original) { + this[i] = this._original[i] + } + }, + data() { + let data = {}; + + for (let i in this) { + if(typeof this[i] !== 'function' && this._inputs.includes(i)){ + data[i] = this[i] + } + } + + return data; + }, + transform(callback) { + transform = callback + + return this + }, + async load({ + method, + url, + apiToken = token.value, + options = { + data:{}, + params:{} + } + }) { + this.errors = {}; + this.hasErrors = false; + this.processing = true; + this.wasSuccessful = false; + + try { + if(options.hasOwnProperty('onStart')) { + options.onStart(options); + } + + let { data } = await axios({ + method: method, + url, + data: prepareData(transform(this.data())), + headers: { + 'Content-Type': (filesCounter > 0) + ? 'multipart/form-data boundary=' + : 'application/json', + 'Accept': 'application/json', + 'Authorization': `Bearer ${apiToken}`, + 'X-CSRF-TOKEN': csrfToken.value + } + }); + + if(data.status == 'success') { + this.wasSuccessful = true; + + if(options.hasOwnProperty('onSuccess')) { + options.onSuccess(data?.data); + } + } else if(data.status == 'fail') { + if(options.hasOwnProperty('onFail')) { + options.onFail(data?.data); + } + } + + if(options.hasOwnProperty('onFinish')) { + options.onFinish(data?.data); + } + } catch (error) { + console.error(error); + + this.hasErrors = true; + + let { response } = error + + if(options.hasOwnProperty('onError')) { + options.onError(response); + } + + if(response.data?.errors != null) { + this.errors = response.data.errors; + + for(let e in this.errors) { + Notify.error(this.errors[e]) + } + } + } + + this.processing = false; + }, + fill(model) { + this._inputs.forEach(element => { + this[element] = (element == 'is_active') + ? (model[element] == 1) + : model[element] ?? this[element] + }); + }, + get(url, options) { + this.load({ + method: 'get', + url, + options + }) + }, + post(url, options) { + this.load({ + method: 'post', + url, + options + }) + }, + put(url, options) { + this.load({ + method: 'put', + url, + options + }) + }, + patch(url, options) { + this.load('patch', { + method: 'patch', + url, + options + }) + }, + delete(url, options) { + this.load({ + method: 'delete', + url, + options + }) + }, + }) +} + +/** + * Instancia de a API para buscador + */ +const useSearcher = (options = { + url: '', + filters: '' +}) => reactive({ + query: '', + errors: {}, + hasErrors: false, + processing: false, + wasSuccessful: false, + async load({ + url, + apiToken = token.value, + filters, + }) { + this.errors = {}; + this.processing = true; + this.hasErrors = false; + this.wasSuccessful = false; + + try { + if(options.hasOwnProperty('onStart')) { + options.onStart(); + } + + let { data } = await axios({ + method: 'get', + url, + params: { + q: this.query, + ...filters + }, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': `Bearer ${apiToken}` + } + }); + + if(data.status == 'success') { + this.wasSuccessful = true; + + if(options.hasOwnProperty('onSuccess')) { + options.onSuccess(data.data); + } + } else if(data.status == 'fail') { + if(options.hasOwnProperty('onFail')) { + options.onFail(data.data); + } + } + + if(options.hasOwnProperty('onFinish')) { + options.onFinish(data.data); + } + } catch (error) { + console.error(error); + + this.hasErrors = true; + + let { response } = error + + // Código de sesión invalida + if(response.status === 401 && response.data.message == 'Unauthenticated.') { + Notify.error(Lang('session.expired')); + closeSession(); + return + } + + if(options.hasOwnProperty('onError')) { + options.onError(response); + } + + if(response.data?.errors != null) { + this.errors = response.data.errors; + for(let e in this.errors) { + Notify.error(this.errors[e]) + } + } + } + + this.processing = false; + }, + pagination(url, filter = {}) { + this.load({ + url, + filters : { + ...options.filters, + ...filter, + } + }) + }, + search(q = '', filter = {}) { + this.query = q + this.load({ + url: options.url, + filters : { + ...options.filters, + ...filter, + } + }) + }, + refresh(filter = {}) { + this.load({ + url: options.url, + filters : { + ...options.filters, + ...filter, + } + }) + } +}) + +export { + api, + token, + apiURL, + closeSession, + defineCsrfToken, + defineApiToken, + hasToken, + resetApiToken, + useApi, + useForm, + useSearcher +} \ No newline at end of file diff --git a/src/services/Broadcast.js b/src/services/Broadcast.js new file mode 100644 index 0000000..081e921 --- /dev/null +++ b/src/services/Broadcast.js @@ -0,0 +1,40 @@ +import Echo from 'laravel-echo'; +import Pusher from 'pusher-js'; +import { token } from '@Services/Api'; + +window.Pusher = Pusher; + +window.Echo = new Echo({ + broadcaster: 'reverb', + authorizer: (channel, options) => { + return { + authorize: async (socketId, callback) => { + try { + let { data } = await axios({ + method: 'post', + url: import.meta.env.VITE_REVERB_SCHEME + '://' + import.meta.env.VITE_REVERB_HOST + '/broadcasting/auth', + data: { + socket_id: socketId, + channel_name: channel.name, + }, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': `Bearer ${token.value}` + } + }); + + callback(null, data); + } catch (err) { + callback(err); + } + } + }; + }, + key: import.meta.env.VITE_REVERB_APP_KEY, + wsHost: import.meta.env.VITE_REVERB_HOST, + wsPort: import.meta.env.VITE_REVERB_PORT ?? 80, + wssPort: import.meta.env.VITE_REVERB_PORT ?? 443, + forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https', + enabledTransports: ['ws', 'wss'], +}); diff --git a/src/services/Page.js b/src/services/Page.js new file mode 100644 index 0000000..a0ec9ff --- /dev/null +++ b/src/services/Page.js @@ -0,0 +1,130 @@ +import { reactive } from "vue"; +import { api, closeSession } from '@Services/Api'; +import { resetPermissions } from '@Plugins/RolePermission'; + +/** + * Cache + * + * Permite cargar los datos una vez para la sesión actual. Se mantienen mientras + * no se recargue la página. + */ +const page = reactive({ + lang: 'es', + app: {}, + user: { + id: 0, + name: 'public' + } +}) + +/** + * Recarga datos en cache + */ +const reloadApp = () => { + const user = localStorage.user + const app = localStorage.app + + if(user) { + page.user = JSON.parse(user); + } + + if(app) { + page.app = JSON.parse(app); + } +} + +/** + * Limpiar sesión de usuario + */ +const resetPage = () => { + localStorage.removeItem('user'); +} + +/** + * Permite buscar una opcionalmente + */ +const view = ({ + name = '', + params = {}, + query = {}, +}) => ({ + name: name, + params, + query, +}) + +/** + * Almacenar datos usuario + */ +const defineUser = (user) => { + localStorage.user = JSON.stringify({ + id: user.id, + name: user.name, + lastname: `${user.paternal} ${user?.maternal ?? ''}`, + email: user.email, + phone: user.phone, + profile_photo_url: user.profile_photo_url, + profile_photo_path: user.profile_photo_path, + }); +} + +/** + * Definir datos de la aplicación + */ +const defineApp = (app) => { + localStorage.app = JSON.stringify(app); +} + +/** + * Instalar el componente de forma nativa + */ +const pagePlugin = { + install: (app, options) => { + app.config.globalProperties.$page = page; + app.config.globalProperties.$view = view; + } +} + +/** + * Reload user + */ +const reloadUser = () => { + return api.get(route('user.show'), { + onSuccess: (r) => { + defineUser(r.user) + reloadApp() + + return r.user; + } + }); +} + +/** + * Cerrar sesión + */ +const logout = () => { + resetPermissions() + resetPage() + + api.post(route('auth.logout'), { + onSuccess: (r) => { + if(r.is_revoked === true) { + closeSession() + + location.replace('/') + } + } + }); +}; + +export { + pagePlugin, + page, + defineApp, + defineUser, + reloadApp, + reloadUser, + resetPage, + logout, + view +} \ No newline at end of file diff --git a/src/stores/DarkMode.js b/src/stores/DarkMode.js new file mode 100644 index 0000000..7efb6fd --- /dev/null +++ b/src/stores/DarkMode.js @@ -0,0 +1,47 @@ +import { defineStore } from 'pinia' + +// Identificador de la página +const page = document.getElementById('main-page'); + +// Almacén del modo oscuro +const useDarkMode = defineStore('dark-mode', { + state: () => ({ + isActive: true + }), + getters: { + getTheme(state) { + return state.isActive + ? 'dark' + : 'light'; + }, + isDark(state) { + return state.isActive === true; + }, + isLight(state) { + return state.isActive === false; + } + }, + actions: { + boot() { + this.apply((localStorage.darkMode == 'true')); + }, + applyDark() { + this.apply(true); + }, + applyLight() { + this.apply(false); + }, + apply(state) { + this.isActive = state; + localStorage.darkMode = state + + if(state) { + page.classList.add('dark'); + } else { + page.classList.remove('dark'); + } + } + }, +}) + +export default useDarkMode \ No newline at end of file diff --git a/src/stores/LeftSidebar.js b/src/stores/LeftSidebar.js new file mode 100644 index 0000000..298b878 --- /dev/null +++ b/src/stores/LeftSidebar.js @@ -0,0 +1,36 @@ +import { defineStore } from 'pinia' + +// Almacenar estado de la barra lateral derecha +const useLeftSidebar = defineStore('left-sidebar', { + state: () => ({ + isActive: true + }), + getters: { + isOpened(state) { + return state.isActive === true; + }, + isClosed(state) { + return state.isActive === false; + } + }, + actions: { + boot() { + this.apply(localStorage.leftSidebar == 'true'); + }, + open() { + this.apply(true); + }, + close() { + this.apply(false); + }, + toggle() { + this.apply(!this.isActive) + }, + apply(state) { + this.isActive = state + localStorage.leftSidebar = state + } + } +}) + +export default useLeftSidebar \ No newline at end of file diff --git a/src/stores/Loader.js b/src/stores/Loader.js new file mode 100644 index 0000000..dd0c23b --- /dev/null +++ b/src/stores/Loader.js @@ -0,0 +1,35 @@ +import axios from 'axios'; +import { defineStore } from 'pinia' + +// Almacén del modo oscuro +const useLoader = defineStore('loader', { + state: () => ({ + processing: false + }), + getters: { + isProcessing(state) { + return state.processing + } + }, + actions: { + boot() { + axios.interceptors.request.use((config) => { + this.processing = true + return config; + }, (error) => { + this.processing = false + return Promise.reject(error); + }); + + axios.interceptors.response.use((response) => { + this.processing = false + return response; + }, (error) => { + this.processing = false + return Promise.reject(error); + }); + } + }, +}) + +export default useLoader \ No newline at end of file diff --git a/src/stores/NotificationSidebar.js b/src/stores/NotificationSidebar.js new file mode 100644 index 0000000..d9e0bf4 --- /dev/null +++ b/src/stores/NotificationSidebar.js @@ -0,0 +1,33 @@ +import { defineStore } from 'pinia' + +// Almacenar estado de la barra lateral derecha +const useNotificationSidebar = defineStore('notification-sidebar', { + state: () => ({ + isActive: false + }), + getters: { + isOpened(state) { + return state.isActive === true; + }, + isClosed(state) { + return state.isActive === false; + } + }, + actions: { + open() { + this.apply(true); + }, + close() { + this.apply(false); + }, + toggle() { + this.apply(!this.isActive) + }, + apply(state) { + this.isActive = state + localStorage.rightSidebar = state + } + }, +}) + +export default useNotificationSidebar \ No newline at end of file diff --git a/src/stores/Notifications.js b/src/stores/Notifications.js new file mode 100644 index 0000000..92590e4 --- /dev/null +++ b/src/stores/Notifications.js @@ -0,0 +1,53 @@ +import { defineStore } from 'pinia' +import { v4 as uuidv4 } from 'uuid'; + +// Almacenar estado de las notificaciones +const useNotification = defineStore('notifications', { + state: () => ({ + notifications: [], + }), + getters: { + getNotifications(state) { + return state.notifications + } + }, + actions: { + boot() { + let local = localStorage.getItem('notifications') + + if(local) { + this.notifications = JSON.parse(localStorage.getItem('notifications')) + } + }, + add({ + title = '', + message = '', + type = 'info', + preserve = false + }) { + this.notifications.push({ + uuid: uuidv4(), + title, + message, + type, + preserve + }) + + this.save() + }, + delete(uuid) { + this.notifications = this.notifications.filter(x => { + return x.uuid != uuid + }) + + this.save() + }, + save() { + localStorage.setItem('notifications', JSON.stringify(this.notifications.filter(x => { + return x.preserve == true + } ))) + } + }, +}) + +export default useNotification \ No newline at end of file diff --git a/src/stores/Notifier.js b/src/stores/Notifier.js new file mode 100644 index 0000000..09d0cfd --- /dev/null +++ b/src/stores/Notifier.js @@ -0,0 +1,134 @@ +import { defineStore } from 'pinia' +import { api } from '@Services/Api' +import { page } from '@Services/Page' +import { hasPermission, reloadPermissions, getAllRolesIds } from '@Plugins/RolePermission' +import { boot as bootAuthUsers, addUser, removeUser } from '@Plugins/AuthUsers' + +// Almacenar estado de la barra lateral derecha +const useNotifier = defineStore('notifier', { + state: () => ({ + counter: 0, + unreadClosedCounter: 0, + notifications: [], + isStarted: false, + isEnabled: import.meta.env.VITE_REVERB_ACTIVE === 'true', + user_id: 0, + }), + actions: { + // Iniciar instancia + boot() { + if(!this.isStarted && this.isEnabled) { + this.user_id = page.user.id; + + this.subscribeGLobalNotifications(); + this.subscribeUserNotifications(); + this.suscribeAuthUsers(); + this.suscribeRoles(); + this.isStarted = true; + + this.getUpdates(); + } + }, + // Detener instancia + stop() { + if(this.isStarted) { + this.unsubscribeUserNotification(); + this.unsubscribeGlobalNotification(); + + this.started.value = false; + } + }, + // Notificaciones Globales + subscribeGLobalNotifications() { + Echo.private('Global') + .listen('Notification', e => { + Notify[e.type](e.message, e.title, e.timeout) + this.getUpdates() + }); + + }, + unsubscribeGlobalNotifications() { + Echo.leave('Global'); + }, + // Usuarios logueados + suscribeAuthUsers() { + if(hasPermission('users.index')) { + Echo.join('online') + .here((users) => { + bootAuthUsers(users); + }) + .joining((user) => { + addUser(user); + }) + .leaving((user) => { + removeUser(user); + }); + } else { + Echo.join('online'); + } + }, + suscribeRoles() { + const roles = getAllRolesIds(); + + roles.forEach(role => { + Echo.private(`App.Models.Role.${role}`) + .listen('UpdateRoleUser', e => { + reloadPermissions(); + + Notify.success(`Actualizando permisos de ${e.role.description}`) + }); + }); + }, + // Notificaciones del usuario + subscribeUserNotifications() { + Echo.private(`App.Models.User.${this.user_id}`) + .notification(x => { + Notify[x.typeNotification](x.description, x.title, x.timeout) + this.getUpdates() + }) + }, + unsubscribeUserNotification() { + Echo.leave(`App.Models.User.${this.user_id}`); + }, + readNotification(id) { + api.post(route('system.notifications.read'), { + data: { + id + }, + onSuccess: res => { + this.getUpdates(); + }, + onFailed: res => { + this.getUpdates(); + } + }) + }, + closeNotification(id) { + api.post(route('system.notifications.close'), { + data: { + id + }, + onSuccess: res => { + this.getUpdates(); + }, + onFailed: res => { + this.getUpdates(); + } + }) + }, + getUpdates() { + api.get(route('system.notifications.all-unread'), { + onSuccess: res => { + this.counter = res.total; + this.unreadClosedCounter = res.unread_closed; + this.notifications = res.notifications; + }, + onFailed: res => { + console.log('error', res) + } + }) + } + } +}) + +export default useNotifier \ No newline at end of file diff --git a/src/stores/RightSidebar.js b/src/stores/RightSidebar.js new file mode 100644 index 0000000..d205ed4 --- /dev/null +++ b/src/stores/RightSidebar.js @@ -0,0 +1,33 @@ +import { defineStore } from 'pinia' + +// Almacenar estado de la barra lateral derecha +const useRightSidebar = defineStore('right-sidebar', { + state: () => ({ + isActive: false + }), + getters: { + isOpened(state) { + return state.isActive === true; + }, + isClosed(state) { + return state.isActive === false; + } + }, + actions: { + open() { + this.apply(true); + }, + close() { + this.apply(false); + }, + toggle() { + this.apply(!this.isActive) + }, + apply(state) { + this.isActive = state + localStorage.rightSidebar = state + } + }, +}) + +export default useRightSidebar \ No newline at end of file diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..d570e01 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,29 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import tailwindcss from "@tailwindcss/vite"; +import vue from '@vitejs/plugin-vue' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [vue(), tailwindcss()], + server: { + allowedHosts: true, + }, + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)), + '@Components': fileURLToPath(new URL('./src/components', import.meta.url)), + '@Controllers': fileURLToPath(new URL('./src/controllers', import.meta.url)), + '@Holos': fileURLToPath(new URL('./src/components/Holos', import.meta.url)), + '@Layouts': fileURLToPath(new URL('./src/layouts', import.meta.url)), + '@Lang': fileURLToPath(new URL('./src/lang', import.meta.url)), + '@Router': fileURLToPath(new URL('./src/router', import.meta.url)), + '@Pages': fileURLToPath(new URL('./src/pages', import.meta.url)), + '@Plugins': fileURLToPath(new URL('./src/plugins', import.meta.url)), + '@Shared': fileURLToPath(new URL('./src/components/Shared', import.meta.url)), + '@Services': fileURLToPath(new URL('./src/services', import.meta.url)), + '@Stores': fileURLToPath(new URL('./src/stores', import.meta.url)), + } + } +})