step: migrate to vue.js

This commit is contained in:
2026-06-27 14:16:26 +02:00
parent e1a32ecd01
commit 1da5c4fefc
17 changed files with 865 additions and 415 deletions
+7
View File
@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(npm install *)"
]
}
}
+495 -115
View File
@@ -8,11 +8,49 @@
"name": "king-arthur", "name": "king-arthur",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"mqtt": "^5.15.1" "mqtt": "^5.15.1",
"pinia": "^2.1.7",
"vue": "^3.3.12",
"vue-router": "^4.2.5"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"typescript": "~6.0.2", "typescript": "~6.0.2",
"vite": "^8.0.10" "vite": "^8.1.0",
"vue-tsc": "^3.3.5"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
"integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
"integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
"integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
"license": "MIT",
"dependencies": {
"@babel/types": "^7.29.7"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
} }
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
@@ -24,22 +62,35 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@babel/types": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
"integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.29.7",
"@babel/helper-validator-identifier": "^7.29.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@emnapi/core": { "node_modules/@emnapi/core": {
"version": "1.10.0", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz",
"integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"@emnapi/wasi-threads": "1.2.1", "@emnapi/wasi-threads": "1.2.2",
"tslib": "^2.4.0" "tslib": "^2.4.0"
} }
}, },
"node_modules/@emnapi/runtime": { "node_modules/@emnapi/runtime": {
"version": "1.10.0", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
"integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@@ -48,9 +99,9 @@
} }
}, },
"node_modules/@emnapi/wasi-threads": { "node_modules/@emnapi/wasi-threads": {
"version": "1.2.1", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
"integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@@ -58,15 +109,21 @@
"tslib": "^2.4.0" "tslib": "^2.4.0"
} }
}, },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
"node_modules/@napi-rs/wasm-runtime": { "node_modules/@napi-rs/wasm-runtime": {
"version": "1.1.4", "version": "1.1.6",
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
"integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"@tybys/wasm-util": "^0.10.1" "@tybys/wasm-util": "^0.10.3"
}, },
"funding": { "funding": {
"type": "github", "type": "github",
@@ -78,9 +135,9 @@
} }
}, },
"node_modules/@oxc-project/types": { "node_modules/@oxc-project/types": {
"version": "0.128.0", "version": "0.137.0",
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.128.0.tgz", "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.137.0.tgz",
"integrity": "sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ==", "integrity": "sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"funding": { "funding": {
@@ -88,9 +145,9 @@
} }
}, },
"node_modules/@rolldown/binding-android-arm64": { "node_modules/@rolldown/binding-android-arm64": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.3.tgz",
"integrity": "sha512-lIDyUAfD7U3+BWKzdxMbJcsYHuqXqmGz40aeRqvuAm3y5TkJSYTBW2RDrn65DJFPQqVjUAUqq5uz8urzQ8aBdQ==", "integrity": "sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -105,9 +162,9 @@
} }
}, },
"node_modules/@rolldown/binding-darwin-arm64": { "node_modules/@rolldown/binding-darwin-arm64": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.3.tgz",
"integrity": "sha512-apJq2ktnGp27nSInMR5Vcj8kY6xJzDAvfdIFlpDcAK/w4cDO58qVoi1YQsES/SKiFNge/6e4CUzgjfHduYqWpQ==", "integrity": "sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -122,9 +179,9 @@
} }
}, },
"node_modules/@rolldown/binding-darwin-x64": { "node_modules/@rolldown/binding-darwin-x64": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.3.tgz",
"integrity": "sha512-5Ofot8xbs+pxRHJqm9/9N/4sTQOvdrwEsmPE9pdLEEoAbdZtG6F2LMDfO1sp6ZAtXJuJV/21ew2srq3W8NXB5g==", "integrity": "sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -139,9 +196,9 @@
} }
}, },
"node_modules/@rolldown/binding-freebsd-x64": { "node_modules/@rolldown/binding-freebsd-x64": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.3.tgz",
"integrity": "sha512-7h8eeOTT1eyqJyx64BFCnWZpNm486hGWt2sqeLLgDxA0xI1oGZ9H7gK1S85uNGmBhkdPwa/6reTxfFFKvIsebw==", "integrity": "sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -156,9 +213,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-arm-gnueabihf": { "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.3.tgz",
"integrity": "sha512-eRcm/HVt9U/JFu5RKAEKwGQYtDCKWLiaH6wOnsSEp6NMBb/3Os8LgHZlNyzMpFVNmiiMFlfb2zEnebfzJrHFmg==", "integrity": "sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@@ -173,9 +230,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-arm64-gnu": { "node_modules/@rolldown/binding-linux-arm64-gnu": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.3.tgz",
"integrity": "sha512-SOrT/cT4ukTmgnrEz/Hg3m7LBnuCLW9psDeMKrimRWY4I8DmnO7Lco8W2vtqPmMkbVu8iJ+g4GFLVLLOVjJ9DQ==", "integrity": "sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -193,9 +250,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-arm64-musl": { "node_modules/@rolldown/binding-linux-arm64-musl": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.3.tgz",
"integrity": "sha512-QWjdxN1HJCpBTAcZ5N5F7wju3gVPzRzSpmGzx7na0c/1qpN9CFil+xt+l9lV/1M6/gqHSNXCiqPfwhVJPeLnug==", "integrity": "sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -213,9 +270,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-ppc64-gnu": { "node_modules/@rolldown/binding-linux-ppc64-gnu": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.3.tgz",
"integrity": "sha512-ugCOyj7a4d9h3q9B+wXmf6g3a68UsjGh6dob5DHevHGMwDUbhsYNbSPxJsENcIttJZ9jv7qGM2UesLw5jqIhdg==", "integrity": "sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@@ -233,9 +290,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-s390x-gnu": { "node_modules/@rolldown/binding-linux-s390x-gnu": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.3.tgz",
"integrity": "sha512-kKWRhbsotpXkGbcd5dllUWg5gEXcDAa8u5YnP9AV5DYNbvJHGzzuwv7dpmhc8NqKMJldl0a+x76IHbspEpEmdA==", "integrity": "sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@@ -253,9 +310,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-x64-gnu": { "node_modules/@rolldown/binding-linux-x64-gnu": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.3.tgz",
"integrity": "sha512-uCo8ElcCIAMyYAZyuIZ81oFkhTSIllNvUCHCAlbhlN4ji3uC28h7IIdlXyIvGO7HsuqnV9p3rD/bpH7XhIyhRw==", "integrity": "sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -273,9 +330,9 @@
} }
}, },
"node_modules/@rolldown/binding-linux-x64-musl": { "node_modules/@rolldown/binding-linux-x64-musl": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.3.tgz",
"integrity": "sha512-XNOQZtuE6yUIvx4rwGemwh8kpL1xvU41FXy/s9K7T/3JVcqGzo3NfKM2HrbrGgfPYGFW42f07Wk++aOC6B9NWA==", "integrity": "sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -293,9 +350,9 @@
} }
}, },
"node_modules/@rolldown/binding-openharmony-arm64": { "node_modules/@rolldown/binding-openharmony-arm64": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.3.tgz",
"integrity": "sha512-tSn/kzrfa7tNOXr7sEacDBN4YsIqTyLqh45IO0nHDwtpKIDNDJr+VFojt+4klSpChxB29JLyduSsE0MKEwa65A==", "integrity": "sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -310,9 +367,9 @@
} }
}, },
"node_modules/@rolldown/binding-wasm32-wasi": { "node_modules/@rolldown/binding-wasm32-wasi": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.3.tgz",
"integrity": "sha512-+J9YGmc+czgqlhYmwun3S3O0FIZhsH8ep2456xwjAdIOmuJxM7xz4P4PtrxU+Bz17a/5bqPA8o3HAAoX0teUdg==", "integrity": "sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==",
"cpu": [ "cpu": [
"wasm32" "wasm32"
], ],
@@ -320,18 +377,18 @@
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"dependencies": { "dependencies": {
"@emnapi/core": "1.10.0", "@emnapi/core": "1.11.1",
"@emnapi/runtime": "1.10.0", "@emnapi/runtime": "1.11.1",
"@napi-rs/wasm-runtime": "^1.1.4" "@napi-rs/wasm-runtime": "^1.1.6"
}, },
"engines": { "engines": {
"node": "^20.19.0 || >=22.12.0" "node": "^20.19.0 || >=22.12.0"
} }
}, },
"node_modules/@rolldown/binding-win32-arm64-msvc": { "node_modules/@rolldown/binding-win32-arm64-msvc": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.3.tgz",
"integrity": "sha512-zsu47DgU0FQzSwi6sU9dZoEdUv7pc1AptSEz/Z8HBg54sV0Pbs3N0+CrIbTsgiu6EyoaNN9CHboqbLaz9lhOyQ==", "integrity": "sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@@ -346,9 +403,9 @@
} }
}, },
"node_modules/@rolldown/binding-win32-x64-msvc": { "node_modules/@rolldown/binding-win32-x64-msvc": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.3.tgz",
"integrity": "sha512-7H+3yqGgmnlDTRRhw/xpYY9J1kf4GC681nVc4GqKhExZTDrVVrV2tsOR9kso0fvgBdcTCcQShx4SLLoHgaLwhg==", "integrity": "sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@@ -363,16 +420,16 @@
} }
}, },
"node_modules/@rolldown/pluginutils": { "node_modules/@rolldown/pluginutils": {
"version": "1.0.0-rc.18", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
"integrity": "sha512-CUY5Mnhe64xQBGZEEXQ5WyZwsc1JU3vAZLIxtrsBt3LO6UOb+C8GunVKqe9sT8NeWb4lqSaoJtp2xo6GxT1MNw==", "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@tybys/wasm-util": { "node_modules/@tybys/wasm-util": {
"version": "0.10.2", "version": "0.10.3",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
"integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
@@ -407,6 +464,171 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"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==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"peerDependencies": {
"vite": "^5.0.0 || ^6.0.0",
"vue": "^3.2.25"
}
},
"node_modules/@volar/language-core": {
"version": "2.4.28",
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz",
"integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@volar/source-map": "2.4.28"
}
},
"node_modules/@volar/source-map": {
"version": "2.4.28",
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz",
"integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@volar/typescript": {
"version": "2.4.28",
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz",
"integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@volar/language-core": "2.4.28",
"path-browserify": "^1.0.1",
"vscode-uri": "^3.0.8"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.39.tgz",
"integrity": "sha512-16KBTEXAJCpDr0mwlw+AZyhu8iyC7R3S2vBwsI7QnWJU6X3WKc9VKeNEZpiMdZ569qWhz9574L3vV55qRL0Vtw==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
"@vue/shared": "3.5.39",
"entities": "^7.0.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.39.tgz",
"integrity": "sha512-oQPigALqYbNxTNPvNgSOe+czwVExfbVF02lz8jP0S3AXJiu3jxYDygNUiqSep4ezzW8XgnubqH63My2A7JR/vg==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.39",
"@vue/shared": "3.5.39"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.39.tgz",
"integrity": "sha512-d0ki86iOyN8LoZPBmk5SJWNwHP19CnDDCfuo//+2WJa2g5Ke0Jay983PIBIcSSzldC68I8DrD5GrHV3OSDfodg==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.29.7",
"@vue/compiler-core": "3.5.39",
"@vue/compiler-dom": "3.5.39",
"@vue/compiler-ssr": "3.5.39",
"@vue/shared": "3.5.39",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.21",
"postcss": "^8.5.15",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.39.tgz",
"integrity": "sha512-Ce7/wvwMHai74bdszfXExdazFigYnlF9zgCmEQUcM1j0fOymlouZ7XilTYNo8oUjhlnjYOZbGrcYKuqjz89Ucw==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.39",
"@vue/shared": "3.5.39"
}
},
"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/language-core": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.5.tgz",
"integrity": "sha512-UkKu5nhX89fg4VhlG/FOeI10G3cj/7radKT/cy9BT4Q9qJmJlSTAc/dP63Xqs29aypN4f39xUV6PsLNk/dcD6g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@volar/language-core": "2.4.28",
"@vue/compiler-dom": "^3.5.0",
"@vue/shared": "^3.5.0",
"alien-signals": "^3.2.0",
"muggle-string": "^0.4.1",
"path-browserify": "^1.0.1",
"picomatch": "^4.0.4"
}
},
"node_modules/@vue/reactivity": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.39.tgz",
"integrity": "sha512-TpsuBJ9gGlZa5d23XcM2y8EXanz9dZeVDQBXRwzy46ItgvM+rWpzs+UVM0wcRLxGvcav0HE5jz2gNL53xlRAog==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.5.39"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.39.tgz",
"integrity": "sha512-9GLtNyRvPAUMbX+7ono0RC2j0guo2LXVi8LvcmAooImACUKm0oFf0jjwbX8/H0AE/t1nxhAkn8RSl9PMCzzxZw==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.39",
"@vue/shared": "3.5.39"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.39.tgz",
"integrity": "sha512-7Y6aAGboKcXAZ3ECuUy7RrS5yy2r47dhTp2SKaJmYxjopImaVFaNa5Ne66NwGovsrxVAl5S5rwc7m22UG7Lmww==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.39",
"@vue/runtime-core": "3.5.39",
"@vue/shared": "3.5.39",
"csstype": "^3.2.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.39.tgz",
"integrity": "sha512-yZSakiAGw85rZfG7UM8akMnIF+FmeiNk47uvHf2nVBBSe+dIKUhZuZq9+XgJhbV3nS5Z4ALH23/MpXofW+mbcw==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.5.39",
"@vue/shared": "3.5.39"
},
"peerDependencies": {
"vue": "3.5.39"
}
},
"node_modules/@vue/shared": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.39.tgz",
"integrity": "sha512-l1rrBtBfTnmxvtsvdQDXltUUy8S1Y+ZaqdfUzmAnJkTd8Z8rv5v/ytW+TKiqEOWyHPoqtPlNFSs0lhRmYVSHVA==",
"license": "MIT"
},
"node_modules/abort-controller": { "node_modules/abort-controller": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -419,6 +641,13 @@
"node": ">=6.5" "node": ">=6.5"
} }
}, },
"node_modules/alien-signals": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz",
"integrity": "sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==",
"dev": true,
"license": "MIT"
},
"node_modules/base64-js": { "node_modules/base64-js": {
"version": "1.5.1", "version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -528,6 +757,12 @@
"node": ">= 6" "node": ">= 6"
} }
}, },
"node_modules/csstype": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
"license": "MIT"
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.4.3", "version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
@@ -555,6 +790,24 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/entities": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
"integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"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/event-target-shim": { "node_modules/event-target-shim": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
@@ -949,6 +1202,15 @@
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/minimist": { "node_modules/minimist": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
@@ -1007,11 +1269,17 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/muggle-string": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
"dev": true,
"license": "MIT"
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.12", "version": "3.3.12",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@@ -1036,11 +1304,17 @@
"js-sdsl": "4.3.0" "js-sdsl": "4.3.0"
} }
}, },
"node_modules/path-browserify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
"dev": true,
"license": "MIT"
},
"node_modules/picocolors": { "node_modules/picocolors": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"dev": true,
"license": "ISC" "license": "ISC"
}, },
"node_modules/picomatch": { "node_modules/picomatch": {
@@ -1056,11 +1330,32 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/pinia": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/pinia/-/pinia-2.3.1.tgz",
"integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==",
"license": "MIT",
"dependencies": {
"@vue/devtools-api": "^6.6.3",
"vue-demi": "^0.14.10"
},
"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": { "node_modules/postcss": {
"version": "8.5.14", "version": "8.5.15",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
"integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@@ -1077,7 +1372,7 @@
], ],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"nanoid": "^3.3.11", "nanoid": "^3.3.12",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
"source-map-js": "^1.2.1" "source-map-js": "^1.2.1"
}, },
@@ -1123,14 +1418,14 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/rolldown": { "node_modules/rolldown": {
"version": "1.0.0-rc.18", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.18.tgz", "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.3.tgz",
"integrity": "sha512-phmyKBpuBdRYDf4hgyynGAYn/rDDe+iZXKVJ7WX5b1zQzpLkP5oJRPGsfJuHdzPMlyyEO/4sPW6yfSx2gf7lVg==", "integrity": "sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@oxc-project/types": "=0.128.0", "@oxc-project/types": "=0.137.0",
"@rolldown/pluginutils": "1.0.0-rc.18" "@rolldown/pluginutils": "^1.0.0"
}, },
"bin": { "bin": {
"rolldown": "bin/cli.mjs" "rolldown": "bin/cli.mjs"
@@ -1139,21 +1434,21 @@
"node": "^20.19.0 || >=22.12.0" "node": "^20.19.0 || >=22.12.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rolldown/binding-android-arm64": "1.0.0-rc.18", "@rolldown/binding-android-arm64": "1.1.3",
"@rolldown/binding-darwin-arm64": "1.0.0-rc.18", "@rolldown/binding-darwin-arm64": "1.1.3",
"@rolldown/binding-darwin-x64": "1.0.0-rc.18", "@rolldown/binding-darwin-x64": "1.1.3",
"@rolldown/binding-freebsd-x64": "1.0.0-rc.18", "@rolldown/binding-freebsd-x64": "1.1.3",
"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.18", "@rolldown/binding-linux-arm-gnueabihf": "1.1.3",
"@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.18", "@rolldown/binding-linux-arm64-gnu": "1.1.3",
"@rolldown/binding-linux-arm64-musl": "1.0.0-rc.18", "@rolldown/binding-linux-arm64-musl": "1.1.3",
"@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.18", "@rolldown/binding-linux-ppc64-gnu": "1.1.3",
"@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.18", "@rolldown/binding-linux-s390x-gnu": "1.1.3",
"@rolldown/binding-linux-x64-gnu": "1.0.0-rc.18", "@rolldown/binding-linux-x64-gnu": "1.1.3",
"@rolldown/binding-linux-x64-musl": "1.0.0-rc.18", "@rolldown/binding-linux-x64-musl": "1.1.3",
"@rolldown/binding-openharmony-arm64": "1.0.0-rc.18", "@rolldown/binding-openharmony-arm64": "1.1.3",
"@rolldown/binding-wasm32-wasi": "1.0.0-rc.18", "@rolldown/binding-wasm32-wasi": "1.1.3",
"@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.18", "@rolldown/binding-win32-arm64-msvc": "1.1.3",
"@rolldown/binding-win32-x64-msvc": "1.0.0-rc.18" "@rolldown/binding-win32-x64-msvc": "1.1.3"
} }
}, },
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
@@ -1204,7 +1499,6 @@
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@@ -1229,9 +1523,9 @@
} }
}, },
"node_modules/tinyglobby": { "node_modules/tinyglobby": {
"version": "0.2.16", "version": "0.2.17",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
"integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1261,7 +1555,7 @@
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"dev": true, "devOptional": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@@ -1284,17 +1578,17 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "8.0.11", "version": "8.1.0",
"resolved": "https://registry.npmjs.org/vite/-/vite-8.0.11.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.0.tgz",
"integrity": "sha512-Jz1mxtUBR5xTT65VOdJZUUeoyLtqljmFkiUXhPTLZka3RDc9vpi/xXkyrnsdRcm2lIi3l3GPMnAidTsEGIj3Ow==", "integrity": "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"lightningcss": "^1.32.0", "lightningcss": "^1.32.0",
"picomatch": "^4.0.4", "picomatch": "^4.0.4",
"postcss": "^8.5.14", "postcss": "^8.5.15",
"rolldown": "1.0.0-rc.18", "rolldown": "~1.1.2",
"tinyglobby": "^0.2.16" "tinyglobby": "^0.2.17"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"
@@ -1310,7 +1604,7 @@
}, },
"peerDependencies": { "peerDependencies": {
"@types/node": "^20.19.0 || >=22.12.0", "@types/node": "^20.19.0 || >=22.12.0",
"@vitejs/devtools": "^0.1.18", "@vitejs/devtools": "^0.3.0",
"esbuild": "^0.27.0 || ^0.28.0", "esbuild": "^0.27.0 || ^0.28.0",
"jiti": ">=1.21.0", "jiti": ">=1.21.0",
"less": "^4.0.0", "less": "^4.0.0",
@@ -1361,6 +1655,92 @@
} }
} }
}, },
"node_modules/vscode-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
"dev": true,
"license": "MIT"
},
"node_modules/vue": {
"version": "3.5.39",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.39.tgz",
"integrity": "sha512-xmZCYabFGcirU8r0fTuvl/LICc1OU620rnqepaJDL/a141ZigkG7AyaxQLdqJ02ZRYzWe6YPaDHeQx7MfknQfA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.39",
"@vue/compiler-sfc": "3.5.39",
"@vue/runtime-dom": "3.5.39",
"@vue/server-renderer": "3.5.39",
"@vue/shared": "3.5.39"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/vue-router": {
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
"integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==",
"license": "MIT",
"dependencies": {
"@vue/devtools-api": "^6.6.4"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"vue": "^3.5.0"
}
},
"node_modules/vue-tsc": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.5.tgz",
"integrity": "sha512-Rzh/G2MmNlMSAMTiQEjDrsb4dgB/jbtEM47rVN2NtidF1dfb/q4w4QvpQBtW5+y3y5H27Hjh7deVwk+YB02fNg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@volar/typescript": "2.4.28",
"@vue/language-core": "3.3.5"
},
"bin": {
"vue-tsc": "bin/vue-tsc.js"
},
"peerDependencies": {
"typescript": ">=5.0.0"
}
},
"node_modules/worker-factory": { "node_modules/worker-factory": {
"version": "7.0.49", "version": "7.0.49",
"resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.49.tgz", "resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.49.tgz",
@@ -1409,9 +1789,9 @@
} }
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "8.20.0", "version": "8.21.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
"integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
+8 -3
View File
@@ -5,14 +5,19 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "tsc && vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"typescript": "~6.0.2", "typescript": "~6.0.2",
"vite": "^8.0.10" "vite": "^8.1.0",
"vue-tsc": "^3.3.5"
}, },
"dependencies": { "dependencies": {
"mqtt": "^5.15.1" "mqtt": "^5.15.1",
"pinia": "^2.1.7",
"vue": "^3.3.12",
"vue-router": "^4.2.5"
} }
} }
+9
View File
@@ -0,0 +1,9 @@
<template>
<router-view />
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
+7
View File
@@ -0,0 +1,7 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
+8 -294
View File
@@ -1,297 +1,11 @@
import mqtt from 'mqtt' import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import { router } from './router'
import './style.css' import './style.css'
type Page = 'home' | 'players' | 'start' | 'text' const app = createApp(App)
type Route = 'home' | 'maintenance' | 'players' | 'start' | 'text'
const storageKey = 'players' app.use(createPinia())
const mqttBrokerHost = '91.99.29.8' app.use(router)
const mqttBrokerPort = 9001 app.mount('#app')
const mqttBrokerPath = '/mqtt'
const mqttUseTls = false
const mqttTopic = 'king-arthur/page/startup'
const mqttMessage = 'start-hit'
const initialPlayers = loadPlayers()
let players: string[] = []
let currentName = ''
function loadPlayers(): string[] {
const saved = localStorage.getItem(storageKey)
if (!saved) return []
try {
const parsed = JSON.parse(saved)
if (Array.isArray(parsed)) {
return parsed.filter((item): item is string => typeof item === 'string' && item.trim().length > 0)
}
} catch {
return []
}
return []
}
function savePlayers(): void {
localStorage.setItem(storageKey, JSON.stringify(players))
}
function publishStartHit(): void {
const protocol = mqttUseTls ? 'wss' : 'ws'
const brokerUrl = `${protocol}://${mqttBrokerHost}:${mqttBrokerPort}${mqttBrokerPath}`
const client = mqtt.connect(brokerUrl)
client.on('connect', () => {
client.publish(mqttTopic, mqttMessage, { qos: 1 }, () => {
client.end()
})
})
client.on('error', (error) => {
console.error('MQTT publish failed:', error)
client.end(true)
})
}
function getRouteFromPath(): Route {
const path = window.location.pathname
if (path === '/') return 'home'
if (path === '/maintenance') return 'maintenance'
if (path === '/players') return 'players'
if (path === '/start') return 'start'
if (path === '/text') return 'text'
if (path.startsWith('/players')) return 'players'
if (path.startsWith('/start')) return 'start'
if (path.startsWith('/text')) return 'text'
return 'home'
}
function navigateTo(path: string): void {
window.history.pushState({}, '', path)
render()
}
function render(): void {
const app = document.querySelector<HTMLDivElement>('#app')
if (!app) return
const route = getRouteFromPath()
const path = window.location.pathname
if (route === 'home') {
app.innerHTML = `
<main class="app">
<section class="page-content">
${renderHomePage()}
</section>
</main>
`
} else if (path === '/maintenance') {
const maintenancePage: Page = 'players'
app.innerHTML = `
<main class="app">
<h1>Simple Player Web App</h1>
<nav class="nav">
<a href="/players" class="nav-link active">Page 1: Players</a>
<a href="/start" class="nav-link">Page 2: Start</a>
<a href="/text" class="nav-link">Page 3: Text</a>
</nav>
<section class="page-content">
${renderPage(maintenancePage)}
</section>
</main>
`
attachNavigationHandlers(maintenancePage)
} else {
const page = route as Page
app.innerHTML = `
<main class="app">
<section class="page-content">
${renderPage(page)}
</section>
</main>
`
attachHandlers(page)
}
}
function renderHomePage(): string {
return `
<div class="home-content">
<h1>Welcome to King Arthur</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<div class="info-section">
<div class="info-box">
<h3>Version</h3>
<p id="version-number">1.0.0</p>
</div>
<div class="info-box">
<h3>Service Hotline</h3>
<p id="service-hotline">+1 800-123-4567</p>
</div>
</div>
<nav class="home-nav">
<a href="/players" class="nav-button">Players</a>
<a href="/start" class="nav-button">Start</a>
<a href="/text" class="nav-button">Text</a>
<a href="/maintenance" class="nav-button">Maintenance</a>
</nav>
</div>
`
}
function renderPage(page: Page): string {
if (page === 'players') {
const listItems = players.map((name, index) => `
<li class="player-item">
<span class="player-name">${name}</span>
<button class="delete-btn" data-index="${index}" title="Delete player">
<svg class="trash-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-9l-1 1H5v2h14V4z" fill="currentColor"/>
</svg>
</button>
</li>
`).join('')
return `
<h2>Add players</h2>
<div class="row">
<input id="player-input" type="text" placeholder="Enter player name" />
<button id="add-player" type="button">Add</button>
</div>
<ul class="player-list">${listItems}</ul>
<div class="players-actions">
<button id="clear-all-btn" type="button" class="btn-secondary">Clear All</button>
<button id="finished-btn" type="button" class="btn-primary">Finished</button>
</div>
`
}
if (page === 'start') {
const shownName = currentName || 'No name selected yet'
return `
<h2>Start</h2>
<button id="start-btn" type="button">Start</button>
<p id="selected-name">${shownName}</p>
`
}
return `
<h2>Some text</h2>
<p>This is the third page with static text.</p>
`
}
function attachNavigationHandlers(page: Page): void {
const navLinks = document.querySelectorAll<HTMLAnchorElement>('.nav-link')
navLinks.forEach((link) => {
link.addEventListener('click', (e) => {
e.preventDefault()
const href = link.getAttribute('href')
if (href) {
navigateTo(href)
updateActiveNavLink(page)
}
})
})
attachHandlers(page)
}
function updateActiveNavLink(page: Page): void {
const navLinks = document.querySelectorAll<HTMLAnchorElement>('.nav-link')
navLinks.forEach((link) => {
link.classList.remove('active')
const href = link.getAttribute('href')
if (
(page === 'players' && href === '/players') ||
(page === 'start' && href === '/start') ||
(page === 'text' && href === '/text')
) {
link.classList.add('active')
}
})
}
function attachHandlers(page: Page): void {
if (page === 'players') {
const input = document.querySelector<HTMLInputElement>('#player-input')
const button = document.querySelector<HTMLButtonElement>('#add-player')
const deleteButtons = document.querySelectorAll<HTMLButtonElement>('.delete-btn')
const clearAllBtn = document.querySelector<HTMLButtonElement>('#clear-all-btn')
const finishedBtn = document.querySelector<HTMLButtonElement>('#finished-btn')
if (input && button) {
const addPlayer = () => {
const value = input.value.trim()
if (!value) return
players.push(value)
savePlayers()
input.value = ''
render()
}
button.addEventListener('click', addPlayer)
input.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
addPlayer()
}
})
}
deleteButtons.forEach((btn) => {
btn.addEventListener('click', () => {
const index = parseInt(btn.getAttribute('data-index') || '0', 10)
players.splice(index, 1)
savePlayers()
render()
})
})
if (clearAllBtn) {
clearAllBtn.addEventListener('click', () => {
if (confirm('Are you sure you want to delete all players?')) {
players = []
savePlayers()
render()
}
})
}
if (finishedBtn) {
finishedBtn.addEventListener('click', () => {
window.location.href = '/start'
})
}
}
if (page === 'start') {
const button = document.querySelector<HTMLButtonElement>('#start-btn')
const selectedName = document.querySelector<HTMLParagraphElement>('#selected-name')
if (button && selectedName) {
button.addEventListener('click', () => {
publishStartHit()
if (players.length === 0) {
currentName = 'Please add players on page 1 first.'
} else {
const randomIndex = Math.floor(Math.random() * players.length)
currentName = (players[randomIndex])
}
selectedName.textContent = currentName
})
}
}
}
window.addEventListener('popstate', render)
if (window.location.pathname === '/' || !window.location.pathname.startsWith('/')) {
window.history.replaceState({}, '', '/')
}
render()
+57
View File
@@ -0,0 +1,57 @@
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Maintenance from '../views/Maintenance.vue'
import Players from '../views/Players.vue'
import Start from '../views/Start.vue'
import Text from '../views/Text.vue'
const routes: any[] = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/players',
name: 'PlayersDirect',
component: Players
},
{
path: '/start',
name: 'StartDirect',
component: Start
},
{
path: '/text',
name: 'TextDirect',
component: Text
},
{
path: '/maintenance',
name: 'Maintenance',
component: Maintenance,
redirect: '/maintenance/players',
children: [
{
path: 'players',
name: 'PlayersInMaintenance',
component: Players
},
{
path: 'start',
name: 'StartInMaintenance',
component: Start
},
{
path: 'text',
name: 'TextInMaintenance',
component: Text
}
]
}
]
export const router = createRouter({
history: createWebHistory(),
routes
})
+31
View File
@@ -0,0 +1,31 @@
import mqtt from 'mqtt'
const mqttBrokerHost = '91.99.29.8'
const mqttBrokerPort = 9001
const mqttBrokerPath = '/mqtt'
const mqttUseTls = false
const mqttTopic = 'king-arthur/page/startup'
const mqttMessage = 'start-hit'
let client: any = null
export function getMqttClient(): any {
return client
}
export function publishStartHit(): void {
const protocol = mqttUseTls ? 'wss' : 'ws'
const brokerUrl = `${protocol}://${mqttBrokerHost}:${mqttBrokerPort}${mqttBrokerPath}`
const tempClient = mqtt.connect(brokerUrl)
tempClient.on('connect', () => {
tempClient.publish(mqttTopic, mqttMessage, { qos: 1 }, () => {
tempClient.end()
})
})
tempClient.on('error', (error: any) => {
console.error('MQTT publish failed:', error)
tempClient.end(true)
})
}
+70
View File
@@ -0,0 +1,70 @@
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const usePlayersStore = defineStore('players', () => {
const players = ref<string[]>([])
const currentName = ref<string>('')
const playersCount = computed(() => players.value.length)
function loadPlayers(): void {
const saved = localStorage.getItem('players')
if (!saved) return
try {
const parsed = JSON.parse(saved)
if (Array.isArray(parsed)) {
players.value = parsed.filter((item): item is string => typeof item === 'string' && item.trim().length > 0)
}
} catch {
players.value = []
}
}
function savePlayers(): void {
localStorage.setItem('players', JSON.stringify(players.value))
}
function addPlayer(name: string): void {
const trimmed = name.trim()
if (!trimmed) return
players.value.push(trimmed)
savePlayers()
}
function deletePlayer(index: number): void {
players.value.splice(index, 1)
savePlayers()
}
function clearAllPlayers(): void {
players.value = []
savePlayers()
}
function selectRandomPlayer(): void {
if (players.value.length === 0) {
currentName.value = 'Please add players on page 1 first.'
} else {
const randomIndex = Math.floor(Math.random() * players.value.length)
currentName.value = players.value[randomIndex]
}
}
function setCurrentName(name: string): void {
currentName.value = name
}
loadPlayers()
return {
players,
currentName,
playersCount,
addPlayer,
deletePlayer,
clearAllPlayers,
selectRandomPlayer,
setCurrentName
}
})
+24
View File
@@ -0,0 +1,24 @@
<template>
<main class="app">
<nav class="nav">
<router-link to="/" class="nav-link">Home</router-link>
<router-link to="/players" class="nav-link" :class="{ active: route.path === '/players' }">Page 1: Players</router-link>
<router-link to="/start" class="nav-link" :class="{ active: route.path === '/start' }">Page 2: Start</router-link>
<router-link to="/text" class="nav-link" :class="{ active: route.path === '/text' }">Page 3: Text</router-link>
</nav>
<section class="page-content">
<Players v-if="route.path === '/players'" />
<Start v-else-if="route.path === '/start'" />
<Text v-else-if="route.path === '/text'" />
</section>
</main>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
import Players from './Players.vue'
import Start from './Start.vue'
import Text from './Text.vue'
const route = useRoute()
</script>
+29
View File
@@ -0,0 +1,29 @@
<template>
<main class="app">
<section class="page-content">
<div class="home-content">
<h1>King Arthur Outdoor Adventure</h1>
<p>Outdoor adventure to find the chosen one and join him on a quest.</p>
<div class="info-section">
<div class="info-box">
<h3>Version</h3>
<p id="version-number">1.0.0</p>
</div>
<div class="info-box">
<h3>Service Hotline</h3>
<p id="service-hotline">+1 800-123-4567</p>
</div>
</div>
<nav class="home-nav">
<router-link to="/players" class="nav-button">Players</router-link>
<router-link to="/start" class="nav-button">Start</router-link>
<router-link to="/text" class="nav-button">Text</router-link>
<router-link to="/maintenance" class="nav-button">Maintenance</router-link>
</nav>
</div>
</section>
</main>
</template>
<script setup lang="ts">
</script>
+23
View File
@@ -0,0 +1,23 @@
<template>
<main class="app">
<h1>Simple Player Web App</h1>
<nav class="nav">
<router-link to="/maintenance/players" class="nav-link" :class="{ active: isActive('/maintenance/players') }">Page 1: Players</router-link>
<router-link to="/maintenance/start" class="nav-link" :class="{ active: isActive('/maintenance/start') }">Page 2: Start</router-link>
<router-link to="/maintenance/text" class="nav-link" :class="{ active: isActive('/maintenance/text') }">Page 3: Text</router-link>
</nav>
<section class="page-content">
<router-view></router-view>
</section>
</main>
</template>
<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
function isActive(path: string): boolean {
return route.path === path
}
</script>
+55
View File
@@ -0,0 +1,55 @@
<template>
<div>
<h2>Add players</h2>
<div class="row">
<input
v-model="playerInput"
type="text"
placeholder="Enter player name"
@keydown.enter="addPlayer"
/>
<button @click="addPlayer" type="button">Add</button>
</div>
<ul class="player-list">
<li v-for="(player, index) in playersStore.players" :key="index" class="player-item">
<span class="player-name">{{ player }}</span>
<button class="delete-btn" @click="deletePlayer(index)" title="Delete player">
<svg class="trash-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-9l-1 1H5v2h14V4z" fill="currentColor"/>
</svg>
</button>
</li>
</ul>
<div class="players-actions">
<button @click="clearAll" type="button" class="btn-secondary">Clear All</button>
<button @click="finished" type="button" class="btn-primary">Finished</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { usePlayersStore } from '../stores/players'
const playerInput = ref<string>('')
const playersStore = usePlayersStore()
function addPlayer(): void {
playersStore.addPlayer(playerInput.value)
playerInput.value = ''
}
function deletePlayer(index: number): void {
playersStore.deletePlayer(index)
}
function clearAll(): void {
if (confirm('Are you sure you want to delete all players?')) {
playersStore.clearAllPlayers()
}
}
function finished(): void {
router.push('/start')
}
</script>
+19
View File
@@ -0,0 +1,19 @@
<template>
<div>
<h2>Start</h2>
<button @click="startGame" id="start-btn" type="button">Start</button>
<p id="selected-name">{{ playersStore.currentName || 'No name selected yet' }}</p>
</div>
</template>
<script setup lang="ts">
import { usePlayersStore } from '../stores/players'
import { publishStartHit } from '../services/mqtt'
const playersStore = usePlayersStore()
function startGame(): void {
publishStartHit()
playersStore.selectRandomPlayer()
}
</script>
+9
View File
@@ -0,0 +1,9 @@
<template>
<div>
<h2>Some text</h2>
<p>This is the third page with static text.</p>
</div>
</template>
<script setup lang="ts">
</script>
+8 -3
View File
@@ -5,6 +5,8 @@
"lib": ["ES2023", "DOM"], "lib": ["ES2023", "DOM"],
"types": ["vite/client"], "types": ["vite/client"],
"skipLibCheck": true, "skipLibCheck": true,
"jsx": "preserve",
"jsxImportSource": "vue",
/* Bundler mode */ /* Bundler mode */
"moduleResolution": "bundler", "moduleResolution": "bundler",
@@ -14,10 +16,13 @@
"noEmit": true, "noEmit": true,
/* Linting */ /* Linting */
"noUnusedLocals": true, "noUnusedLocals": false,
"noUnusedParameters": true, "noUnusedParameters": false,
"erasableSyntaxOnly": true, "erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true "noFallthroughCasesInSwitch": true
}, },
"include": ["src"] "include": ["src"],
"vueCompilerOptions": {
"experimentalRuntimeMode": "runtime"
}
} }
+6
View File
@@ -0,0 +1,6 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()]
})