Compare commits
43 commits
Author | SHA1 | Date | |
---|---|---|---|
43e80a4688 | |||
df35978722 | |||
3befba2f5c | |||
394e1fff5a | |||
7af68e51ba | |||
be998b1959 | |||
4fee40921e | |||
e17a6b70ec | |||
d6576a5004 | |||
18c7ccd084 | |||
999e912021 | |||
926a5c3d86 | |||
427a3fadbb | |||
b5c1b46938 | |||
c141004cd2 | |||
650fa5fb4c | |||
219d590e71 | |||
8e33400516 | |||
3279036332 | |||
9de0059976 | |||
007eda1b8c | |||
e986e23767 | |||
ef25e178bf | |||
de5600899d | |||
8275253adf | |||
e8dcdd37ea | |||
06c0dc8271 | |||
67d2358a37 | |||
d1a3772f6c | |||
e96718c273 | |||
a2c27899f7 | |||
98967bc491 | |||
7a25132d0b | |||
5423802ae5 | |||
ee5ed04bcb | |||
79445dd9a3 | |||
b4ad43147b | |||
8d7b3d6dc2 | |||
298592681b | |||
7c2c68a7b8 | |||
b775ee5d03 | |||
b318f77438 | |||
0065a9f9a9 |
46 changed files with 1592 additions and 350 deletions
3
.env.example
Normal file
3
.env.example
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
DISCORD_CLIENT_ID=
|
||||||
|
DISCORD_CLIENT_SECRET=
|
||||||
|
PUBLIC_BASE_URL=http://localhost:5173
|
2
.envrc
2
.envrc
|
@ -1 +1 @@
|
||||||
use flake
|
use nix
|
||||||
|
|
|
@ -14,6 +14,10 @@ jobs:
|
||||||
- uses: oven-sh/setup-bun@v2
|
- uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
env:
|
||||||
|
DISCORD_CLIENT_ID: ${{ secrets.DISCORD_CLIENT_ID }}
|
||||||
|
DISCORD_CLIENT_SECRET: ${{ secrets.DISCORD_CLIENT_SECRET }}
|
||||||
|
PUBLIC_BASE_URL: https://tcl-guessr.pages.dev
|
||||||
run: |
|
run: |
|
||||||
bun install --frozen-lockfile
|
bun install --frozen-lockfile
|
||||||
bun run build
|
bun run build
|
||||||
|
|
667
bun.lock
Normal file
667
bun.lock
Normal file
|
@ -0,0 +1,667 @@
|
||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"name": "tcl-guessr",
|
||||||
|
"dependencies": {
|
||||||
|
"@fontsource-variable/inter": "^5.1.1",
|
||||||
|
"@oslojs/crypto": "^1.0.1",
|
||||||
|
"@oslojs/encoding": "^1.1.0",
|
||||||
|
"arctic": "^3.2.2",
|
||||||
|
"destr": "^2.0.3",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
|
"leaflet-defaulticon-compatibility": "^0.1.2",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@cloudflare/workers-types": "^4.20250129.0",
|
||||||
|
"@sveltejs/adapter-cloudflare": "^5.0.2",
|
||||||
|
"@sveltejs/kit": "^2.17.1",
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
|
"@types/eslint": "^9.6.1",
|
||||||
|
"@types/leaflet": "^1.9.16",
|
||||||
|
"eslint": "^9.19.0",
|
||||||
|
"eslint-config-prettier": "^10.0.1",
|
||||||
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
|
"globals": "^15.14.0",
|
||||||
|
"prettier": "^3.4.2",
|
||||||
|
"prettier-plugin-svelte": "^3.3.3",
|
||||||
|
"svelte": "^5.19.7",
|
||||||
|
"svelte-check": "^4.1.4",
|
||||||
|
"typescript": "^5.7.3",
|
||||||
|
"typescript-eslint": "^8.23.0",
|
||||||
|
"vite": "^6.0.11",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||||
|
|
||||||
|
"@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.3.4", "", { "dependencies": { "mime": "^3.0.0" } }, "sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q=="],
|
||||||
|
|
||||||
|
"@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20250129.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-M+xETVnl+xy2dfDDWmp0XXr2rttl70a6bljQygl0EmYmNswFTcYbQWCaBuNBo9kabU59rLKr4a/b3QZ07NoL/g=="],
|
||||||
|
|
||||||
|
"@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20250129.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c4PQUyIMp+bCMxZkAMBzXgTHjRZxeYCujDbb3staestqgRbenzcfauXsMd6np35ng+EE1uBgHNPV4+7fC0ZBfg=="],
|
||||||
|
|
||||||
|
"@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20250129.0", "", { "os": "linux", "cpu": "x64" }, "sha512-xJx8LwWFxsm5U3DETJwRuOmT5RWBqm4FmA4itYXvcEICca9pWJDB641kT4PnpypwDNmYOebhU7A+JUrCRucG0w=="],
|
||||||
|
|
||||||
|
"@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20250129.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-dR//npbaX5p323huBVNIy5gaWubQx6CC3aiXeK0yX4aD5ar8AjxQFb2U/Sgjeo65Rkt53hJWqC7IwRpK/eOxrA=="],
|
||||||
|
|
||||||
|
"@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20250129.0", "", { "os": "win32", "cpu": "x64" }, "sha512-OeO+1nPj/ocAE3adFar/tRFGRkbCrBnrOYXq0FUBSpyNHpDdA9/U3PAw5CN4zvjfTnqXZfTxTFeqoruqzRzbtg=="],
|
||||||
|
|
||||||
|
"@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250129.0", "", {}, "sha512-H7g/sDB9GaV+fIPf3utNEYncFhryIvDThiBbfZtu0bZmVXcVd9ApP3OMqUYhNV8MShWQASvgWletKKBZGT9/oA=="],
|
||||||
|
|
||||||
|
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
|
||||||
|
|
||||||
|
"@esbuild-plugins/node-globals-polyfill": ["@esbuild-plugins/node-globals-polyfill@0.2.3", "", { "peerDependencies": { "esbuild": "*" } }, "sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw=="],
|
||||||
|
|
||||||
|
"@esbuild-plugins/node-modules-polyfill": ["@esbuild-plugins/node-modules-polyfill@0.2.2", "", { "dependencies": { "escape-string-regexp": "^4.0.0", "rollup-plugin-node-polyfills": "^0.2.1" }, "peerDependencies": { "esbuild": "*" } }, "sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA=="],
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.24.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm": ["@esbuild/android-arm@0.24.2", "", { "os": "android", "cpu": "arm" }, "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.24.2", "", { "os": "android", "cpu": "arm64" }, "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg=="],
|
||||||
|
|
||||||
|
"@esbuild/android-x64": ["@esbuild/android-x64@0.24.2", "", { "os": "android", "cpu": "x64" }, "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.24.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.24.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.24.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.24.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.24.2", "", { "os": "linux", "cpu": "arm" }, "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.24.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.24.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.24.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.24.2", "", { "os": "linux", "cpu": "none" }, "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.24.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.24.2", "", { "os": "linux", "cpu": "x64" }, "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.24.2", "", { "os": "none", "cpu": "arm64" }, "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.24.2", "", { "os": "none", "cpu": "x64" }, "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.24.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.24.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA=="],
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.24.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.24.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.24.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="],
|
||||||
|
|
||||||
|
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA=="],
|
||||||
|
|
||||||
|
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||||
|
|
||||||
|
"@eslint/config-array": ["@eslint/config-array@0.19.2", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w=="],
|
||||||
|
|
||||||
|
"@eslint/core": ["@eslint/core@0.10.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw=="],
|
||||||
|
|
||||||
|
"@eslint/eslintrc": ["@eslint/eslintrc@3.2.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w=="],
|
||||||
|
|
||||||
|
"@eslint/js": ["@eslint/js@9.19.0", "", {}, "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ=="],
|
||||||
|
|
||||||
|
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||||
|
|
||||||
|
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.5", "", { "dependencies": { "@eslint/core": "^0.10.0", "levn": "^0.4.1" } }, "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A=="],
|
||||||
|
|
||||||
|
"@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="],
|
||||||
|
|
||||||
|
"@fontsource-variable/inter": ["@fontsource-variable/inter@5.1.1", "", {}, "sha512-OpXFTmiH6tHkYijMvQTycFKBLK4X+SRV6tet1m4YOUH7SzIIlMqDja+ocDtiCA72UthBH/vF+3ZtlMr2rN/wIw=="],
|
||||||
|
|
||||||
|
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||||
|
|
||||||
|
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
|
||||||
|
|
||||||
|
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||||
|
|
||||||
|
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.1", "", {}, "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA=="],
|
||||||
|
|
||||||
|
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||||
|
|
||||||
|
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||||
|
|
||||||
|
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
|
||||||
|
|
||||||
|
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||||
|
|
||||||
|
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||||
|
|
||||||
|
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||||
|
|
||||||
|
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||||
|
|
||||||
|
"@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="],
|
||||||
|
|
||||||
|
"@oslojs/binary": ["@oslojs/binary@1.0.0", "", {}, "sha512-9RCU6OwXU6p67H4NODbuxv2S3eenuQ4/WFLrsq+K/k682xrznH5EVWA7N4VFk9VYVcbFtKqur5YQQZc0ySGhsQ=="],
|
||||||
|
|
||||||
|
"@oslojs/crypto": ["@oslojs/crypto@1.0.1", "", { "dependencies": { "@oslojs/asn1": "1.0.0", "@oslojs/binary": "1.0.0" } }, "sha512-7n08G8nWjAr/Yu3vu9zzrd0L9XnrJfpMioQcvCMxBIiF5orECHe5/3J0jmXRVvgfqMm/+4oxlQ+Sq39COYLcNQ=="],
|
||||||
|
|
||||||
|
"@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="],
|
||||||
|
|
||||||
|
"@oslojs/jwt": ["@oslojs/jwt@0.2.0", "", { "dependencies": { "@oslojs/encoding": "0.4.1" } }, "sha512-bLE7BtHrURedCn4Mco3ma9L4Y1GR2SMBuIvjWr7rmQ4/W/4Jy70TIAgZ+0nIlk0xHz1vNP8x8DCns45Sb2XRbg=="],
|
||||||
|
|
||||||
|
"@polka/url": ["@polka/url@1.0.0-next.28", "", {}, "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.34.2", "", { "os": "android", "cpu": "arm" }, "sha512-6Fyg9yQbwJR+ykVdT9sid1oc2ewejS6h4wzQltmJfSW53N60G/ah9pngXGANdy9/aaE/TcUFpWosdm7JXS1WTQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.34.2", "", { "os": "android", "cpu": "arm64" }, "sha512-K5GfWe+vtQ3kyEbihrimM38UgX57UqHp+oME7X/EX9Im6suwZfa7Hsr8AtzbJvukTpwMGs+4s29YMSO3rwWtsw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.34.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PSN58XG/V/tzqDb9kDGutUruycgylMlUE59f40ny6QIRNsTEIZsrNQTJKUN2keMMSmlzgunMFqyaGLmly39sug=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.34.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-gQhK788rQJm9pzmXyfBB84VHViDERhAhzGafw+E5mUpnGKuxZGkMVDa3wgDFKT6ukLC5V7QTifzsUKdNVxp5qQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.34.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-eiaHgQwGPpxLC3+zTAcdKl4VsBl3r0AiJOd1Um/ArEzAjN/dbPK1nROHrVkdnoE6p7Svvn04w3f/jEZSTVHunA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.34.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-lhdiwQ+jf8pewYOTG4bag0Qd68Jn1v2gO1i0mTuiD+Qkt5vNfHVK/jrT7uVvycV8ZchlzXp5HDVmhpzjC6mh0g=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.34.2", "", { "os": "linux", "cpu": "arm" }, "sha512-lfqTpWjSvbgQP1vqGTXdv+/kxIznKXZlI109WkIFPbud41bjigjNmOAAKoazmRGx+k9e3rtIdbq2pQZPV1pMig=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.34.2", "", { "os": "linux", "cpu": "arm" }, "sha512-RGjqULqIurqqv+NJTyuPgdZhka8ImMLB32YwUle2BPTDqDoXNgwFjdjQC59FbSk08z0IqlRJjrJ0AvDQ5W5lpw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.34.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-ZvkPiheyXtXlFqHpsdgscx+tZ7hoR59vOettvArinEspq5fxSDSgfF+L5wqqJ9R4t+n53nyn0sKxeXlik7AY9Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.34.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UlFk+E46TZEoxD9ufLKDBzfSG7Ki03fo6hsNRRRHF+KuvNZ5vd1RRVQm8YZlGsjcJG8R252XFK0xNPay+4WV7w=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.34.2", "", { "os": "linux", "cpu": "none" }, "sha512-hJhfsD9ykx59jZuuoQgYT1GEcNNi3RCoEmbo5OGfG8RlHOiVS7iVNev9rhLKh7UBYq409f4uEw0cclTXx8nh8Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.34.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-g/O5IpgtrQqPegvqopvmdCF9vneLE7eqYfdPWW8yjPS8f63DNam3U4ARL1PNNB64XHZDHKpvO2Giftf43puB8Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.34.2", "", { "os": "linux", "cpu": "none" }, "sha512-bSQijDC96M6PuooOuXHpvXUYiIwsnDmqGU8+br2U7iPoykNi9JtMUpN7K6xml29e0evK0/g0D1qbAUzWZFHY5Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.34.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-49TtdeVAsdRuiUHXPrFVucaP4SivazetGUVH8CIxVsNsaPHV4PFkpLmH9LeqU/R4Nbgky9lzX5Xe1NrzLyraVA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.34.2", "", { "os": "linux", "cpu": "x64" }, "sha512-j+jFdfOycLIQ7FWKka9Zd3qvsIyugg5LeZuHF6kFlXo6MSOc6R1w37YUVy8VpAKd81LMWGi5g9J25P09M0SSIw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.34.2", "", { "os": "linux", "cpu": "x64" }, "sha512-aDPHyM/D2SpXfSNCVWCxyHmOqN9qb7SWkY1+vaXqMNMXslZYnwh9V/UCudl6psyG0v6Ukj7pXanIpfZwCOEMUg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.34.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-LQRkCyUBnAo7r8dbEdtNU08EKLCJMgAk2oP5H3R7BnUlKLqgR3dUjrLBVirmc1RK6U6qhtDw29Dimeer8d5hzQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.34.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-wt8OhpQUi6JuPFkm1wbVi1BByeag87LDFzeKSXzIdGcX4bMLqORTtKxLoCbV57BHYNSUSOKlSL4BYYUghainYA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.34.2", "", { "os": "win32", "cpu": "x64" }, "sha512-rUrqINax0TvrPBXrFKg0YbQx18NpPN3NNrgmaao9xRNbTwek7lOXObhx8tQy8gelmQ/gLaGy1WptpU2eKJZImg=="],
|
||||||
|
|
||||||
|
"@sveltejs/adapter-cloudflare": ["@sveltejs/adapter-cloudflare@5.0.2", "", { "dependencies": { "@cloudflare/workers-types": "^4.20241106.0", "esbuild": "^0.24.0", "worktop": "0.8.0-next.18" }, "peerDependencies": { "@sveltejs/kit": "^2.0.0", "wrangler": "^3.87.0" } }, "sha512-jlNRYFQ5mfmHmBqF79GhbFty/BTU+HZvgaT1uDREQmUcngT5j8yV85pxCOORl1r7rIVd0silRNBD5RJFsU5UUg=="],
|
||||||
|
|
||||||
|
"@sveltejs/kit": ["@sveltejs/kit@2.17.1", "", { "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", "devalue": "^5.1.0", "esm-env": "^1.2.2", "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0" }, "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-CpoGSLqE2MCmcQwA2CWJvOsZ9vW+p/1H3itrFykdgajUNAEyQPbsaSn7fZb6PLHQwe+07njxje9ss0fjZoCAyw=="],
|
||||||
|
|
||||||
|
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.0.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.0", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.15", "vitefu": "^1.0.4" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw=="],
|
||||||
|
|
||||||
|
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="],
|
||||||
|
|
||||||
|
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||||
|
|
||||||
|
"@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="],
|
||||||
|
|
||||||
|
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
|
||||||
|
|
||||||
|
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
|
||||||
|
|
||||||
|
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
|
"@types/leaflet": ["@types/leaflet@1.9.16", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-wzZoyySUxkgMZ0ihJ7IaUIblG8Rdc8AbbZKLneyn+QjYsj5q1QU7TEKYqwTr10BGSzY5LI7tJk9Ifo+mEjdFRw=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.23.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/type-utils": "8.23.0", "@typescript-eslint/utils": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.23.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/types": "8.23.0", "@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0" } }, "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.23.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.23.0", "@typescript-eslint/utils": "8.23.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/types": ["@typescript-eslint/types@8.23.0", "", {}, "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.8.0" } }, "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.23.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.23.0", "@typescript-eslint/types": "8.23.0", "@typescript-eslint/typescript-estree": "8.23.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.23.0", "", { "dependencies": { "@typescript-eslint/types": "8.23.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ=="],
|
||||||
|
|
||||||
|
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
|
||||||
|
|
||||||
|
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||||
|
|
||||||
|
"acorn-typescript": ["acorn-typescript@1.4.13", "", { "peerDependencies": { "acorn": ">=8.9.0" } }, "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q=="],
|
||||||
|
|
||||||
|
"acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="],
|
||||||
|
|
||||||
|
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||||
|
|
||||||
|
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||||
|
|
||||||
|
"arctic": ["arctic@3.2.2", "", { "dependencies": { "@oslojs/crypto": "1.0.1", "@oslojs/encoding": "1.1.0", "@oslojs/jwt": "0.2.0" } }, "sha512-wypdE8NnUOMbxsKtKGn57pEtt47EBvwVOFutGVmOPEHfg4nizOfVwl+yWpp7cUCkZJptuHh7hJixsrUhMOpusw=="],
|
||||||
|
|
||||||
|
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||||
|
|
||||||
|
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
||||||
|
|
||||||
|
"as-table": ["as-table@1.0.55", "", { "dependencies": { "printable-characters": "^1.0.42" } }, "sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ=="],
|
||||||
|
|
||||||
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
|
|
||||||
|
"blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="],
|
||||||
|
|
||||||
|
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
|
||||||
|
|
||||||
|
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||||
|
|
||||||
|
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||||
|
|
||||||
|
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||||
|
|
||||||
|
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
||||||
|
|
||||||
|
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||||
|
|
||||||
|
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||||
|
|
||||||
|
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||||
|
|
||||||
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
|
"confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
|
||||||
|
|
||||||
|
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
||||||
|
|
||||||
|
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||||
|
|
||||||
|
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
|
||||||
|
|
||||||
|
"data-uri-to-buffer": ["data-uri-to-buffer@2.0.2", "", {}, "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA=="],
|
||||||
|
|
||||||
|
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
|
||||||
|
|
||||||
|
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||||
|
|
||||||
|
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||||
|
|
||||||
|
"defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
|
||||||
|
|
||||||
|
"destr": ["destr@2.0.3", "", {}, "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ=="],
|
||||||
|
|
||||||
|
"devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="],
|
||||||
|
|
||||||
|
"esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="],
|
||||||
|
|
||||||
|
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||||
|
|
||||||
|
"eslint": ["eslint@9.19.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.10.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.19.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA=="],
|
||||||
|
|
||||||
|
"eslint-compat-utils": ["eslint-compat-utils@0.5.1", "", { "dependencies": { "semver": "^7.5.4" }, "peerDependencies": { "eslint": ">=6.0.0" } }, "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q=="],
|
||||||
|
|
||||||
|
"eslint-config-prettier": ["eslint-config-prettier@10.0.1", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "build/bin/cli.js" } }, "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw=="],
|
||||||
|
|
||||||
|
"eslint-plugin-svelte": ["eslint-plugin-svelte@2.46.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", "eslint-compat-utils": "^0.5.1", "esutils": "^2.0.3", "known-css-properties": "^0.35.0", "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.1.0", "semver": "^7.6.2", "svelte-eslint-parser": "^0.43.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw=="],
|
||||||
|
|
||||||
|
"eslint-scope": ["eslint-scope@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="],
|
||||||
|
|
||||||
|
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
|
||||||
|
|
||||||
|
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
||||||
|
|
||||||
|
"espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
|
||||||
|
|
||||||
|
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
||||||
|
|
||||||
|
"esrap": ["esrap@1.4.3", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-Xddc1RsoFJ4z9nR7W7BFaEPIp4UXoeQ0+077UdWLxbafMQFyU79sQJMk7kxNgRwQ9/aVgaKacCHC2pUACGwmYw=="],
|
||||||
|
|
||||||
|
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||||
|
|
||||||
|
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||||
|
|
||||||
|
"estree-walker": ["estree-walker@0.6.1", "", {}, "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="],
|
||||||
|
|
||||||
|
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||||
|
|
||||||
|
"exit-hook": ["exit-hook@2.2.1", "", {}, "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw=="],
|
||||||
|
|
||||||
|
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||||
|
|
||||||
|
"fast-glob": ["fast-glob@3.3.3", "", { "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" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
||||||
|
|
||||||
|
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||||
|
|
||||||
|
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||||
|
|
||||||
|
"fastq": ["fastq@1.19.0", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA=="],
|
||||||
|
|
||||||
|
"fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="],
|
||||||
|
|
||||||
|
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||||
|
|
||||||
|
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||||
|
|
||||||
|
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||||
|
|
||||||
|
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||||
|
|
||||||
|
"flatted": ["flatted@3.3.2", "", {}, "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA=="],
|
||||||
|
|
||||||
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
|
"get-source": ["get-source@2.0.12", "", { "dependencies": { "data-uri-to-buffer": "^2.0.0", "source-map": "^0.6.1" } }, "sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w=="],
|
||||||
|
|
||||||
|
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||||
|
|
||||||
|
"glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
|
||||||
|
|
||||||
|
"globals": ["globals@15.14.0", "", {}, "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig=="],
|
||||||
|
|
||||||
|
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
||||||
|
|
||||||
|
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||||
|
|
||||||
|
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||||
|
|
||||||
|
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||||
|
|
||||||
|
"import-meta-resolve": ["import-meta-resolve@4.1.0", "", {}, "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw=="],
|
||||||
|
|
||||||
|
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||||
|
|
||||||
|
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||||
|
|
||||||
|
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||||
|
|
||||||
|
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||||
|
|
||||||
|
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||||
|
|
||||||
|
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||||
|
|
||||||
|
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
|
||||||
|
|
||||||
|
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||||
|
|
||||||
|
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||||
|
|
||||||
|
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
||||||
|
|
||||||
|
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||||
|
|
||||||
|
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||||
|
|
||||||
|
"known-css-properties": ["known-css-properties@0.35.0", "", {}, "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A=="],
|
||||||
|
|
||||||
|
"leaflet": ["leaflet@1.9.4", "", {}, "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="],
|
||||||
|
|
||||||
|
"leaflet-defaulticon-compatibility": ["leaflet-defaulticon-compatibility@0.1.2", "", {}, "sha512-IrKagWxkTwzxUkFIumy/Zmo3ksjuAu3zEadtOuJcKzuXaD76Gwvg2Z1mLyx7y52ykOzM8rAH5ChBs4DnfdGa6Q=="],
|
||||||
|
|
||||||
|
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||||
|
|
||||||
|
"lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
|
||||||
|
|
||||||
|
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
||||||
|
|
||||||
|
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||||
|
|
||||||
|
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||||
|
|
||||||
|
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||||
|
|
||||||
|
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||||
|
|
||||||
|
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||||
|
|
||||||
|
"mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
|
||||||
|
|
||||||
|
"miniflare": ["miniflare@3.20250129.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "acorn": "^8.8.0", "acorn-walk": "^8.2.0", "exit-hook": "^2.2.1", "glob-to-regexp": "^0.4.1", "stoppable": "^1.1.0", "undici": "^5.28.4", "workerd": "1.20250129.0", "ws": "^8.18.0", "youch": "^3.2.2", "zod": "^3.22.3" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-qYlGEjMl/2kJdgNaztj4hpA64d6Dl79Lx/NL61p/v5XZRiWanBOTgkQqdPxCKZOj6KQnioqhC7lfd6jDXKSs2A=="],
|
||||||
|
|
||||||
|
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||||
|
|
||||||
|
"mlly": ["mlly@1.7.4", "", { "dependencies": { "acorn": "^8.14.0", "pathe": "^2.0.1", "pkg-types": "^1.3.0", "ufo": "^1.5.4" } }, "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw=="],
|
||||||
|
|
||||||
|
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||||
|
|
||||||
|
"mrmime": ["mrmime@2.0.0", "", {}, "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw=="],
|
||||||
|
|
||||||
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
|
"mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
|
||||||
|
|
||||||
|
"nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
|
||||||
|
|
||||||
|
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||||
|
|
||||||
|
"ohash": ["ohash@1.1.4", "", {}, "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g=="],
|
||||||
|
|
||||||
|
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||||
|
|
||||||
|
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||||
|
|
||||||
|
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||||
|
|
||||||
|
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||||
|
|
||||||
|
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||||
|
|
||||||
|
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||||
|
|
||||||
|
"path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="],
|
||||||
|
|
||||||
|
"pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
||||||
|
|
||||||
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
|
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
|
"pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
|
||||||
|
|
||||||
|
"postcss": ["postcss@8.5.1", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ=="],
|
||||||
|
|
||||||
|
"postcss-load-config": ["postcss-load-config@3.1.4", "", { "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg=="],
|
||||||
|
|
||||||
|
"postcss-safe-parser": ["postcss-safe-parser@6.0.0", "", { "peerDependencies": { "postcss": "^8.3.3" } }, "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ=="],
|
||||||
|
|
||||||
|
"postcss-scss": ["postcss-scss@4.0.9", "", { "peerDependencies": { "postcss": "^8.4.29" } }, "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A=="],
|
||||||
|
|
||||||
|
"postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
|
||||||
|
|
||||||
|
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||||
|
|
||||||
|
"prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="],
|
||||||
|
|
||||||
|
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.3.3", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw=="],
|
||||||
|
|
||||||
|
"printable-characters": ["printable-characters@1.0.42", "", {}, "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ=="],
|
||||||
|
|
||||||
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||||
|
|
||||||
|
"readdirp": ["readdirp@4.1.1", "", {}, "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw=="],
|
||||||
|
|
||||||
|
"regexparam": ["regexparam@3.0.0", "", {}, "sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q=="],
|
||||||
|
|
||||||
|
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||||
|
|
||||||
|
"reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="],
|
||||||
|
|
||||||
|
"rollup": ["rollup@4.34.2", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.34.2", "@rollup/rollup-android-arm64": "4.34.2", "@rollup/rollup-darwin-arm64": "4.34.2", "@rollup/rollup-darwin-x64": "4.34.2", "@rollup/rollup-freebsd-arm64": "4.34.2", "@rollup/rollup-freebsd-x64": "4.34.2", "@rollup/rollup-linux-arm-gnueabihf": "4.34.2", "@rollup/rollup-linux-arm-musleabihf": "4.34.2", "@rollup/rollup-linux-arm64-gnu": "4.34.2", "@rollup/rollup-linux-arm64-musl": "4.34.2", "@rollup/rollup-linux-loongarch64-gnu": "4.34.2", "@rollup/rollup-linux-powerpc64le-gnu": "4.34.2", "@rollup/rollup-linux-riscv64-gnu": "4.34.2", "@rollup/rollup-linux-s390x-gnu": "4.34.2", "@rollup/rollup-linux-x64-gnu": "4.34.2", "@rollup/rollup-linux-x64-musl": "4.34.2", "@rollup/rollup-win32-arm64-msvc": "4.34.2", "@rollup/rollup-win32-ia32-msvc": "4.34.2", "@rollup/rollup-win32-x64-msvc": "4.34.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-sBDUoxZEaqLu9QeNalL8v3jw6WjPku4wfZGyTU7l7m1oC+rpRihXc/n/H+4148ZkGz5Xli8CHMns//fFGKvpIQ=="],
|
||||||
|
|
||||||
|
"rollup-plugin-inject": ["rollup-plugin-inject@3.0.2", "", { "dependencies": { "estree-walker": "^0.6.1", "magic-string": "^0.25.3", "rollup-pluginutils": "^2.8.1" } }, "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w=="],
|
||||||
|
|
||||||
|
"rollup-plugin-node-polyfills": ["rollup-plugin-node-polyfills@0.2.1", "", { "dependencies": { "rollup-plugin-inject": "^3.0.0" } }, "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA=="],
|
||||||
|
|
||||||
|
"rollup-pluginutils": ["rollup-pluginutils@2.8.2", "", { "dependencies": { "estree-walker": "^0.6.1" } }, "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ=="],
|
||||||
|
|
||||||
|
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||||
|
|
||||||
|
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
||||||
|
|
||||||
|
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
||||||
|
|
||||||
|
"set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="],
|
||||||
|
|
||||||
|
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||||
|
|
||||||
|
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||||
|
|
||||||
|
"sirv": ["sirv@3.0.0", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg=="],
|
||||||
|
|
||||||
|
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||||
|
|
||||||
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
|
"sourcemap-codec": ["sourcemap-codec@1.4.8", "", {}, "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA=="],
|
||||||
|
|
||||||
|
"stacktracey": ["stacktracey@2.1.8", "", { "dependencies": { "as-table": "^1.0.36", "get-source": "^2.0.12" } }, "sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw=="],
|
||||||
|
|
||||||
|
"stoppable": ["stoppable@1.1.0", "", {}, "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="],
|
||||||
|
|
||||||
|
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||||
|
|
||||||
|
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||||
|
|
||||||
|
"svelte": ["svelte@5.19.7", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "acorn-typescript": "^1.4.13", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^1.4.3", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-I0UUp2MpB5gF8aqHJVklOcRcoLgQNnBolSwLMMqDepE9gVwmGeYBmJp1/obzae72QpxdPIymA4AunIm2x70LBg=="],
|
||||||
|
|
||||||
|
"svelte-check": ["svelte-check@4.1.4", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-v0j7yLbT29MezzaQJPEDwksybTE2Ups9rUxEXy92T06TiA0cbqcO8wAOwNUVkFW6B0hsYHA+oAX3BS8b/2oHtw=="],
|
||||||
|
|
||||||
|
"svelte-eslint-parser": ["svelte-eslint-parser@0.43.0", "", { "dependencies": { "eslint-scope": "^7.2.2", "eslint-visitor-keys": "^3.4.3", "espree": "^9.6.1", "postcss": "^8.4.39", "postcss-scss": "^4.0.9" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA=="],
|
||||||
|
|
||||||
|
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||||
|
|
||||||
|
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||||
|
|
||||||
|
"ts-api-utils": ["ts-api-utils@2.0.1", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w=="],
|
||||||
|
|
||||||
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
|
|
||||||
|
"typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
||||||
|
|
||||||
|
"typescript-eslint": ["typescript-eslint@8.23.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.23.0", "@typescript-eslint/parser": "8.23.0", "@typescript-eslint/utils": "8.23.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.8.0" } }, "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ=="],
|
||||||
|
|
||||||
|
"ufo": ["ufo@1.5.4", "", {}, "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ=="],
|
||||||
|
|
||||||
|
"undici": ["undici@5.28.5", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA=="],
|
||||||
|
|
||||||
|
"unenv": ["unenv@2.0.0-rc.1", "", { "dependencies": { "defu": "^6.1.4", "mlly": "^1.7.4", "ohash": "^1.1.4", "pathe": "^1.1.2", "ufo": "^1.5.4" } }, "sha512-PU5fb40H8X149s117aB4ytbORcCvlASdtF97tfls4BPIyj4PeVxvpSuy1jAptqYHqB0vb2w2sHvzM0XWcp2OKg=="],
|
||||||
|
|
||||||
|
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||||
|
|
||||||
|
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
||||||
|
|
||||||
|
"vite": ["vite@6.0.11", "", { "dependencies": { "esbuild": "^0.24.2", "postcss": "^8.4.49", "rollup": "^4.23.0" }, "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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg=="],
|
||||||
|
|
||||||
|
"vitefu": ["vitefu@1.0.5", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" }, "optionalPeers": ["vite"] }, "sha512-h4Vflt9gxODPFNGPwp4zAMZRpZR7eslzwH2c5hn5kNZ5rhnKyRJ50U+yGCdc2IRaBs8O4haIgLNGrV5CrpMsCA=="],
|
||||||
|
|
||||||
|
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||||
|
|
||||||
|
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||||
|
|
||||||
|
"workerd": ["workerd@1.20250129.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20250129.0", "@cloudflare/workerd-darwin-arm64": "1.20250129.0", "@cloudflare/workerd-linux-64": "1.20250129.0", "@cloudflare/workerd-linux-arm64": "1.20250129.0", "@cloudflare/workerd-windows-64": "1.20250129.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-Rprz8rxKTF4l6q/nYYI07lBetJnR19mGipx+u/a27GZOPKMG5SLIzA2NciZlJaB2Qd5YY+4p/eHOeKqo5keVWA=="],
|
||||||
|
|
||||||
|
"worktop": ["worktop@0.8.0-next.18", "", { "dependencies": { "mrmime": "^2.0.0", "regexparam": "^3.0.0" } }, "sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw=="],
|
||||||
|
|
||||||
|
"wrangler": ["wrangler@3.107.3", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.3.4", "@esbuild-plugins/node-globals-polyfill": "0.2.3", "@esbuild-plugins/node-modules-polyfill": "0.2.2", "blake3-wasm": "2.1.5", "esbuild": "0.17.19", "miniflare": "3.20250129.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.1", "workerd": "1.20250129.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20250129.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-N9ZMDHZ+DI5/B0yclr3bG57U/Zw7wSzGdpO2l7j6+3q8yUf+4Fk0Rvneo2t8rjLewKlvqgt9D9siFuo8MXJ55Q=="],
|
||||||
|
|
||||||
|
"ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
|
||||||
|
|
||||||
|
"yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
|
||||||
|
|
||||||
|
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||||
|
|
||||||
|
"youch": ["youch@3.3.4", "", { "dependencies": { "cookie": "^0.7.1", "mustache": "^4.2.0", "stacktracey": "^2.1.8" } }, "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg=="],
|
||||||
|
|
||||||
|
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
||||||
|
|
||||||
|
"zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
|
||||||
|
|
||||||
|
"@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
|
||||||
|
|
||||||
|
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
|
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||||
|
|
||||||
|
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||||
|
|
||||||
|
"@oslojs/jwt/@oslojs/encoding": ["@oslojs/encoding@0.4.1", "", {}, "sha512-hkjo6MuIK/kQR5CrGNdAPZhS01ZCXuWDRJ187zh6qqF2+yMHZpD9fAYpX8q2bOO6Ryhl3XpCT6kUX76N8hhm4Q=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
|
|
||||||
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|
||||||
|
"mlly/pathe": ["pathe@2.0.2", "", {}, "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w=="],
|
||||||
|
|
||||||
|
"pkg-types/pathe": ["pathe@2.0.2", "", {}, "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w=="],
|
||||||
|
|
||||||
|
"rollup-plugin-inject/magic-string": ["magic-string@0.25.9", "", { "dependencies": { "sourcemap-codec": "^1.4.8" } }, "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ=="],
|
||||||
|
|
||||||
|
"svelte-eslint-parser/eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="],
|
||||||
|
|
||||||
|
"svelte-eslint-parser/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
|
"svelte-eslint-parser/espree": ["espree@9.6.1", "", { "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } }, "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild": ["esbuild@0.17.19", "", { "optionalDependencies": { "@esbuild/android-arm": "0.17.19", "@esbuild/android-arm64": "0.17.19", "@esbuild/android-x64": "0.17.19", "@esbuild/darwin-arm64": "0.17.19", "@esbuild/darwin-x64": "0.17.19", "@esbuild/freebsd-arm64": "0.17.19", "@esbuild/freebsd-x64": "0.17.19", "@esbuild/linux-arm": "0.17.19", "@esbuild/linux-arm64": "0.17.19", "@esbuild/linux-ia32": "0.17.19", "@esbuild/linux-loong64": "0.17.19", "@esbuild/linux-mips64el": "0.17.19", "@esbuild/linux-ppc64": "0.17.19", "@esbuild/linux-riscv64": "0.17.19", "@esbuild/linux-s390x": "0.17.19", "@esbuild/linux-x64": "0.17.19", "@esbuild/netbsd-x64": "0.17.19", "@esbuild/openbsd-x64": "0.17.19", "@esbuild/sunos-x64": "0.17.19", "@esbuild/win32-arm64": "0.17.19", "@esbuild/win32-ia32": "0.17.19", "@esbuild/win32-x64": "0.17.19" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw=="],
|
||||||
|
|
||||||
|
"youch/cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
|
||||||
|
|
||||||
|
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.17.19", "", { "os": "android", "cpu": "arm" }, "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.17.19", "", { "os": "android", "cpu": "arm64" }, "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.17.19", "", { "os": "android", "cpu": "x64" }, "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.17.19", "", { "os": "darwin", "cpu": "arm64" }, "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.17.19", "", { "os": "darwin", "cpu": "x64" }, "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.17.19", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.17.19", "", { "os": "freebsd", "cpu": "x64" }, "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.17.19", "", { "os": "linux", "cpu": "arm" }, "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.17.19", "", { "os": "linux", "cpu": "arm64" }, "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.17.19", "", { "os": "linux", "cpu": "ia32" }, "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.17.19", "", { "os": "linux", "cpu": "none" }, "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.17.19", "", { "os": "linux", "cpu": "none" }, "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.17.19", "", { "os": "linux", "cpu": "ppc64" }, "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.17.19", "", { "os": "linux", "cpu": "none" }, "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.17.19", "", { "os": "linux", "cpu": "s390x" }, "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.17.19", "", { "os": "linux", "cpu": "x64" }, "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.17.19", "", { "os": "none", "cpu": "x64" }, "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.17.19", "", { "os": "openbsd", "cpu": "x64" }, "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.17.19", "", { "os": "sunos", "cpu": "x64" }, "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.17.19", "", { "os": "win32", "cpu": "arm64" }, "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.17.19", "", { "os": "win32", "cpu": "ia32" }, "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw=="],
|
||||||
|
|
||||||
|
"wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.17.19", "", { "os": "win32", "cpu": "x64" }, "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA=="],
|
||||||
|
}
|
||||||
|
}
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
48
flake.lock
generated
48
flake.lock
generated
|
@ -1,48 +0,0 @@
|
||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-parts": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs-lib": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1727826117,
|
|
||||||
"narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1729665710,
|
|
||||||
"narHash": "sha256-AlcmCXJZPIlO5dmFzV3V2XF6x/OpNWUV8Y/FMPGd8Z4=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "2768c7d042a37de65bb1b5b3268fc987e534c49d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-parts": "flake-parts",
|
|
||||||
"nixpkgs": "nixpkgs"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
28
flake.nix
28
flake.nix
|
@ -1,28 +0,0 @@
|
||||||
{
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
|
|
||||||
flake-parts = {
|
|
||||||
url = "github:hercules-ci/flake-parts";
|
|
||||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = {flake-parts, ...} @ inputs:
|
|
||||||
flake-parts.lib.mkFlake {inherit inputs;} {
|
|
||||||
systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"];
|
|
||||||
|
|
||||||
perSystem = {
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
devShells.default = with pkgs;
|
|
||||||
mkShellNoCC {
|
|
||||||
buildInputs = [bun wrangler];
|
|
||||||
};
|
|
||||||
|
|
||||||
formatter = pkgs.alejandra;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
12
migrations/0001_init.sql
Normal file
12
migrations/0001_init.sql
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
-- Migration number: 0001 2024-11-19T11:13:32.513Z
|
||||||
|
CREATE TABLE user (
|
||||||
|
`id` VARCHAR(32) NOT NULL PRIMARY KEY,
|
||||||
|
`name` VARCHAR(32) NOT NULL,
|
||||||
|
`avatar_hash` VARCHAR(32) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE session (
|
||||||
|
`id` TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`user_id` VARCHAR(32) NOT NULL REFERENCES user(id),
|
||||||
|
`expires_at` INTEGER NOT NULL
|
||||||
|
);
|
19
migrations/0002_add_scores_tables.sql
Normal file
19
migrations/0002_add_scores_tables.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
-- Migration number: 0002 2024-11-21T10:59:43.394Z
|
||||||
|
CREATE TABLE game (
|
||||||
|
`id` TEXT PRIMARY KEY, -- uuid
|
||||||
|
`user_id` TEXT NOT NULL,
|
||||||
|
`mode` TEXT NOT NULL,
|
||||||
|
`time` INTEGER NOT NULL,
|
||||||
|
`total_score` INTEGER NOT NULL,
|
||||||
|
FOREIGN KEY(user_id) REFERENCES user(id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table round (
|
||||||
|
`id` INTEGER PRIMARY KEY ASC, -- rowid alias, should be automatically assigned
|
||||||
|
`game_id` TEXT NOT NULL,
|
||||||
|
`points` INTEGER NOT NULL,
|
||||||
|
`distance` INTEGER NOT NULL,
|
||||||
|
`stop_name` TEXT NOT NULL,
|
||||||
|
FOREIGN KEY(game_id) REFERENCES game(id)
|
||||||
|
);
|
||||||
|
|
2
migrations/0003_add_stops_type_column.sql
Normal file
2
migrations/0003_add_stops_type_column.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
-- Migration number: 0003 2024-11-21T20:19:29.020Z
|
||||||
|
ALTER TABLE game ADD COLUMN `stops_type` TEXT NOT NULL DEFAULT "metro";
|
44
migrations/0004_fix_tables.sql
Normal file
44
migrations/0004_fix_tables.sql
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
-- Migration number: 0004 2024-11-25T09:05:22.577Z
|
||||||
|
CREATE TABLE user_tmp (
|
||||||
|
`id` TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`name` TEXT NOT NULL,
|
||||||
|
`avatar_hash` TEXT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE session_tmp (
|
||||||
|
`id` TEXT NOT NULL PRIMARY KEY,
|
||||||
|
`user_id` TEXT NOT NULL REFERENCES user_tmp(id),
|
||||||
|
`expires_at` INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE game_tmp (
|
||||||
|
`id` TEXT NOT NULL PRIMARY KEY, -- uuid
|
||||||
|
`user_id` TEXT NULL REFERENCES user_tmp(id),
|
||||||
|
`mode` TEXT NOT NULL,
|
||||||
|
`time` INTEGER NOT NULL,
|
||||||
|
`total_score` INTEGER NOT NULL,
|
||||||
|
`stops_type` TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE round_tmp (
|
||||||
|
`id` INTEGER PRIMARY KEY ASC, -- rowid alias, should be automatically assigned
|
||||||
|
`game_id` TEXT NOT NULL REFERENCES game_tmp(id),
|
||||||
|
`points` INTEGER NOT NULL,
|
||||||
|
`distance` INTEGER NOT NULL,
|
||||||
|
`stop_name` TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO user_tmp(id, name, avatar_hash) SELECT id, name, avatar_hash FROM user;
|
||||||
|
INSERT INTO session_tmp(id, user_id, expires_at) SELECT id, user_id, expires_at FROM session;
|
||||||
|
INSERT INTO game_tmp(id, user_id, mode, time, total_score, stops_type) SELECT id, user_id, mode, time, total_score, stops_type FROM game;
|
||||||
|
INSERT INTO round_tmp(id, game_id, points, distance, stop_name) SELECT id, game_id, points, distance, stop_name FROM round;
|
||||||
|
|
||||||
|
DROP TABLE round;
|
||||||
|
DROP TABLE game;
|
||||||
|
DROP TABLE session;
|
||||||
|
DROP TABLE user;
|
||||||
|
|
||||||
|
ALTER TABLE user_tmp RENAME TO user;
|
||||||
|
ALTER TABLE session_tmp RENAME TO session;
|
||||||
|
ALTER TABLE game_tmp RENAME TO game;
|
||||||
|
ALTER TABLE round_tmp RENAME TO round;
|
42
package.json
42
package.json
|
@ -12,30 +12,32 @@
|
||||||
"format": "prettier --write ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fontsource-variable/inter": "^5.1.1",
|
||||||
|
"@oslojs/crypto": "^1.0.1",
|
||||||
|
"@oslojs/encoding": "^1.1.0",
|
||||||
|
"arctic": "^3.2.2",
|
||||||
|
"destr": "^2.0.3",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"leaflet-defaulticon-compatibility": "^0.1.2"
|
"leaflet-defaulticon-compatibility": "^0.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cloudflare/workers-types": "^4.20241022.0",
|
"@cloudflare/workers-types": "^4.20250129.0",
|
||||||
"@sveltejs/adapter-cloudflare": "^4.7.4",
|
"@sveltejs/adapter-cloudflare": "^5.0.2",
|
||||||
"@sveltejs/kit": "^2.7.3",
|
"@sveltejs/kit": "^2.17.1",
|
||||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
||||||
"@types/eslint": "^9.6.1",
|
"@types/eslint": "^9.6.1",
|
||||||
"@types/leaflet": "^1.9.14",
|
"@types/leaflet": "^1.9.16",
|
||||||
"eslint": "^9.13.0",
|
"eslint": "^9.19.0",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^10.0.1",
|
||||||
"eslint-plugin-svelte": "^2.46.0",
|
"eslint-plugin-svelte": "^2.46.1",
|
||||||
"globals": "^15.11.0",
|
"globals": "^15.14.0",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.4.2",
|
||||||
"prettier-plugin-svelte": "^3.2.7",
|
"prettier-plugin-svelte": "^3.3.3",
|
||||||
"svelte": "^5.1.2",
|
"svelte": "^5.19.7",
|
||||||
"svelte-check": "^4.0.5",
|
"svelte-check": "^4.1.4",
|
||||||
"typescript": "^5.6.3",
|
"typescript": "^5.7.3",
|
||||||
"typescript-eslint": "^8.11.0",
|
"typescript-eslint": "^8.23.0",
|
||||||
"vite": "^5.4.10"
|
"vite": "^6.0.11"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module"
|
||||||
"patchedDependencies": {
|
|
||||||
"@sveltejs/adapter-cloudflare@4.7.4": "patches/@sveltejs%2Fadapter-cloudflare@4.7.4.patch"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
diff --git a/index.js b/index.js
|
|
||||||
index 0fe55898e5697fc6a061299780e163ca4553cb05..e9fb7fea0082c7d3df7b07df21bd99cca6c4957c 100644
|
|
||||||
--- a/index.js
|
|
||||||
+++ b/index.js
|
|
||||||
@@ -144,29 +144,33 @@ export default function (options = {}) {
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
- async emulate() {
|
|
||||||
- const proxy = await getPlatformProxy(options.platformProxy);
|
|
||||||
- const platform = /** @type {App.Platform} */ ({
|
|
||||||
- env: proxy.env,
|
|
||||||
- context: proxy.ctx,
|
|
||||||
- caches: proxy.caches,
|
|
||||||
- cf: proxy.cf
|
|
||||||
- });
|
|
||||||
+ emulate() {
|
|
||||||
+ const getting_platform = (async () => {
|
|
||||||
+ const proxy = await getPlatformProxy(options.platformProxy);
|
|
||||||
+ const platform = /** @type {App.Platform} */ ({
|
|
||||||
+ env: proxy.env,
|
|
||||||
+ context: proxy.ctx,
|
|
||||||
+ caches: proxy.caches,
|
|
||||||
+ cf: proxy.cf
|
|
||||||
+ });
|
|
||||||
|
|
||||||
- /** @type {Record<string, any>} */
|
|
||||||
- const env = {};
|
|
||||||
- const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env }));
|
|
||||||
+ /** @type {Record<string, any>} */
|
|
||||||
+ const env = {};
|
|
||||||
+ const prerender_platform = /** @type {App.Platform} */ (/** @type {unknown} */ ({ env }));
|
|
||||||
|
|
||||||
- for (const key in proxy.env) {
|
|
||||||
- Object.defineProperty(env, key, {
|
|
||||||
- get: () => {
|
|
||||||
- throw new Error(`Cannot access platform.env.${key} in a prerenderable route`);
|
|
||||||
- }
|
|
||||||
- });
|
|
||||||
- }
|
|
||||||
+ for (const key in proxy.env) {
|
|
||||||
+ Object.defineProperty(env, key, {
|
|
||||||
+ get: () => {
|
|
||||||
+ throw new Error(`Cannot access platform.env.${key} in a prerenderable route`);
|
|
||||||
+ }
|
|
||||||
+ });
|
|
||||||
+ }
|
|
||||||
+ return { platform, prerender_platform };
|
|
||||||
+ })();
|
|
||||||
|
|
||||||
return {
|
|
||||||
- platform: ({ prerender }) => {
|
|
||||||
+ platform: async ({ prerender }) => {
|
|
||||||
+ const { platform, prerender_platform } = await getting_platform;
|
|
||||||
return prerender ? prerender_platform : platform;
|
|
||||||
}
|
|
||||||
};
|
|
10
shell.nix
Normal file
10
shell.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
pkgs ? import <nixpkgs> { },
|
||||||
|
}:
|
||||||
|
pkgs.mkShellNoCC {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
bun
|
||||||
|
nodejs
|
||||||
|
wrangler
|
||||||
|
];
|
||||||
|
}
|
42
src/app.css
Normal file
42
src/app.css
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
@import "@fontsource-variable/inter";
|
||||||
|
@import "@fontsource-variable/inter/wght-italic.css";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--background-color: white;
|
||||||
|
--text-color: black;
|
||||||
|
--accent-color: #0077b8;
|
||||||
|
color-scheme: light;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
:root {
|
||||||
|
--background-color: #16191d;
|
||||||
|
--text-color: #f8f9fa;
|
||||||
|
--accent-color: #a5d8ff;
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: "Inter Variable", sans-serif;
|
||||||
|
background-color: var(--background-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--accent-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contents {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
max-width: 70ch;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
}
|
9
src/app.d.ts
vendored
9
src/app.d.ts
vendored
|
@ -1,14 +1,19 @@
|
||||||
|
import type { Session, User } from "$lib/auth";
|
||||||
|
|
||||||
// See https://kit.svelte.dev/docs/types#app
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
declare global {
|
declare global {
|
||||||
namespace App {
|
namespace App {
|
||||||
// interface Error {}
|
// interface Error {}
|
||||||
// interface Locals {}
|
|
||||||
// interface PageData {}
|
// interface PageData {}
|
||||||
// interface PageState {}
|
// interface PageState {}
|
||||||
|
interface Locals {
|
||||||
|
user: User | null;
|
||||||
|
session: Session | null;
|
||||||
|
}
|
||||||
interface Platform {
|
interface Platform {
|
||||||
env?: {
|
env?: {
|
||||||
TCL_GUESSR_KV: KVNamespace;
|
TCL_GUESSR_D1: D1Database;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/app.html
18
src/app.html
|
@ -2,19 +2,17 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
<link rel="icon" href="%sveltekit.assets%/favicon.avif" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<meta name="og:title" content="TCL-Guessr" />
|
||||||
|
<meta name="og:type" content="website" />
|
||||||
|
<meta name="og:image" content="/logo.png" />
|
||||||
|
<meta name="theme-color" content="#ff0000" />
|
||||||
|
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-preload-data="hover">
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
<div class="contents">%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<style>
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</html>
|
</html>
|
||||||
|
|
25
src/hooks.server.ts
Normal file
25
src/hooks.server.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { deleteSessionTokenCookie, setSessionTokenCookie } from "$lib/auth/cookie";
|
||||||
|
import { validateSessionToken } from "$lib/auth/session";
|
||||||
|
import type { Handle } from "@sveltejs/kit";
|
||||||
|
|
||||||
|
export const handle: Handle = async ({ event, resolve }) => {
|
||||||
|
const db = event.platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||||
|
const token = event.cookies.get("session") ?? null;
|
||||||
|
|
||||||
|
if (db === null || token === null) {
|
||||||
|
event.locals.session = null;
|
||||||
|
event.locals.user = null;
|
||||||
|
return resolve(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { session, user } = await validateSessionToken(token, db);
|
||||||
|
if (session !== null) {
|
||||||
|
setSessionTokenCookie(event.cookies, token, session.expiresAt);
|
||||||
|
} else {
|
||||||
|
deleteSessionTokenCookie(event.cookies);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.locals.session = session;
|
||||||
|
event.locals.user = user;
|
||||||
|
return resolve(event);
|
||||||
|
};
|
19
src/lib/auth/cookie.ts
Normal file
19
src/lib/auth/cookie.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import type { Cookies } from "@sveltejs/kit";
|
||||||
|
|
||||||
|
export function setSessionTokenCookie(cookies: Cookies, token: string, expiresAt: Date): void {
|
||||||
|
cookies.set("session", token, {
|
||||||
|
httpOnly: true,
|
||||||
|
sameSite: "lax",
|
||||||
|
expires: expiresAt,
|
||||||
|
path: "/",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deleteSessionTokenCookie(cookies: Cookies): void {
|
||||||
|
cookies.set("session", "", {
|
||||||
|
httpOnly: true,
|
||||||
|
sameSite: "lax",
|
||||||
|
maxAge: 0,
|
||||||
|
path: "/",
|
||||||
|
});
|
||||||
|
}
|
15
src/lib/auth/discord.ts
Normal file
15
src/lib/auth/discord.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Discord } from "arctic";
|
||||||
|
import { DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET } from "$env/static/private";
|
||||||
|
import { PUBLIC_BASE_URL } from "$env/static/public";
|
||||||
|
|
||||||
|
export interface DiscordUser {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
avatar: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const discord = new Discord(
|
||||||
|
DISCORD_CLIENT_ID,
|
||||||
|
DISCORD_CLIENT_SECRET,
|
||||||
|
`${PUBLIC_BASE_URL}/login/callback`,
|
||||||
|
);
|
21
src/lib/auth/index.ts
Normal file
21
src/lib/auth/index.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
export type SessionValidationResult =
|
||||||
|
| { session: Session; user: User }
|
||||||
|
| { session: null; user: null };
|
||||||
|
|
||||||
|
export interface Session {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
expiresAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
avatarHash: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CookieData {
|
||||||
|
state: string;
|
||||||
|
codeVerifier: string;
|
||||||
|
next: string;
|
||||||
|
}
|
86
src/lib/auth/session.ts
Normal file
86
src/lib/auth/session.ts
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from "@oslojs/encoding";
|
||||||
|
import { sha256 } from "@oslojs/crypto/sha2";
|
||||||
|
import type { Session, SessionValidationResult, User } from ".";
|
||||||
|
|
||||||
|
interface ValidateResponse {
|
||||||
|
id: string;
|
||||||
|
user_id: string;
|
||||||
|
expires_at: number;
|
||||||
|
name: string;
|
||||||
|
avatar_hash: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateSessionToken(): string {
|
||||||
|
const bytes = new Uint8Array(40);
|
||||||
|
crypto.getRandomValues(bytes);
|
||||||
|
return encodeBase32LowerCaseNoPadding(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createSession(
|
||||||
|
token: string,
|
||||||
|
userId: string,
|
||||||
|
db: D1Database,
|
||||||
|
): Promise<Session> {
|
||||||
|
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
||||||
|
const session: Session = {
|
||||||
|
id: sessionId,
|
||||||
|
userId,
|
||||||
|
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), // 7 days
|
||||||
|
};
|
||||||
|
|
||||||
|
await db
|
||||||
|
.prepare("INSERT INTO session (id, user_id, expires_at) VALUES (?, ?, ?)")
|
||||||
|
.bind(session.id, session.userId, Math.floor(session.expiresAt.getTime() / 1000))
|
||||||
|
.run();
|
||||||
|
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function validateSessionToken(
|
||||||
|
token: string,
|
||||||
|
db: D1Database,
|
||||||
|
): Promise<SessionValidationResult> {
|
||||||
|
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
||||||
|
|
||||||
|
const row = await db
|
||||||
|
.prepare(
|
||||||
|
"SELECT session.id, session.user_id, session.expires_at, user.name, user.avatar_hash FROM session INNER JOIN user ON user.id = session.user_id WHERE session.id = ?",
|
||||||
|
)
|
||||||
|
.bind(sessionId)
|
||||||
|
.first<ValidateResponse>();
|
||||||
|
|
||||||
|
if (row === null) return { session: null, user: null };
|
||||||
|
|
||||||
|
const session: Session = {
|
||||||
|
id: row.id,
|
||||||
|
userId: row.user_id,
|
||||||
|
expiresAt: new Date(row.expires_at * 1000),
|
||||||
|
};
|
||||||
|
|
||||||
|
const user: User = {
|
||||||
|
id: row.user_id,
|
||||||
|
name: row.name,
|
||||||
|
avatarHash: row.avatar_hash,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Date.now() >= session.expiresAt.getTime()) {
|
||||||
|
await invalidateSession(sessionId, db);
|
||||||
|
return { session: null, user: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
// if less than 3 days left
|
||||||
|
if (Date.now() >= session.expiresAt.getTime() - 1000 * 60 * 60 * 24 * 3) {
|
||||||
|
session.expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24 * 7); // 7 days
|
||||||
|
|
||||||
|
await db
|
||||||
|
.prepare("UPDATE session SET expires_at = ? WHERE id = ?")
|
||||||
|
.bind(Math.floor(session.expiresAt.getTime() / 1000), session.id)
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
return { session, user };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function invalidateSession(sessionId: string, db: D1Database): Promise<void> {
|
||||||
|
await db.prepare("DELETE FROM session WHERE id = ?").bind(sessionId).run();
|
||||||
|
}
|
107
src/lib/index.ts
107
src/lib/index.ts
|
@ -1,7 +1,5 @@
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
import type { CheckResponse, ClientGameData, GameOptions, ServerGameData } from "./types";
|
import type { CheckResponse, ClientGameData, GameOptions } from "./types";
|
||||||
|
|
||||||
type FetchType = typeof fetch;
|
|
||||||
|
|
||||||
const metroUrl =
|
const metroUrl =
|
||||||
"https://data.grandlyon.com/geoserver/sytral/ows?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=sytral:tcl_sytral.tcllignemf_2_0_0&outputFormat=application/json&SRSNAME=EPSG:4171&sortBy=gid";
|
"https://data.grandlyon.com/geoserver/sytral/ows?SERVICE=WFS&VERSION=2.0.0&request=GetFeature&typename=sytral:tcl_sytral.tcllignemf_2_0_0&outputFormat=application/json&SRSNAME=EPSG:4171&sortBy=gid";
|
||||||
|
@ -15,21 +13,26 @@ let lazyTram: [GeoJSON.Feature, string][] | null = null;
|
||||||
let lazyStops: GeoJSON.Feature[] | null = null;
|
let lazyStops: GeoJSON.Feature[] | null = null;
|
||||||
|
|
||||||
export async function createGame(
|
export async function createGame(
|
||||||
|
userId: string | null,
|
||||||
mode: string,
|
mode: string,
|
||||||
|
stopsType: string,
|
||||||
stops: GeoJSON.Feature[],
|
stops: GeoJSON.Feature[],
|
||||||
kv: KVNamespace<string>,
|
db: D1Database,
|
||||||
): Promise<ClientGameData> {
|
): Promise<ClientGameData> {
|
||||||
const uuid = crypto.randomUUID();
|
const uuid = crypto.randomUUID();
|
||||||
const stopNames = stops.map((s) => s.properties!.nom);
|
const stopNames = stops.map((s) => s.properties!.nom);
|
||||||
|
|
||||||
const serverData: ServerGameData = {
|
const gameSql = db
|
||||||
mode,
|
.prepare(
|
||||||
stops,
|
"INSERT INTO game (id, user_id, mode, stops_type, time, total_score) VALUES (?, ?, ?, ?, unixepoch('now'), 0)",
|
||||||
distances: new Array(stops.length).fill(-1),
|
)
|
||||||
scores: new Array(stops.length).fill(-1),
|
.bind(uuid, userId, mode, stopsType);
|
||||||
};
|
|
||||||
|
|
||||||
await kv.put(`game:${uuid}`, JSON.stringify(serverData), { expirationTtl: 600 });
|
const roundSql = db.prepare(
|
||||||
|
"INSERT INTO round (game_id, points, distance, stop_name) VALUES (?, -1, -1, ?)",
|
||||||
|
);
|
||||||
|
|
||||||
|
await db.batch([gameSql, ...stopNames.map((s) => roundSql.bind(uuid, s))]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
gameId: uuid,
|
gameId: uuid,
|
||||||
|
@ -39,36 +42,46 @@ export async function createGame(
|
||||||
|
|
||||||
export async function saveScore(
|
export async function saveScore(
|
||||||
uuid: string,
|
uuid: string,
|
||||||
index: number,
|
stopName: string,
|
||||||
distanceCalc: (latlng: [number, number]) => number,
|
distanceCalc: (latlng: [number, number]) => number,
|
||||||
scoreCalc: (dist: number) => number,
|
scoreCalc: (dist: number) => number,
|
||||||
kv: KVNamespace<string>,
|
db: D1Database,
|
||||||
): Promise<CheckResponse | null> {
|
): Promise<CheckResponse | null> {
|
||||||
const serverData: ServerGameData | null = await kv.get(`game:${uuid}`, "json");
|
const row = await db
|
||||||
if (!serverData) return null;
|
.prepare(
|
||||||
|
"SELECT round.id, round.stop_name, round.points, game.stops_type FROM round INNER JOIN game ON game.id = round.game_id WHERE round.game_id = ? AND round.stop_name = ?",
|
||||||
|
)
|
||||||
|
.bind(uuid, stopName)
|
||||||
|
.first();
|
||||||
|
|
||||||
if (serverData.scores[index] != -1) {
|
if (row === null || row.points !== -1) return null;
|
||||||
return null;
|
|
||||||
} else {
|
const type = row.stops_type as "metro" | "tram";
|
||||||
const coords = (serverData.stops[index].geometry as GeoJSON.Point).coordinates;
|
const stops = (await getMergedStops(type)).filter((f) => f.properties?.nom === stopName);
|
||||||
|
|
||||||
|
if (stops.length === 0) return null;
|
||||||
|
|
||||||
|
const coords = (stops[0].geometry as GeoJSON.Point).coordinates;
|
||||||
const latlng: [number, number] = [coords[1], coords[0]];
|
const latlng: [number, number] = [coords[1], coords[0]];
|
||||||
|
|
||||||
const distance = Math.round(distanceCalc(latlng));
|
const distance = Math.round(distanceCalc(latlng));
|
||||||
const score = Math.round(scoreCalc(distance));
|
const score = Math.round(scoreCalc(distance));
|
||||||
|
|
||||||
serverData.distances[index] = distance;
|
await db.batch([
|
||||||
serverData.scores[index] = score;
|
db
|
||||||
await kv.put(`game:${uuid}`, JSON.stringify(serverData), { expirationTtl: 600 });
|
.prepare("UPDATE round SET points = ?, distance = ? WHERE id = ?")
|
||||||
|
.bind(score, distance, row.id),
|
||||||
|
db.prepare("UPDATE game SET total_score = total_score + ? WHERE id = ?").bind(score, uuid),
|
||||||
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
distance,
|
distance,
|
||||||
score,
|
score,
|
||||||
solution: latlng,
|
solution: latlng,
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMetro(fetch: FetchType): Promise<[GeoJSON.Feature, string][]> {
|
export async function getMetro(): Promise<[GeoJSON.Feature, string][]> {
|
||||||
if (!lazyMetro) {
|
if (!lazyMetro) {
|
||||||
const metro: GeoJSON.FeatureCollection = await fetch(metroUrl).then((r) => r.json());
|
const metro: GeoJSON.FeatureCollection = await fetch(metroUrl).then((r) => r.json());
|
||||||
|
|
||||||
|
@ -81,7 +94,7 @@ export async function getMetro(fetch: FetchType): Promise<[GeoJSON.Feature, stri
|
||||||
return lazyMetro;
|
return lazyMetro;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTram(fetch: FetchType): Promise<[GeoJSON.Feature, string][]> {
|
export async function getTram(): Promise<[GeoJSON.Feature, string][]> {
|
||||||
if (!lazyTram) {
|
if (!lazyTram) {
|
||||||
const tram: GeoJSON.FeatureCollection = await fetch(tramUrl).then((r) => r.json());
|
const tram: GeoJSON.FeatureCollection = await fetch(tramUrl).then((r) => r.json());
|
||||||
|
|
||||||
|
@ -94,7 +107,22 @@ export async function getTram(fetch: FetchType): Promise<[GeoJSON.Feature, strin
|
||||||
return lazyTram;
|
return lazyTram;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getStops(fetch: FetchType): Promise<GeoJSON.Feature[]> {
|
async function getLineCodes(stopsType: "metro" | "tram"): Promise<Set<string>> {
|
||||||
|
let lines;
|
||||||
|
|
||||||
|
switch (stopsType) {
|
||||||
|
case "metro":
|
||||||
|
lines = await getMetro();
|
||||||
|
break;
|
||||||
|
case "tram":
|
||||||
|
lines = await getTram();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Set<string>(lines.map(([f]) => f.properties!.code_ligne));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStops(): Promise<GeoJSON.Feature[]> {
|
||||||
if (!lazyStops) {
|
if (!lazyStops) {
|
||||||
const stops: GeoJSON.FeatureCollection = await fetch(stopsUrl).then((r) => r.json());
|
const stops: GeoJSON.FeatureCollection = await fetch(stopsUrl).then((r) => r.json());
|
||||||
lazyStops = stops.features;
|
lazyStops = stops.features;
|
||||||
|
@ -103,11 +131,9 @@ async function getStops(fetch: FetchType): Promise<GeoJSON.Feature[]> {
|
||||||
return lazyStops;
|
return lazyStops;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMergedStops(
|
export async function getMergedStops(stopsType: "metro" | "tram"): Promise<GeoJSON.Feature[]> {
|
||||||
fetch: FetchType,
|
const stops = await getStops();
|
||||||
lineCodes: Set<string>,
|
const lineCodes = await getLineCodes(stopsType);
|
||||||
): Promise<GeoJSON.Feature[]> {
|
|
||||||
const stops = await getStops(fetch);
|
|
||||||
|
|
||||||
const crossingStops = stops.filter((f) => {
|
const crossingStops = stops.filter((f) => {
|
||||||
if (f.properties?.desserte) {
|
if (f.properties?.desserte) {
|
||||||
|
@ -133,9 +159,11 @@ export async function getMergedStops(
|
||||||
|
|
||||||
const desserte = matching.map((f) => f.properties?.desserte).join(",");
|
const desserte = matching.map((f) => f.properties?.desserte).join(",");
|
||||||
|
|
||||||
const feature = matching[0];
|
const feature: GeoJSON.Feature = {
|
||||||
feature.geometry = { type: "Point", coordinates: [lonAvg, latAvg] };
|
...matching[0],
|
||||||
if (feature.properties) feature.properties.desserte = desserte;
|
geometry: { type: "Point", coordinates: [lonAvg, latAvg] },
|
||||||
|
properties: { ...matching[0].properties, desserte },
|
||||||
|
};
|
||||||
|
|
||||||
return feature;
|
return feature;
|
||||||
},
|
},
|
||||||
|
@ -150,11 +178,12 @@ export function parseOptions(url: URL): GameOptions {
|
||||||
error(400, "gamemode is invalid");
|
error(400, "gamemode is invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const stopsType = url.searchParams.get("stops_type");
|
||||||
mode,
|
if (stopsType !== "metro" && stopsType !== "tram") {
|
||||||
metro: url.searchParams.has("metro"),
|
error(400, "stops_type is invalid");
|
||||||
tram: url.searchParams.has("tram"),
|
}
|
||||||
};
|
|
||||||
|
return { mode, stopsType };
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://underscorejs.org/docs/modules/sample.html
|
// https://underscorejs.org/docs/modules/sample.html
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
export interface GameOptions {
|
export interface GameOptions {
|
||||||
mode: "easy" | "hard" | "extreme demon ultra miguel";
|
mode: "easy" | "hard" | "extreme demon ultra miguel";
|
||||||
metro: boolean;
|
stopsType: "metro" | "tram";
|
||||||
tram: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MapData {
|
export interface MapData {
|
||||||
|
@ -9,13 +8,6 @@ export interface MapData {
|
||||||
stops: [number, number][];
|
stops: [number, number][];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServerGameData {
|
|
||||||
mode: string;
|
|
||||||
stops: GeoJSON.Feature[];
|
|
||||||
distances: number[];
|
|
||||||
scores: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ClientGameData {
|
export interface ClientGameData {
|
||||||
stopNames: string[];
|
stopNames: string[];
|
||||||
gameId: string;
|
gameId: string;
|
||||||
|
@ -23,7 +15,7 @@ export interface ClientGameData {
|
||||||
|
|
||||||
export interface CheckData {
|
export interface CheckData {
|
||||||
gameId: string;
|
gameId: string;
|
||||||
index: number;
|
stopName: string;
|
||||||
latlng: [number, number];
|
latlng: [number, number];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
5
src/routes/+layout.svelte
Normal file
5
src/routes/+layout.svelte
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<script>
|
||||||
|
import "../app.css";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<slot />
|
5
src/routes/+page.server.ts
Normal file
5
src/routes/+page.server.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import type { PageServerLoad } from "./$types";
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ locals }) => {
|
||||||
|
return { user: locals.user };
|
||||||
|
};
|
|
@ -1,10 +1,40 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { PageData } from "./$types";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
data: PageData;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<svelte:head>
|
||||||
<h1>TCL-Guessr</h1>
|
<title>TCL-Guessr</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<form action="/game" method="GET">
|
<h1><img src="/logo.avif" alt="tcl-guessr logo" width="240" height="240" /></h1>
|
||||||
|
|
||||||
|
<div class="login">
|
||||||
|
{#if props.data.user === null}
|
||||||
|
<a href="/login">Se connecter</a>
|
||||||
|
{:else}
|
||||||
|
Connecté en tant que <img
|
||||||
|
src={`https://cdn.discordapp.com/avatars/${props.data.user.id}/${props.data.user.avatarHash}.webp?size=64`}
|
||||||
|
alt="avatar"
|
||||||
|
class="pfp"
|
||||||
|
width="32"
|
||||||
|
height="32"
|
||||||
|
/> <b>{props.data.user.name}</b> - <a href="logout">Se déconnecter</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2><a href="/leaderboard">Meilleurs scores</a></h2>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h2>Jouer</h2>
|
||||||
|
|
||||||
|
<form action="/game" method="GET">
|
||||||
<label>
|
<label>
|
||||||
difficulté: <select name="mode">
|
difficulté: <select name="mode">
|
||||||
<option value="easy">Facile (pour les nuls)</option>
|
<option value="easy">Facile (pour les nuls)</option>
|
||||||
|
@ -15,28 +45,46 @@
|
||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div>
|
<label>
|
||||||
<label>metro: <input type="checkbox" name="metro" checked /></label>
|
arrets: <select name="stops_type">
|
||||||
<label>tram: <input type="checkbox" name="tram" /></label>
|
<option value="metro">Métro</option>
|
||||||
</div>
|
<option value="tram">Tram</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
<input type="submit" value="LANCER LA PARTIE" />
|
<input type="submit" class="start" value="LANCER LA PARTIE" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
img {
|
||||||
padding: 16px;
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pfp {
|
||||||
|
border-radius: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
form {
|
form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
width: fit-content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="submit"] {
|
label {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -4,23 +4,23 @@ import type { RequestHandler } from "./$types";
|
||||||
import type { CheckData } from "$lib/types";
|
import type { CheckData } from "$lib/types";
|
||||||
|
|
||||||
export const POST: RequestHandler = async ({ request, platform }) => {
|
export const POST: RequestHandler = async ({ request, platform }) => {
|
||||||
const kv = platform?.env?.TCL_GUESSR_KV;
|
const db = platform?.env?.TCL_GUESSR_D1;
|
||||||
if (!kv) error(500, "could not connect to kv");
|
if (!db) error(500, "could not connect to d1");
|
||||||
|
|
||||||
const data: CheckData = await request.json();
|
const data: CheckData = await request.json();
|
||||||
|
|
||||||
const solution = await saveScore(
|
const solution = await saveScore(
|
||||||
data.gameId,
|
data.gameId,
|
||||||
data.index,
|
data.stopName,
|
||||||
(solution) => calcDistance(data.latlng, solution),
|
(solution) => calcDistance(data.latlng, solution),
|
||||||
(distance) => calculatePoints(distance),
|
(distance) => calculatePoints(distance),
|
||||||
kv,
|
db,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (solution) {
|
if (solution) {
|
||||||
return Response.json(solution);
|
return Response.json(solution);
|
||||||
} else {
|
} else {
|
||||||
return new Response(null, { status: 404 });
|
return error(404);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,22 @@
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
import type { RequestHandler } from "./$types";
|
import type { RequestHandler } from "./$types";
|
||||||
import { createGame, getMergedStops, getMetro, getTram, parseOptions, sample } from "$lib";
|
import { createGame, getMergedStops, parseOptions, sample } from "$lib";
|
||||||
|
|
||||||
export const GET: RequestHandler = async ({ fetch, url, platform }) => {
|
export const GET: RequestHandler = async ({ url, platform, locals }) => {
|
||||||
const kv = platform?.env?.TCL_GUESSR_KV;
|
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||||
if (!kv) error(500, "could not connect to kv");
|
if (db === null) error(500, "could not connect to d1");
|
||||||
|
|
||||||
|
const userId = locals.user?.id ?? null;
|
||||||
const options = parseOptions(url);
|
const options = parseOptions(url);
|
||||||
const lineColors: [GeoJSON.Feature, string][] = [];
|
|
||||||
|
|
||||||
if (options.metro) lineColors.push(...(await getMetro(fetch)));
|
const crossingStops = await getMergedStops(options.stopsType);
|
||||||
if (options.tram) lineColors.push(...(await getTram(fetch)));
|
|
||||||
|
|
||||||
const lineCodes = new Set<string>(lineColors.map(([f]) => f.properties!.code_ligne));
|
|
||||||
const crossingStops = await getMergedStops(fetch, lineCodes);
|
|
||||||
|
|
||||||
const randomStops = sample(crossingStops, 5);
|
const randomStops = sample(crossingStops, 5);
|
||||||
if (!randomStops) {
|
if (!randomStops) {
|
||||||
error(400, "could not select random stop");
|
error(400, "could not select random stop");
|
||||||
}
|
}
|
||||||
|
|
||||||
const gameData = await createGame(options.mode, randomStops, kv);
|
const gameData = await createGame(userId, options.mode, options.stopsType, randomStops, db);
|
||||||
|
|
||||||
return Response.json(gameData);
|
return Response.json(gameData);
|
||||||
};
|
};
|
||||||
|
|
19
src/routes/api/leaderboard/+server.ts
Normal file
19
src/routes/api/leaderboard/+server.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { parseOptions } from "$lib";
|
||||||
|
import { error } from "@sveltejs/kit";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ url, platform }) => {
|
||||||
|
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||||
|
if (db === null) error(500, "could not connect to d1");
|
||||||
|
|
||||||
|
const options = parseOptions(url);
|
||||||
|
|
||||||
|
const { results } = await db
|
||||||
|
.prepare(
|
||||||
|
"SELECT game.id, max(game.total_score) AS total_score, user.name FROM game INNER JOIN user ON user.id = game.user_id WHERE game.mode = ? AND game.stops_type = ? GROUP BY game.user_id ORDER BY game.total_score DESC, game.time ASC LIMIT 10",
|
||||||
|
)
|
||||||
|
.bind(options.mode, options.stopsType)
|
||||||
|
.all();
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(results));
|
||||||
|
};
|
|
@ -2,21 +2,22 @@ import { getMergedStops, getMetro, getTram, parseOptions } from "$lib";
|
||||||
import type { MapData } from "$lib/types";
|
import type { MapData } from "$lib/types";
|
||||||
import type { RequestHandler } from "./$types";
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
export const GET: RequestHandler = async ({ fetch, url }) => {
|
export const GET: RequestHandler = async ({ url }) => {
|
||||||
const options = parseOptions(url);
|
const options = parseOptions(url);
|
||||||
const mapData: MapData = { lines: [], stops: [] };
|
const mapData: MapData = { lines: [], stops: [] };
|
||||||
|
|
||||||
if (options.mode !== "extreme demon ultra miguel") {
|
if (options.mode !== "extreme demon ultra miguel") {
|
||||||
const lineColors: [GeoJSON.Feature, string][] = [];
|
switch (options.stopsType) {
|
||||||
|
case "metro":
|
||||||
if (options.metro) lineColors.push(...(await getMetro(fetch)));
|
mapData.lines = await getMetro();
|
||||||
if (options.tram) lineColors.push(...(await getTram(fetch)));
|
break;
|
||||||
|
case "tram":
|
||||||
mapData.lines = lineColors;
|
mapData.lines = await getTram();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (options.mode === "easy") {
|
if (options.mode === "easy") {
|
||||||
const lineCodes = new Set<string>(lineColors.map(([f]) => f.properties!.code_ligne));
|
const crossingStops = await getMergedStops(options.stopsType);
|
||||||
const crossingStops = await getMergedStops(fetch, lineCodes);
|
|
||||||
|
|
||||||
const strippedStops: [number, number][] = crossingStops.map((f) => {
|
const strippedStops: [number, number][] = crossingStops.map((f) => {
|
||||||
const coords = (f.geometry as GeoJSON.Point).coordinates;
|
const coords = (f.geometry as GeoJSON.Point).coordinates;
|
||||||
|
|
16
src/routes/api/save/+server.ts
Normal file
16
src/routes/api/save/+server.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { error, redirect } from "@sveltejs/kit";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ locals, platform, url }) => {
|
||||||
|
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||||
|
if (db === null) error(500, "could not connect to d1");
|
||||||
|
|
||||||
|
const gameId = url.searchParams.get("id") ?? null;
|
||||||
|
if (gameId === null) error(400, "no game id specified");
|
||||||
|
|
||||||
|
if (locals.user === null) error(401);
|
||||||
|
|
||||||
|
await db.prepare("UPDATE game SET user_id = ? WHERE id = ?").bind(locals.user.id, gameId).run();
|
||||||
|
|
||||||
|
redirect(302, `/results?gameId=${gameId}`);
|
||||||
|
};
|
|
@ -1,18 +1,22 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { CheckData, CheckResponse, ClientGameData, MapData } from "$lib/types";
|
import type { CheckData, CheckResponse, ClientGameData, MapData } from "$lib/types";
|
||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
|
import { onMount } from "svelte";
|
||||||
import L from "leaflet";
|
import L from "leaflet";
|
||||||
|
|
||||||
import "leaflet/dist/leaflet.css";
|
import "leaflet/dist/leaflet.css";
|
||||||
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
|
import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css";
|
||||||
import "leaflet-defaulticon-compatibility";
|
import "leaflet-defaulticon-compatibility";
|
||||||
import { goto } from "$app/navigation";
|
|
||||||
|
|
||||||
const zoom = 13;
|
const zoom = 13;
|
||||||
const center: [number, number] = [45.742858495, 4.86163814];
|
const center: [number, number] = [45.742858495, 4.86163814];
|
||||||
|
|
||||||
|
const metroIcon = new L.Icon({ iconUrl: "/metro.svg", iconSize: [29, 15] });
|
||||||
|
const tramIcon = new L.Icon({ iconUrl: "/tram.svg", iconSize: [29, 15] });
|
||||||
|
|
||||||
let mapPromise = $state(fetchMap());
|
let mapPromise = $state(fetchMap());
|
||||||
let gamePromise = $state(fetchGame());
|
let gamePromise = $state(fetchGame());
|
||||||
|
let isChecking = $state(false);
|
||||||
let results: CheckResponse | null = $state(null);
|
let results: CheckResponse | null = $state(null);
|
||||||
|
|
||||||
let currentIndex = $state(0);
|
let currentIndex = $state(0);
|
||||||
|
@ -22,6 +26,15 @@
|
||||||
let solutionMarker: L.Marker | null = $state(null);
|
let solutionMarker: L.Marker | null = $state(null);
|
||||||
let solutionLine: L.Polyline | null = $state(null);
|
let solutionLine: L.Polyline | null = $state(null);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
window.addEventListener("beforeunload", async (e) => {
|
||||||
|
const gameData = await gamePromise;
|
||||||
|
if (gameData.stopNames.length > currentIndex + 1) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
async function fetchMap(): Promise<MapData> {
|
async function fetchMap(): Promise<MapData> {
|
||||||
return fetch("/api/map?" + $page.url.searchParams).then((r) => r.json());
|
return fetch("/api/map?" + $page.url.searchParams).then((r) => r.json());
|
||||||
}
|
}
|
||||||
|
@ -43,8 +56,10 @@
|
||||||
mapData.lines.forEach(([feature, color]) => {
|
mapData.lines.forEach(([feature, color]) => {
|
||||||
L.geoJSON(feature, { style: { color } }).addTo(map!);
|
L.geoJSON(feature, { style: { color } }).addTo(map!);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const icon = $page.url.searchParams.get("stops_type") === "tram" ? tramIcon : metroIcon;
|
||||||
mapData.stops.forEach((coords) => {
|
mapData.stops.forEach((coords) => {
|
||||||
const marker = L.marker(coords).addTo(map!);
|
const marker = L.marker(coords, { icon }).addTo(map!);
|
||||||
marker.on("click", (e) => setMarker(e.latlng));
|
marker.on("click", (e) => setMarker(e.latlng));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -58,22 +73,19 @@
|
||||||
|
|
||||||
function setMarker(pos: L.LatLng) {
|
function setMarker(pos: L.LatLng) {
|
||||||
if (map && !results) {
|
if (map && !results) {
|
||||||
if (playerMarker) {
|
playerMarker = (playerMarker ?? L.marker(pos).addTo(map)).setLatLng(pos);
|
||||||
playerMarker = playerMarker.setLatLng(pos);
|
|
||||||
} else {
|
|
||||||
playerMarker = L.marker(pos).addTo(map);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkLocation() {
|
async function checkLocation() {
|
||||||
if (!playerMarker || results) return;
|
if (!playerMarker || results || isChecking) return;
|
||||||
|
isChecking = true;
|
||||||
|
|
||||||
const gameData = await gamePromise;
|
const gameData = await gamePromise;
|
||||||
|
|
||||||
const checkData: CheckData = {
|
const checkData: CheckData = {
|
||||||
gameId: gameData.gameId,
|
gameId: gameData.gameId,
|
||||||
index: currentIndex,
|
stopName: gameData.stopNames[currentIndex],
|
||||||
latlng: [playerMarker.getLatLng().lat, playerMarker.getLatLng().lng],
|
latlng: [playerMarker.getLatLng().lat, playerMarker.getLatLng().lng],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,8 +110,10 @@
|
||||||
.addTo(map)
|
.addTo(map)
|
||||||
.openPopup();
|
.openPopup();
|
||||||
} else {
|
} else {
|
||||||
alert("it seems than an error occurred");
|
alert(`une erreur est survenue: ${response.status} ${await response.text()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isChecking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function restartGame() {
|
async function restartGame() {
|
||||||
|
@ -119,44 +133,52 @@
|
||||||
results = null;
|
results = null;
|
||||||
|
|
||||||
if (gameData.stopNames.length <= currentIndex + 1) {
|
if (gameData.stopNames.length <= currentIndex + 1) {
|
||||||
goto("/results?" + new URLSearchParams({ gameId: gameData.gameId }));
|
window.location.href = "/results?" + new URLSearchParams({ gameId: gameData.gameId });
|
||||||
} else {
|
} else {
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<svelte:head>
|
||||||
{#await Promise.all([mapPromise, gamePromise])}
|
<title>TCL-Guessr</title>
|
||||||
<h1>Loading...</h1>
|
</svelte:head>
|
||||||
|
|
||||||
<div><button disabled>Loading...</button></div>
|
{#await Promise.all([mapPromise, gamePromise])}
|
||||||
{:then [, gameData]}
|
<h1>Chargement...</h1>
|
||||||
|
|
||||||
|
<div><button disabled>Chargement...</button></div>
|
||||||
|
{:then [, gameData]}
|
||||||
<h1>{gameData.stopNames[currentIndex]}</h1>
|
<h1>{gameData.stopNames[currentIndex]}</h1>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
{#if results === null}
|
{#if results === null}
|
||||||
<button onclick={checkLocation} disabled={!playerMarker}>SUBMIT</button>
|
<button onclick={checkLocation} disabled={!playerMarker || isChecking}>VÉRIFIER</button>
|
||||||
{:else}
|
{:else}
|
||||||
<button onclick={restartGame}>NEXT</button>
|
<button onclick={restartGame}>SUIVANT</button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
{/await}
|
{/await}
|
||||||
|
|
||||||
<span class="results" hidden={!results}>
|
<span class="results" hidden={!results}>
|
||||||
{results?.score} points! Vous etiez à {results?.distance}m.
|
{results?.score} points! Vous etiez à {results?.distance}m.
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
:global(body),
|
||||||
display: flex;
|
:global(html) {
|
||||||
flex-direction: column;
|
margin: 0;
|
||||||
gap: 8px;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
text-align: center;
|
}
|
||||||
|
|
||||||
|
:global(.contents) {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.results {
|
.results {
|
||||||
|
|
110
src/routes/leaderboard/+page.svelte
Normal file
110
src/routes/leaderboard/+page.svelte
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
<script lang="ts">
|
||||||
|
interface LeaderboardGame {
|
||||||
|
id: string;
|
||||||
|
total_score: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mode = $state("extreme demon ultra miguel");
|
||||||
|
let stopsType = $state("metro");
|
||||||
|
let leaderboardPromise = $derived(fetchLeaderboard(mode, stopsType));
|
||||||
|
|
||||||
|
async function fetchLeaderboard(mode: string, stops_type: string): Promise<LeaderboardGame[]> {
|
||||||
|
const params = new URLSearchParams({ mode, stops_type });
|
||||||
|
return await fetch("/api/leaderboard?" + params).then((r) => r.json());
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<meta name="og:description" content="Tableau des scores" />
|
||||||
|
<title>Tableau des scores</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<h1>Tableau des scores</h1>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
Mode: <select name="mode" bind:value={mode}>
|
||||||
|
<option value="easy">Facile (pour les nuls)</option>
|
||||||
|
<option value="hard">Dur (pour les gigaillards)</option>
|
||||||
|
<option value="extreme demon ultra miguel" selected>
|
||||||
|
EXTREME DEMON ULTRA MIGUEL DE LA MORT QUI TUE
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
- Arrêts:
|
||||||
|
<select name="stops_type" bind:value={stopsType}>
|
||||||
|
<option value="metro" selected>Métro</option>
|
||||||
|
<option value="tram">Tram</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
{#await leaderboardPromise}
|
||||||
|
<h2>Chargement...</h2>
|
||||||
|
{:then games}
|
||||||
|
{#if games.length === 0}
|
||||||
|
<h2>No scores yet :(</h2>
|
||||||
|
{:else}
|
||||||
|
<ul>
|
||||||
|
{#each games as game}
|
||||||
|
<li class:rainbow={game.total_score === 25000}>
|
||||||
|
<b>{game.total_score}</b> points par {game.name} -
|
||||||
|
<a href="/results?gameId={game.id}">Détails</a>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
<a href="/">Page principale</a>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
ul {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rainbow {
|
||||||
|
animation: rainbow 5s linear;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rainbow {
|
||||||
|
100%,
|
||||||
|
0% {
|
||||||
|
color: rgb(255, 0, 0);
|
||||||
|
}
|
||||||
|
8% {
|
||||||
|
color: rgb(255, 127, 0);
|
||||||
|
}
|
||||||
|
16% {
|
||||||
|
color: rgb(255, 255, 0);
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
color: rgb(127, 255, 0);
|
||||||
|
}
|
||||||
|
33% {
|
||||||
|
color: rgb(0, 255, 0);
|
||||||
|
}
|
||||||
|
41% {
|
||||||
|
color: rgb(0, 255, 127);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
color: rgb(0, 255, 255);
|
||||||
|
}
|
||||||
|
58% {
|
||||||
|
color: rgb(0, 127, 255);
|
||||||
|
}
|
||||||
|
66% {
|
||||||
|
color: rgb(0, 0, 255);
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
color: rgb(127, 0, 255);
|
||||||
|
}
|
||||||
|
83% {
|
||||||
|
color: rgb(255, 0, 255);
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
color: rgb(255, 0, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
25
src/routes/login/+server.ts
Normal file
25
src/routes/login/+server.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { redirect } from "@sveltejs/kit";
|
||||||
|
import { generateCodeVerifier, generateState } from "arctic";
|
||||||
|
import { discord } from "$lib/auth/discord";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
import type { CookieData } from "$lib/auth";
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ cookies, url }) => {
|
||||||
|
const cookie: CookieData = {
|
||||||
|
state: generateState(),
|
||||||
|
codeVerifier: generateCodeVerifier(),
|
||||||
|
next: url.searchParams.get("next") ?? "/",
|
||||||
|
};
|
||||||
|
|
||||||
|
const scopes = ["identify"];
|
||||||
|
const authUrl = discord.createAuthorizationURL(cookie.state, cookie.codeVerifier, scopes);
|
||||||
|
|
||||||
|
cookies.set("discord_oauth_state", JSON.stringify(cookie), {
|
||||||
|
path: "/",
|
||||||
|
httpOnly: true,
|
||||||
|
maxAge: 60 * 10,
|
||||||
|
sameSite: "lax",
|
||||||
|
});
|
||||||
|
|
||||||
|
redirect(302, authUrl);
|
||||||
|
};
|
55
src/routes/login/callback/+server.ts
Normal file
55
src/routes/login/callback/+server.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { error, redirect } from "@sveltejs/kit";
|
||||||
|
import { discord, type DiscordUser } from "$lib/auth/discord";
|
||||||
|
import { OAuth2RequestError, type OAuth2Tokens } from "arctic";
|
||||||
|
import { createSession, generateSessionToken } from "$lib/auth/session";
|
||||||
|
import { setSessionTokenCookie } from "$lib/auth/cookie";
|
||||||
|
import { destr } from "destr";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
import type { CookieData } from "$lib/auth";
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ platform, url, cookies, fetch }) => {
|
||||||
|
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||||
|
if (db === null) error(500, "could not access D1");
|
||||||
|
|
||||||
|
const code = url.searchParams.get("code");
|
||||||
|
const state = url.searchParams.get("state");
|
||||||
|
const cookie = destr<CookieData>(cookies.get("discord_oauth_state")) ?? null;
|
||||||
|
|
||||||
|
if (code === null || state === null || cookie === null) {
|
||||||
|
error(400, "missing things from oauth2 response");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state !== cookie.state) {
|
||||||
|
error(400, "state does not match");
|
||||||
|
}
|
||||||
|
|
||||||
|
let tokens: OAuth2Tokens;
|
||||||
|
try {
|
||||||
|
tokens = await discord.validateAuthorizationCode(code, cookie.codeVerifier);
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof OAuth2RequestError) {
|
||||||
|
error(400, e.message);
|
||||||
|
} else {
|
||||||
|
error(400, "could not validate auth code");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const discordUser: DiscordUser = await fetch("https://discord.com/api/v10/users/@me", {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${tokens.accessToken()}`,
|
||||||
|
},
|
||||||
|
}).then((r) => r.json());
|
||||||
|
|
||||||
|
await db
|
||||||
|
.prepare(
|
||||||
|
"INSERT INTO user(id, name, avatar_hash) VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET name=excluded.name, avatar_hash=excluded.avatar_hash;",
|
||||||
|
)
|
||||||
|
.bind(discordUser.id, discordUser.username, discordUser.avatar)
|
||||||
|
.run();
|
||||||
|
|
||||||
|
const sessionToken = generateSessionToken();
|
||||||
|
const session = await createSession(sessionToken, discordUser.id, db);
|
||||||
|
setSessionTokenCookie(cookies, sessionToken, session.expiresAt);
|
||||||
|
|
||||||
|
redirect(302, cookie.next);
|
||||||
|
};
|
16
src/routes/logout/+server.ts
Normal file
16
src/routes/logout/+server.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { invalidateSession } from "$lib/auth/session";
|
||||||
|
import { redirect } from "@sveltejs/kit";
|
||||||
|
import type { RequestHandler } from "./$types";
|
||||||
|
|
||||||
|
export const GET: RequestHandler = async ({ platform, locals }) => {
|
||||||
|
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||||
|
|
||||||
|
if (locals.session !== null && db !== null) {
|
||||||
|
await invalidateSession(locals.session.id, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
locals.session = null;
|
||||||
|
locals.user = null;
|
||||||
|
|
||||||
|
redirect(302, "/");
|
||||||
|
};
|
|
@ -1,16 +1,29 @@
|
||||||
import type { PageServerLoad } from "./$types";
|
import type { PageServerLoad } from "./$types";
|
||||||
import { error } from "@sveltejs/kit";
|
import { error } from "@sveltejs/kit";
|
||||||
import type { ServerGameData } from "$lib/types";
|
|
||||||
|
|
||||||
export const load: PageServerLoad = async ({ url, platform }) => {
|
interface JoinedRoundScore {
|
||||||
const kv = platform?.env?.TCL_GUESSR_KV;
|
mode: string;
|
||||||
if (!kv) error(500, "could not connect to kv");
|
stops_type: string;
|
||||||
|
total_score: number;
|
||||||
|
name: string;
|
||||||
|
points: number;
|
||||||
|
distance: number;
|
||||||
|
stop_name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const load: PageServerLoad = async ({ locals, url, platform }) => {
|
||||||
|
const db = platform?.env?.TCL_GUESSR_D1;
|
||||||
|
if (!db) error(500, "could not connect to d1");
|
||||||
|
|
||||||
const gameId = url.searchParams.get("gameId");
|
const gameId = url.searchParams.get("gameId");
|
||||||
if (!gameId) error(400, "gameId was not specified");
|
if (!gameId) error(400, "gameId was not specified");
|
||||||
|
|
||||||
const gameData: ServerGameData | null = await kv.get(`game:${gameId}`, "json");
|
const { results } = await db
|
||||||
if (!gameData) error(404, "could not fetch game data");
|
.prepare(
|
||||||
|
"SELECT game.mode, game.stops_type, game.total_score, user.name, round.points, round.distance, round.stop_name FROM game INNER JOIN round ON round.game_id = game.id LEFT JOIN user ON user.id = game.user_id WHERE game.id = ?;",
|
||||||
|
)
|
||||||
|
.bind(gameId)
|
||||||
|
.all<JoinedRoundScore>();
|
||||||
|
|
||||||
return { gameData, gameId };
|
return { rounds: results, gameId, loggedIn: locals.user !== null };
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from "$app/navigation";
|
|
||||||
import type { PageData } from "./$types";
|
import type { PageData } from "./$types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
@ -7,45 +6,57 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const props: Props = $props();
|
const props: Props = $props();
|
||||||
const gameData = props.data.gameData;
|
|
||||||
|
|
||||||
const totalScore = gameData.scores.reduce((a, b) => a + b);
|
const totalScore = props.data.rounds[0].total_score;
|
||||||
|
const mode = props.data.rounds[0].mode;
|
||||||
|
const stops_type = props.data.rounds[0].stops_type;
|
||||||
|
const name = props.data.rounds[0].name;
|
||||||
|
|
||||||
|
const saveParams = new URLSearchParams({ next: `/api/save?id=${props.data.gameId}` });
|
||||||
|
const restartParams = new URLSearchParams({ mode, stops_type });
|
||||||
|
const ogDesc = `${totalScore} points par ${name ?? "inconnu"} - Difficulté: ${mode} - Arrêts: ${stops_type}`;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="container">
|
<svelte:head>
|
||||||
<h1>yippee !!!</h1>
|
<meta name="og:description" content={ogDesc} />
|
||||||
|
<title>TCL-Guessr - Résultats</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
<h2>score total: {totalScore}</h2>
|
<h1>Score total: {totalScore}</h1>
|
||||||
|
|
||||||
<span>mode: {gameData.mode}</span>
|
<span>Mode: <b>{mode}</b> - Arrêts: <b>{stops_type}</b></span>
|
||||||
|
|
||||||
<table>
|
{#if name !== null}
|
||||||
|
<span>Joué par {name}</span>
|
||||||
|
{:else if props.data.loggedIn}
|
||||||
|
<span>Joué par <i>un inconnu...</i></span>
|
||||||
|
{:else}
|
||||||
|
<span><a href="/login?{saveParams}">Connectez vous</a> pour sauvegarder votre score!</span>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each gameData.stops as stop, i}
|
{#each props.data.rounds as round}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{stop.properties!.nom}</td>
|
<td>{round.stop_name}</td>
|
||||||
<td>{gameData.scores[i]} points</td>
|
<td><b>{round.points}</b> points</td>
|
||||||
<td>{gameData.distances[i]} metres</td>
|
<td>{round.distance} mètres</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<span class="small">id de partie: {props.data.gameId}</span>
|
<span class="small">id de partie: {props.data.gameId}</span>
|
||||||
|
|
||||||
<button class="restart" onclick={() => goto("/")}>RELANCER !!!</button>
|
<h2>
|
||||||
</div>
|
<a href="/">Page principale</a> -
|
||||||
|
<a href="/game?{restartParams}">Relancer une partie</a> -
|
||||||
|
<a href="/leaderboard">Meilleurs scores</a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
td {
|
||||||
border: 1px solid black;
|
border: 1px solid var(--text-color);
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,9 +65,4 @@
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: darkgray;
|
color: darkgray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.restart {
|
|
||||||
width: 600px;
|
|
||||||
height: 75px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
BIN
static/favicon.avif
Normal file
BIN
static/favicon.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
BIN
static/logo.avif
Normal file
BIN
static/logo.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
static/logo.png
Normal file
BIN
static/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 195 KiB |
21
static/metro.svg
Normal file
21
static/metro.svg
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="138" height="72" id="svg2" version="1.1" inkscape:version="0.48.1 " sodipodi:docname="_logo-generic.svg">
|
||||||
|
<defs id="defs4"/>
|
||||||
|
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="5.6568542" inkscape:cx="65.794397" inkscape:cy="47.944674" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1280" inkscape:window-height="968" inkscape:window-x="-4" inkscape:window-y="-4" inkscape:window-maximized="1"/>
|
||||||
|
<metadata id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<dc:title/>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g inkscape:groupmode="layer" id="layer1" inkscape:label="Calque">
|
||||||
|
<flowRoot xml:space="preserve" id="flowRoot2988" style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion id="flowRegion2990"><rect id="rect2992" width="60" height="46" x="9" y="9"/></flowRegion><flowPara id="flowPara2994"/></flowRoot> <path style="fill:#ee1c25;fill-opacity:1;stroke:none" d="M 10.306041,-9.708713e-5 128,0 c 11.1875,18.5 10,36 10,36 0,0 0.82757,18.63169 -10,36 l -117.702238,9.7e-5 c -11.5644706,-18.863868 -9.93826201,-36 -9.93826201,-36 0,0 -1.91764309,-16.028869 9.94654101,-36.00019408713 z" id="rect3764" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccc"/>
|
||||||
|
<g transform="translate(-7.7333374,1.1003853)" style="font-size:70px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Confluence;-inkscape-font-specification:Confluence Bold" id="flowRoot3766">
|
||||||
|
<path d="m 51.363037,9.3035893 -1.890564,53.6920167 10.010376,0 0.350342,-38.430786 1.540222,5.039367 10.00824,33.391419 10.010376,0 9.801025,-32.620239 1.749573,-5.810547 0.350342,38.430786 10.010371,0 -1.82006,-53.5510255 -12.531132,0 -11.409606,36.7495725 c -0.420159,1.399959 -0.677219,2.379775 -0.77118,2.939453 -0.0926,0.747694 -0.162386,1.587944 -0.20935,2.520752 l -0.209351,0 c -0.09403,-1.213366 -0.187309,-2.099901 -0.279846,-2.659607 -0.09403,-0.700669 -0.351086,-1.680485 -0.771179,-2.939453 L 63.892029,9.3035893 z" style="" id="path3784"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3 KiB |
21
static/tram.svg
Normal file
21
static/tram.svg
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="138" height="72" id="svg2" version="1.1" inkscape:version="0.48.1 " sodipodi:docname="lyon tcl logo-metro-full.svg">
|
||||||
|
<defs id="defs4"/>
|
||||||
|
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="5.6568542" inkscape:cx="65.794397" inkscape:cy="47.944674" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1280" inkscape:window-height="968" inkscape:window-x="-4" inkscape:window-y="-4" inkscape:window-maximized="1"/>
|
||||||
|
<metadata id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<dc:title/>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g inkscape:groupmode="layer" id="layer1" inkscape:label="Calque">
|
||||||
|
<flowRoot xml:space="preserve" id="flowRoot2988" style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"><flowRegion id="flowRegion2990"><rect id="rect2992" width="60" height="46" x="9" y="9"/></flowRegion><flowPara id="flowPara2994"/></flowRoot> <path style="fill:#ee1c25;fill-opacity:1;stroke:none" d="M 10.306041,-9.708713e-5 128,0 c 11.1875,18.5 10,36 10,36 0,0 0.82757,18.63169 -10,36 l -117.702238,9.7e-5 c -11.5644706,-18.863868 -9.93826201,-36 -9.93826201,-36 0,0 -1.91764309,-16.028869 9.94654101,-36.00019408713 z" id="rect3764" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccc"/>
|
||||||
|
<g transform="translate(-7.7333374,1.1003853)" style="font-size:70px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Confluence;-inkscape-font-specification:Confluence Bold" id="flowRoot3766">
|
||||||
|
<path d="m 72.112244,17.214051 0,45.640564 9.170837,0 0,-45.640564 14.13971,0 0,-7.9104617 -37.450257,0 0,7.9104617 z" style="" id="path3787"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
|
@ -2,6 +2,7 @@ name = "tcl-guessr"
|
||||||
compatibility_date = "2024-09-25"
|
compatibility_date = "2024-09-25"
|
||||||
pages_build_output_dir = ".svelte-kit/cloudflare"
|
pages_build_output_dir = ".svelte-kit/cloudflare"
|
||||||
|
|
||||||
[[kv_namespaces]]
|
[[d1_databases]]
|
||||||
binding = "TCL_GUESSR_KV"
|
binding = "TCL_GUESSR_D1"
|
||||||
id = "b2d8980ac3a74a80854c35bf9569dbf8"
|
database_name = "tcl-guessr"
|
||||||
|
database_id = "dd6fbdf0-5ede-4226-9787-4fbe15a46caa"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue