data endpoint for entity 90008 (aka. a website)

Compare changes

Choose any two refs to compare.

Changed files
+8874 -5305
.forgejo
workflows
eunomia
src
static
nix
src
static
-28
.forgejo/workflows/build.yaml
···
-
name: build website
-
-
on:
-
push:
-
workflow_dispatch:
-
-
jobs:
-
build:
-
runs-on: lixpine
-
steps:
-
- uses: actions/checkout@v4
-
with:
-
github-server-url: 'https://git.gaze.systems'
-
- uses: https://github.com/cachix/cachix-action@v16
-
with:
-
name: gazesys-infra
-
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
-
- run: nix show-config
-
- run: nix build . -L --show-trace
-
deploy:
-
runs-on: lixpine
-
needs: build
-
steps:
-
- name: trigger deploy
-
env:
-
PAT: ${{ secrets.PAT }}
-
run: |
-
curl -X POST "https://git.gaze.systems/api/v1/repos/90008/ark/actions/workflows/deploy.yaml/dispatches" -H "Accept: application/json" -H "Authorization: token $PAT" --json '{"ref": "terra"}'
-1
.gitattributes
···
-
+10 -9
.gitignore
···
# Output
.output
.vercel
-
/.svelte-kit
-
/build
-
/visitcount
-
/bouncecount
-
/legitvisitcount
-
/fakevisitcount
-
/distancetravelled
-
/notes
-
/note
+
.svelte-kit
+
build
+
visitcount
+
bouncecount
+
legitvisitcount
+
fakevisitcount
+
distancetravelled
+
notes
+
note
+
data
# OS
.DS_Store
-4
.prettierignore
···
-
# Package Managers
-
package-lock.json
-
pnpm-lock.yaml
-
yarn.lock
-8
.prettierrc
···
-
{
-
"useTabs": true,
-
"singleQuote": true,
-
"trailingComma": "none",
-
"printWidth": 100,
-
"plugins": ["prettier-plugin-svelte"],
-
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
-
}
-9
README.md
···
-
code for one of its (90008) human-facing data endpoints (aka a website.)
-
-
- the website itself uses sveltekit (w/ typescript) and tailwindcss. it's served with bun.
-
- the logs and guestbook show posts from its bsky account and a guestbook account respectively, hosted on its pds.
-
- it's deployed to a server with nix, so it's packaged with nix (see flake.nix).
-
-
notes to itself:
-
-
- don't use tags starting with h- (same goes for p-) in root layout or page, this causes hcard parsers to trip up
-908
bun.lock
···
-
{
-
"lockfileVersion": 1,
-
"workspaces": {
-
"": {
-
"name": "website",
-
"dependencies": {
-
"@neodrag/svelte": "^2.3.3",
-
"@rowanmanning/feed-parser": "^2.1.1",
-
"@skyware/bot": "^0.4.0",
-
"@std/toml": "npm:@jsr/std__toml",
-
"@types/bun": "^1.2.20",
-
"@types/node-schedule": "^2.1.8",
-
"nanoid": "^5.1.5",
-
"node-schedule": "^2.1.1",
-
"prometheus-remote-write": "^0.5.1",
-
"robots-parser": "^3.0.1",
-
"steamgriddb": "^2.2.0",
-
},
-
"devDependencies": {
-
"@sveltejs/kit": "^2.33.1",
-
"@sveltejs/vite-plugin-svelte": "^6.1.3",
-
"@tailwindcss/forms": "^0.5.10",
-
"@tailwindcss/typography": "^0.5.16",
-
"@types/eslint": "^9.6.1",
-
"@types/node": "^22.17.2",
-
"autoprefixer": "^10.4.21",
-
"eslint": "^9.33.0",
-
"eslint-config-prettier": "^10.1.8",
-
"eslint-plugin-svelte": "^3.11.0",
-
"globals": "^16.3.0",
-
"mdsvex": "^0.12.6",
-
"postcss": "^8.5.6",
-
"prettier": "^3.6.2",
-
"prettier-plugin-svelte": "^3.4.0",
-
"svelte": "^5.38.2",
-
"svelte-adapter-bun": "^0.5.2",
-
"svelte-check": "^4.3.1",
-
"sveltekit-rate-limiter": "^0.7.0",
-
"tailwindcss": "^3.4.17",
-
"tslib": "^2.8.1",
-
"typescript": "^5.9.2",
-
"typescript-eslint": "^8.40.0",
-
"typescript-svelte-plugin": "^0.3.50",
-
"vite": "^7.1.3",
-
},
-
},
-
},
-
"trustedDependencies": [
-
"esbuild",
-
"@sveltejs/kit",
-
"protobufjs",
-
],
-
"packages": {
-
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
-
-
"@atcute/atproto": ["@atcute/atproto@3.1.1", "", { "dependencies": { "@atcute/lexicons": "^1.1.0" } }, "sha512-D+RLTIPF0xLu7BPZY8KSewAPemJFh+3n3zeQ3ROsLxbTtCHbrTDMAmAFexaVRAPGcPYrwXaBUlv7yZjScJolMg=="],
-
-
"@atcute/bluesky": ["@atcute/bluesky@3.2.0", "", { "dependencies": { "@atcute/atproto": "^3.1.1", "@atcute/lexicons": "^1.1.0" } }, "sha512-OqPLqUNjXcgQ25MaPdU7H0QcWmZrx6QQk7d5B22A5U4xy+hZJ954kQ5mSAn24Bt0DEm4j/isq1WZovr3vaPTUA=="],
-
-
"@atcute/bluesky-richtext-builder": ["@atcute/bluesky-richtext-builder@2.0.3", "", { "dependencies": { "@atcute/bluesky": "^3.0.2", "@atcute/lexicons": "^1.0.2" } }, "sha512-FOd4At9etRfkfpun3PFBU1TjRurWNjjwkZZ9UcURxdzOg8H6NBZXk4Djdz0Q8VpbcqUxjDOycGHTJClOA8+OEw=="],
-
-
"@atcute/car": ["@atcute/car@3.1.1", "", { "dependencies": { "@atcute/cbor": "^2.2.4", "@atcute/cid": "^2.2.3", "@atcute/uint8array": "^1.0.2", "@atcute/varint": "^1.0.2", "yocto-queue": "^1.2.1" } }, "sha512-yhez/LqIl0zHubG6z/G/gqWYHmg7wJ5L4jNkbXj5FvZ4eOvmzsw8+ojbdq6wfMU4p5NhP0pUJNLkTZHbYSPmLg=="],
-
-
"@atcute/cbor": ["@atcute/cbor@2.2.5", "", { "dependencies": { "@atcute/cid": "^2.2.3", "@atcute/multibase": "^1.1.4", "@atcute/uint8array": "^1.0.3" } }, "sha512-sBT8+6qau0mC3kwgmjl+nzqGn02xsE9b+kSgXm4/BRd9w8fwdRQYwcC9ApDlfaojrljJfcEkimppl/IcPOF3CA=="],
-
-
"@atcute/cid": ["@atcute/cid@2.2.3", "", { "dependencies": { "@atcute/multibase": "^1.1.4", "@atcute/uint8array": "^1.0.2" } }, "sha512-WEzNSL1EuCVtCQDFYEBIm4dEP6PcMEwi8IYUVIWvT77eO5EjY58F63z5T4qMABxSBM0+L4kqMxypdL1Fzf6LZw=="],
-
-
"@atcute/client": ["@atcute/client@4.0.3", "", { "dependencies": { "@atcute/identity": "^1.0.2", "@atcute/lexicons": "^1.0.3" } }, "sha512-RIOZWFVLca/HiPAAUDqQPOdOreCxTbL5cb+WUf5yqQOKIu5yEAP3eksinmlLmgIrlr5qVOE7brazUUzaskFCfw=="],
-
-
"@atcute/identity": ["@atcute/identity@1.0.3", "", { "dependencies": { "@atcute/lexicons": "^1.0.4", "@badrap/valita": "^0.4.5" } }, "sha512-mNMxbKHFGys03A8JXKk0KfMBzdd0vrYMzZZWjpw1nYTs0+ea6bo5S1hwqVUZxHdo1gFHSe/t63jxQIF4yL9aKw=="],
-
-
"@atcute/lexicons": ["@atcute/lexicons@1.1.0", "", { "dependencies": { "esm-env": "^1.2.2" } }, "sha512-LFqwnria78xLYb62Ri/+WwQpUTgZp2DuyolNGIIOV1dpiKhFFFh//nscHMA6IExFLQRqWDs3tTjy7zv0h3sf1Q=="],
-
-
"@atcute/multibase": ["@atcute/multibase@1.1.4", "", { "dependencies": { "@atcute/uint8array": "^1.0.2" } }, "sha512-NUf5AeeSOmuZHGU+4GAaMtISJoG+ZHtW/vUVA4lK/YDt/7LODAW0Fd0NNIIUPVUoW0xJS6zSEIWvwLLuxmEHhA=="],
-
-
"@atcute/ozone": ["@atcute/ozone@3.1.3", "", { "dependencies": { "@atcute/atproto": "^3.1.1", "@atcute/bluesky": "^3.2.0", "@atcute/lexicons": "^1.1.0" } }, "sha512-XJrt7lgUgF7w/JGoJbdD1bFlUKHCr9tf+RxT8J+8HZTGhhitj32YXDFqiDFKK/sbSpCR/Dj9gCpTMnfLVn+x/Q=="],
-
-
"@atcute/uint8array": ["@atcute/uint8array@1.0.3", "", {}, "sha512-M/K+ihiVW8Pl2PFLzaC4E3l4JaZ1IH05Q0AbPWUC4cVHnd/gZ/1kAF5ngdtGvJeDMirHZ2VAy7OmAsPwR/2nlA=="],
-
-
"@atcute/varint": ["@atcute/varint@1.0.2", "", {}, "sha512-0O31hePzzr4O3NGWHUKKOyta6CGSL+AtN8iir8grGxu9jXyI7DBARlw6PbgKA6uTAvsXdpmRmF8MX+p0TsLnNg=="],
-
-
"@badrap/valita": ["@badrap/valita@0.4.6", "", {}, "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg=="],
-
-
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.8", "", { "os": "aix", "cpu": "ppc64" }, "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA=="],
-
-
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.8", "", { "os": "android", "cpu": "arm" }, "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw=="],
-
-
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.8", "", { "os": "android", "cpu": "arm64" }, "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w=="],
-
-
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.8", "", { "os": "android", "cpu": "x64" }, "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA=="],
-
-
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw=="],
-
-
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg=="],
-
-
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.8", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA=="],
-
-
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw=="],
-
-
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.8", "", { "os": "linux", "cpu": "arm" }, "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg=="],
-
-
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w=="],
-
-
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.8", "", { "os": "linux", "cpu": "ia32" }, "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg=="],
-
-
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ=="],
-
-
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw=="],
-
-
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.8", "", { "os": "linux", "cpu": "ppc64" }, "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ=="],
-
-
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg=="],
-
-
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.8", "", { "os": "linux", "cpu": "s390x" }, "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg=="],
-
-
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.8", "", { "os": "linux", "cpu": "x64" }, "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ=="],
-
-
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.8", "", { "os": "none", "cpu": "arm64" }, "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw=="],
-
-
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.8", "", { "os": "none", "cpu": "x64" }, "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg=="],
-
-
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.8", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ=="],
-
-
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.8", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ=="],
-
-
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.8", "", { "os": "none", "cpu": "arm64" }, "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg=="],
-
-
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.8", "", { "os": "sunos", "cpu": "x64" }, "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w=="],
-
-
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ=="],
-
-
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.8", "", { "os": "win32", "cpu": "ia32" }, "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg=="],
-
-
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.8", "", { "os": "win32", "cpu": "x64" }, "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw=="],
-
-
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.7.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw=="],
-
-
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
-
-
"@eslint/config-array": ["@eslint/config-array@0.21.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ=="],
-
-
"@eslint/config-helpers": ["@eslint/config-helpers@0.3.1", "", {}, "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA=="],
-
-
"@eslint/core": ["@eslint/core@0.15.2", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg=="],
-
-
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "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-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
-
-
"@eslint/js": ["@eslint/js@9.33.0", "", {}, "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A=="],
-
-
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
-
-
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.3.5", "", { "dependencies": { "@eslint/core": "^0.15.2", "levn": "^0.4.1" } }, "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w=="],
-
-
"@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.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
-
-
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
-
-
"@isaacs/ttlcache": ["@isaacs/ttlcache@1.4.1", "", {}, "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="],
-
-
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="],
-
-
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
-
-
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
-
-
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.4", "", {}, "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw=="],
-
-
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.29", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ=="],
-
-
"@jsr/std__collections": ["@jsr/std__collections@1.1.3", "https://npm.jsr.io/~/11/@jsr/std__collections/1.1.3.tgz", {}, "sha512-jGG6mv3IjOyxm6PyT1YVbLyAlZL+Gow6LOpBw+84qb1nkdJY0+t6bi7ICEqAwUz87cNjBS0P+yZQ5HHclJhsfw=="],
-
-
"@neodrag/svelte": ["@neodrag/svelte@2.3.3", "", { "peerDependencies": { "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0" } }, "sha512-avXzhrilsBsnMFljhVAQ7h+6hbSIrvRCJ61GCiGbGISkC1QOhjDCNvPZo2+7KVwiYrnUBx4NRH0kTIqrcxv9Lg=="],
-
-
"@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=="],
-
-
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
-
-
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
-
-
"@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
-
-
"@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
-
-
"@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="],
-
-
"@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="],
-
-
"@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="],
-
-
"@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="],
-
-
"@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
-
-
"@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="],
-
-
"@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="],
-
-
"@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="],
-
-
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.46.2", "", { "os": "android", "cpu": "arm" }, "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA=="],
-
-
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.46.2", "", { "os": "android", "cpu": "arm64" }, "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ=="],
-
-
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.46.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ=="],
-
-
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.46.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA=="],
-
-
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.46.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg=="],
-
-
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.46.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw=="],
-
-
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.46.2", "", { "os": "linux", "cpu": "arm" }, "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA=="],
-
-
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.46.2", "", { "os": "linux", "cpu": "arm" }, "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ=="],
-
-
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.46.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng=="],
-
-
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.46.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg=="],
-
-
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.46.2", "", { "os": "linux", "cpu": "none" }, "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA=="],
-
-
"@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.46.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw=="],
-
-
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.46.2", "", { "os": "linux", "cpu": "none" }, "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ=="],
-
-
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.46.2", "", { "os": "linux", "cpu": "none" }, "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw=="],
-
-
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.46.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA=="],
-
-
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.46.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA=="],
-
-
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.46.2", "", { "os": "linux", "cpu": "x64" }, "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA=="],
-
-
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.46.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g=="],
-
-
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.46.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ=="],
-
-
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.46.2", "", { "os": "win32", "cpu": "x64" }, "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg=="],
-
-
"@rowanmanning/feed-parser": ["@rowanmanning/feed-parser@2.1.1", "", { "dependencies": { "fast-xml-parser": "^5.0.8", "html-entities": "^2.3.3" } }, "sha512-OFxb37OaQ8ki1VQt/FtrDw74nY2epU9He0QOCzkfc/FxbeulCJo7SbZNiDw2ruwnISuO7PhDsZ69DdWzCVEIsA=="],
-
-
"@skyware/bot": ["@skyware/bot@0.4.0", "", { "dependencies": { "@atcute/atproto": "^3.1.1", "@atcute/bluesky": "^3.2.0", "@atcute/bluesky-richtext-builder": "^2.0.3", "@atcute/client": "^4.0.3", "@atcute/lexicons": "^1.1.0", "@atcute/ozone": "^3.1.3", "quick-lru": "^7.0.0", "rate-limit-threshold": "^0.1.5" }, "optionalDependencies": { "@skyware/firehose": "^0.5.2", "@skyware/jetstream": "^0.2.5" } }, "sha512-xbodXxB0PRqOwaB/llbdX1sZ9wqIXZhTxwPl77XL9BAP5/SI1DbM0wvo7qwkmI4CBBakE6Hp7ZYj0pyYDb81Uw=="],
-
-
"@skyware/firehose": ["@skyware/firehose@0.5.2", "", { "dependencies": { "@atcute/car": "^3.0.3", "@atcute/cbor": "^2.2.2", "nanoevents": "^9.1.0" } }, "sha512-Ayg/cF0BkakBNQVA51ClDka0+nC96WiARNrGElMQxfqbwao0PBaCXkunfr8qS4DWS3TqLnR6hA9mvm1vAYlxJQ=="],
-
-
"@skyware/jetstream": ["@skyware/jetstream@0.2.5", "", { "dependencies": { "@atcute/atproto": "^3.1.0", "@atcute/bluesky": "^3.1.4", "@atcute/lexicons": "^1.1.0", "partysocket": "^1.1.3", "tiny-emitter": "^2.1.0" } }, "sha512-fM/zs03DLwqRyzZZJFWN20e76KrdqIp97Tlm8Cek+vxn96+tu5d/fx79V6H85L0QN6HvGiX2l9A8hWFqHvYlOA=="],
-
-
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
-
-
"@std/toml": ["@jsr/std__toml@1.0.9", "https://npm.jsr.io/~/11/@jsr/std__toml/1.0.9.tgz", { "dependencies": { "@jsr/std__collections": "^1.1.3" } }, "sha512-gKUQsEmhHFmChYQwYAjGvuC3HoZRLUcf3Ib/FsyQjAw76nBLSl0i+jLqRfqX1DVUD6Bqgm6JWlmvqvBtXf4m0w=="],
-
-
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
-
-
"@sveltejs/kit": ["@sveltejs/kit@2.33.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.1.0", "esm-env": "^1.2.2", "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": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["@opentelemetry/api"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-q2jnchZAG3+DvaEB3/SDF4hqjWPhWE8HRuQPEp+6v2r9n0PpsFH+Ea0EJQPPzzlqlMRO6+t58INhbjshevHE8A=="],
-
-
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.1.3", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-3pppgIeIZs6nrQLazzKcdnTJ2IWiui/UucEPXKyFG35TKaHQrfkWBnv6hyJcLxFuR90t+LaoecrqTs8rJKWfSQ=="],
-
-
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.1", "", { "dependencies": { "debug": "^4.4.1" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA=="],
-
-
"@tailwindcss/forms": ["@tailwindcss/forms@0.5.10", "", { "dependencies": { "mini-svg-data-uri": "^1.2.3" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" } }, "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw=="],
-
-
"@tailwindcss/typography": ["@tailwindcss/typography@0.5.16", "", { "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA=="],
-
-
"@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="],
-
-
"@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.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
-
-
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
-
-
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
-
-
"@types/node": ["@types/node@22.17.2", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-gL6z5N9Jm9mhY+U2KXZpteb+09zyffliRkZyZOHODGATyC5B1Jt/7TzuuiLkFsSUMLbS1OLmlj/E+/3KF4Q/4w=="],
-
-
"@types/node-schedule": ["@types/node-schedule@2.1.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-k00g6Yj/oUg/CDC+MeLHUzu0+OFxWbIqrFfDiLi6OPKxTujvpv29mHGM8GtKr7B+9Vv92FcK/8mRqi1DK5f3hA=="],
-
-
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
-
-
"@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
-
-
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.40.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.40.0", "@typescript-eslint/type-utils": "8.40.0", "@typescript-eslint/utils": "8.40.0", "@typescript-eslint/visitor-keys": "8.40.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.40.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-w/EboPlBwnmOBtRbiOvzjD+wdiZdgFeo17lkltrtn7X37vagKKWJABvyfsJXTlHe6XBzugmYgd4A4nW+k8Mixw=="],
-
-
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.40.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.40.0", "@typescript-eslint/types": "8.40.0", "@typescript-eslint/typescript-estree": "8.40.0", "@typescript-eslint/visitor-keys": "8.40.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-jCNyAuXx8dr5KJMkecGmZ8KI61KBUhkCob+SD+C+I5+Y1FWI2Y3QmY4/cxMCC5WAsZqoEtEETVhUiUMIGCf6Bw=="],
-
-
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.40.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.40.0", "@typescript-eslint/types": "^8.40.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-/A89vz7Wf5DEXsGVvcGdYKbVM9F7DyFXj52lNYUDS1L9yJfqjW/fIp5PgMuEJL/KeqVTe2QSbXAGUZljDUpArw=="],
-
-
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.40.0", "", { "dependencies": { "@typescript-eslint/types": "8.40.0", "@typescript-eslint/visitor-keys": "8.40.0" } }, "sha512-y9ObStCcdCiZKzwqsE8CcpyuVMwRouJbbSrNuThDpv16dFAj429IkM6LNb1dZ2m7hK5fHyzNcErZf7CEeKXR4w=="],
-
-
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.40.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-jtMytmUaG9d/9kqSl/W3E3xaWESo4hFDxAIHGVW/WKKtQhesnRIJSAJO6XckluuJ6KDB5woD1EiqknriCtAmcw=="],
-
-
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.40.0", "", { "dependencies": { "@typescript-eslint/types": "8.40.0", "@typescript-eslint/typescript-estree": "8.40.0", "@typescript-eslint/utils": "8.40.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-eE60cK4KzAc6ZrzlJnflXdrMqOBaugeukWICO2rB0KNvwdIMaEaYiywwHMzA1qFpTxrLhN9Lp4E/00EgWcD3Ow=="],
-
-
"@typescript-eslint/types": ["@typescript-eslint/types@8.40.0", "", {}, "sha512-ETdbFlgbAmXHyFPwqUIYrfc12ArvpBhEVgGAxVYSwli26dn8Ko+lIo4Su9vI9ykTZdJn+vJprs/0eZU0YMAEQg=="],
-
-
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.40.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.40.0", "@typescript-eslint/tsconfig-utils": "8.40.0", "@typescript-eslint/types": "8.40.0", "@typescript-eslint/visitor-keys": "8.40.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.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-k1z9+GJReVVOkc1WfVKs1vBrR5MIKKbdAjDTPvIK3L8De6KbFfPFt6BKpdkdk7rZS2GtC/m6yI5MYX+UsuvVYQ=="],
-
-
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.40.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.40.0", "@typescript-eslint/types": "8.40.0", "@typescript-eslint/typescript-estree": "8.40.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Cgzi2MXSZyAUOY+BFwGs17s7ad/7L+gKt6Y8rAVVWS+7o6wrjeFN4nVfTpbE25MNcxyJ+iYUXflbs2xR9h4UBg=="],
-
-
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.40.0", "", { "dependencies": { "@typescript-eslint/types": "8.40.0", "eslint-visitor-keys": "^4.2.1" } }, "sha512-8CZ47QwalyRjsypfwnbI3hKy5gJDPmrkLjkgMxhi0+DZZ2QNx2naS6/hWoVYUHU7LU2zleF68V9miaVZvhFfTA=="],
-
-
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
-
-
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
-
-
"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-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
-
-
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
-
-
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
-
-
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
-
-
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
-
-
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
-
-
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
-
-
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
-
-
"autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="],
-
-
"axios": ["axios@1.11.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA=="],
-
-
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
-
-
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
-
-
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
-
-
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
-
-
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
-
-
"browserslist": ["browserslist@4.25.2", "", { "dependencies": { "caniuse-lite": "^1.0.30001733", "electron-to-chromium": "^1.5.199", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-0si2SJK3ooGzIawRu61ZdPCO1IncZwS8IzuX73sPZsXW6EQ/w/DAfPyKI8l1ETTCr2MnvqWitmlCUxgdul45jA=="],
-
-
"bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
-
-
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
-
-
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
-
-
"camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
-
-
"caniuse-lite": ["caniuse-lite@1.0.30001733", "", {}, "sha512-e4QKw/O2Kavj2VQTKZWrwzkt3IxOmIlU6ajRb6LP64LHpBo1J67k2Hi4Vu/TgJWsNtynurfS0uK3MaUTCPfu5Q=="],
-
-
"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=="],
-
-
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
-
-
"commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
-
-
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
-
-
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
-
-
"cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="],
-
-
"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=="],
-
-
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
-
-
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
-
-
"dedent-js": ["dedent-js@1.0.1", "", {}, "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ=="],
-
-
"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=="],
-
-
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
-
-
"devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="],
-
-
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
-
-
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
-
-
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
-
-
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
-
-
"electron-to-chromium": ["electron-to-chromium@1.5.199", "", {}, "sha512-3gl0S7zQd88kCAZRO/DnxtBKuhMO4h0EaQIN3YgZfV6+pW+5+bf2AdQeHNESCoaQqo/gjGVYEf2YM4O5HJQqpQ=="],
-
-
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
-
-
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
-
-
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
-
-
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
-
-
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
-
-
"esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
-
-
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
-
-
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
-
-
"eslint": ["eslint@9.33.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", "@eslint/config-helpers": "^0.3.1", "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.33.0", "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@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.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.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-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA=="],
-
-
"eslint-config-prettier": ["eslint-config-prettier@10.1.8", "", { "peerDependencies": { "eslint": ">=7.0.0" }, "bin": { "eslint-config-prettier": "bin/cli.js" } }, "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w=="],
-
-
"eslint-plugin-svelte": ["eslint-plugin-svelte@3.11.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.3.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-KliWlkieHyEa65aQIkRwUFfHzT5Cn4u3BQQsu3KlkJOs7c1u7ryn84EWaOjEzilbKgttT4OfBURA8Uc4JBSQIw=="],
-
-
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
-
-
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
-
-
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
-
-
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
-
-
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
-
-
"esrap": ["esrap@2.1.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA=="],
-
-
"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=="],
-
-
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
-
-
"event-target-polyfill": ["event-target-polyfill@0.0.4", "", {}, "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ=="],
-
-
"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=="],
-
-
"fast-xml-parser": ["fast-xml-parser@5.2.5", "", { "dependencies": { "strnum": "^2.1.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ=="],
-
-
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
-
-
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
-
-
"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.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
-
-
"follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
-
-
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
-
-
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
-
-
"fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
-
-
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
-
-
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
-
-
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
-
-
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
-
-
"glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
-
-
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
-
-
"globals": ["globals@16.3.0", "", {}, "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ=="],
-
-
"globalyzer": ["globalyzer@0.1.0", "", {}, "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q=="],
-
-
"globrex": ["globrex@0.1.2", "", {}, "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="],
-
-
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
-
-
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
-
-
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
-
-
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
-
-
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
-
-
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
-
-
"html-entities": ["html-entities@2.6.0", "", {}, "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="],
-
-
"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=="],
-
-
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
-
-
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
-
-
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
-
-
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
-
-
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
-
-
"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=="],
-
-
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
-
-
"jiti": ["jiti@1.21.7", "", { "bin": { "jiti": "bin/jiti.js" } }, "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A=="],
-
-
"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.37.0", "", {}, "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="],
-
-
"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@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
-
-
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
-
-
"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.castarray": ["lodash.castarray@4.4.0", "", {}, "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q=="],
-
-
"lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
-
-
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
-
-
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
-
-
"long-timeout": ["long-timeout@0.1.1", "", {}, "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="],
-
-
"lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="],
-
-
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
-
-
"luxon": ["luxon@3.7.1", "", {}, "sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg=="],
-
-
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
-
-
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
-
-
"mdsvex": ["mdsvex@0.12.6", "", { "dependencies": { "@types/mdast": "^4.0.4", "@types/unist": "^2.0.3", "prism-svelte": "^0.4.7", "prismjs": "^1.17.1", "unist-util-visit": "^2.0.1", "vfile-message": "^2.0.4" }, "peerDependencies": { "svelte": "^3.56.0 || ^4.0.0 || ^5.0.0-next.120" } }, "sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg=="],
-
-
"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-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
-
-
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
-
-
"mini-svg-data-uri": ["mini-svg-data-uri@1.4.4", "", { "bin": { "mini-svg-data-uri": "cli.js" } }, "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg=="],
-
-
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
-
-
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
-
-
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
-
-
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
-
-
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
-
-
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
-
-
"nanoevents": ["nanoevents@9.1.0", "", {}, "sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A=="],
-
-
"nanoid": ["nanoid@5.1.5", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw=="],
-
-
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
-
-
"no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="],
-
-
"node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="],
-
-
"node-schedule": ["node-schedule@2.1.1", "", { "dependencies": { "cron-parser": "^4.2.0", "long-timeout": "0.1.1", "sorted-array-functions": "^1.3.0" } }, "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ=="],
-
-
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
-
-
"normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
-
-
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
-
-
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
-
-
"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=="],
-
-
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
-
-
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
-
-
"partysocket": ["partysocket@1.1.5", "", { "dependencies": { "event-target-polyfill": "^0.0.4" } }, "sha512-8uw9foq9bij4sKLCtTSHvyqMrMTQ5FJjrHc7BjoM2s95Vu7xYCN63ABpI7OZHC7ZMP5xaom/A+SsoFPXmTV6ZQ=="],
-
-
"pascal-case": ["pascal-case@3.1.2", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g=="],
-
-
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
-
-
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
-
-
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
-
-
"path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
-
-
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
-
-
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
-
-
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
-
-
"pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="],
-
-
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
-
-
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
-
-
"postcss-js": ["postcss-js@4.0.1", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw=="],
-
-
"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-nested": ["postcss-nested@6.2.0", "", { "dependencies": { "postcss-selector-parser": "^6.1.1" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ=="],
-
-
"postcss-safe-parser": ["postcss-safe-parser@7.0.1", "", { "peerDependencies": { "postcss": "^8.4.31" } }, "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A=="],
-
-
"postcss-scss": ["postcss-scss@4.0.9", "", { "peerDependencies": { "postcss": "^8.4.29" } }, "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A=="],
-
-
"postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
-
-
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
-
-
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
-
-
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
-
-
"prettier-plugin-svelte": ["prettier-plugin-svelte@3.4.0", "", { "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" } }, "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ=="],
-
-
"prism-svelte": ["prism-svelte@0.4.7", "", {}, "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ=="],
-
-
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
-
-
"prometheus-remote-write": ["prometheus-remote-write@0.5.1", "", { "dependencies": { "protobufjs": "^7.2.4", "snappyjs": "^0.6.1" }, "peerDependencies": { "node-fetch": "^2.6.7" }, "optionalPeers": ["node-fetch"] }, "sha512-wCQk35u4EWIzGQyCeBKKaVdUefiTyFA8X/SU8B5KQX82k4vwDQW4LMb8pYmyBLZWAUBHcxSoacwosPRE2VvW+w=="],
-
-
"protobufjs": ["protobufjs@7.5.3", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw=="],
-
-
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
-
-
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
-
-
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
-
-
"quick-lru": ["quick-lru@7.0.1", "", {}, "sha512-kLjThirJMkWKutUKbZ8ViqFc09tDQhlbQo2MNuVeLWbRauqYP96Sm6nzlQ24F0HFjUNZ4i9+AgldJ9H6DZXi7g=="],
-
-
"rate-limit-threshold": ["rate-limit-threshold@0.1.5", "", {}, "sha512-75vpvXC/ZqQJrFDp0dVtfoXZi8kxQP2eBuxVYFvGDfnHhcgE+ZG870u4ItQhWQh54Y6nNwOaaq5g3AL9n27lTg=="],
-
-
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
-
-
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
-
-
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
-
-
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
-
-
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
-
-
"robots-parser": ["robots-parser@3.0.1", "", {}, "sha512-s+pyvQeIKIZ0dx5iJiQk1tPLJAWln39+MI5jtM8wnyws+G5azk+dMnMX0qfbqNetKKNgcWWOdi0sfm+FbQbgdQ=="],
-
-
"rollup": ["rollup@4.46.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.46.2", "@rollup/rollup-android-arm64": "4.46.2", "@rollup/rollup-darwin-arm64": "4.46.2", "@rollup/rollup-darwin-x64": "4.46.2", "@rollup/rollup-freebsd-arm64": "4.46.2", "@rollup/rollup-freebsd-x64": "4.46.2", "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", "@rollup/rollup-linux-arm-musleabihf": "4.46.2", "@rollup/rollup-linux-arm64-gnu": "4.46.2", "@rollup/rollup-linux-arm64-musl": "4.46.2", "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", "@rollup/rollup-linux-ppc64-gnu": "4.46.2", "@rollup/rollup-linux-riscv64-gnu": "4.46.2", "@rollup/rollup-linux-riscv64-musl": "4.46.2", "@rollup/rollup-linux-s390x-gnu": "4.46.2", "@rollup/rollup-linux-x64-gnu": "4.46.2", "@rollup/rollup-linux-x64-musl": "4.46.2", "@rollup/rollup-win32-arm64-msvc": "4.46.2", "@rollup/rollup-win32-ia32-msvc": "4.46.2", "@rollup/rollup-win32-x64-msvc": "4.46.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg=="],
-
-
"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.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
-
-
"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=="],
-
-
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
-
-
"sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="],
-
-
"snappyjs": ["snappyjs@0.6.1", "", {}, "sha512-YIK6I2lsH072UE0aOFxxY1dPDCS43I5ktqHpeAsuLNYWkE5pGxRGWfDM4/vSUfNzXjC1Ivzt3qx31PCLmc9yqg=="],
-
-
"sorted-array-functions": ["sorted-array-functions@1.3.0", "", {}, "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA=="],
-
-
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
-
-
"steamgriddb": ["steamgriddb@2.2.0", "", { "dependencies": { "axios": "^1.7.2" } }, "sha512-0A7dBIv57FwtTKAkZq5uokcb2kprZFAHRpCuwmGz3MWVQjrXG0uDz3qr0oNkEAoDGc2DyOoAx18mR2tFvePBvA=="],
-
-
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
-
-
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
-
-
"strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
-
-
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
-
-
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
-
-
"strnum": ["strnum@2.1.1", "", {}, "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="],
-
-
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
-
-
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
-
-
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
-
-
"svelte": ["svelte@5.38.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-iAcp/oFAWauVSGILdD67n7DiwgLHXZzWZIdzl7araRxu72jUr7PFAo2Iie7gXt0IbnlYvhxCb9GT3ZJUquO3PA=="],
-
-
"svelte-adapter-bun": ["svelte-adapter-bun@0.5.2", "", { "dependencies": { "tiny-glob": "^0.2.9" } }, "sha512-xEtFgaal6UgrCwwkSIcapO9kopoFNUYCYqyKCikdqxX9bz2TDYnrWQZ7qBnkunMxi1HOIERUCvTcebYGiarZLA=="],
-
-
"svelte-check": ["svelte-check@4.3.1", "", { "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-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg=="],
-
-
"svelte-eslint-parser": ["svelte-eslint-parser@1.3.1", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-0Iztj5vcOVOVkhy1pbo5uA9r+d3yaVoE5XPc9eABIWDOSJZ2mOsZ4D+t45rphWCOr0uMw3jtSG2fh2e7GvKnPg=="],
-
-
"svelte2tsx": ["svelte2tsx@0.7.42", "", { "dependencies": { "dedent-js": "^1.0.1", "pascal-case": "^3.1.1" }, "peerDependencies": { "svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0", "typescript": "^4.9.4 || ^5.0.0" } }, "sha512-PSNrKS16aVdAajoFjpF5M0t6TA7ha7GcKbBajD9RG3M+vooAuvLnWAGUSC6eJL4zEOVbOWKtcS2BuY4rxPljoA=="],
-
-
"sveltekit-rate-limiter": ["sveltekit-rate-limiter@0.7.0", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1" }, "peerDependencies": { "@sveltejs/kit": "1.x || 2.x" } }, "sha512-aQI8Y1dTWKsB4YiZMBYORMDwy2SaFA2J5t848dEPVNkXWzhqrHqHUBb7QiNiLWqAeWvOJBwD+MZnsbmvbhGQdg=="],
-
-
"tailwindcss": ["tailwindcss@3.4.17", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.6.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.2", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.6", "lilconfig": "^3.1.3", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.4.47", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.2", "postcss-nested": "^6.2.0", "postcss-selector-parser": "^6.1.2", "resolve": "^1.22.8", "sucrase": "^3.35.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og=="],
-
-
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
-
-
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
-
-
"tiny-emitter": ["tiny-emitter@2.1.0", "", {}, "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="],
-
-
"tiny-glob": ["tiny-glob@0.2.9", "", { "dependencies": { "globalyzer": "0.1.0", "globrex": "^0.1.2" } }, "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg=="],
-
-
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
-
-
"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.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
-
-
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
-
-
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
-
-
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
-
-
"typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="],
-
-
"typescript-eslint": ["typescript-eslint@8.40.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.40.0", "@typescript-eslint/parser": "8.40.0", "@typescript-eslint/typescript-estree": "8.40.0", "@typescript-eslint/utils": "8.40.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Xvd2l+ZmFDPEt4oj1QEXzA4A2uUK6opvKu3eGN9aGjB8au02lIVcLyi375w94hHyejTOmzIU77L8ol2sRg9n7Q=="],
-
-
"typescript-svelte-plugin": ["typescript-svelte-plugin@0.3.50", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "svelte2tsx": "~0.7.35" } }, "sha512-CD6jMNAYJwqCyQ5zZBDRuveeJvAgIogLwXMf5eXAl4K36wD8W+Npw49h6j5fXnpd7SKcG3uptGpeCGETED6WSA=="],
-
-
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
-
-
"unist-util-is": ["unist-util-is@4.1.0", "", {}, "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg=="],
-
-
"unist-util-stringify-position": ["unist-util-stringify-position@2.0.3", "", { "dependencies": { "@types/unist": "^2.0.2" } }, "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g=="],
-
-
"unist-util-visit": ["unist-util-visit@2.0.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0", "unist-util-visit-parents": "^3.0.0" } }, "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q=="],
-
-
"unist-util-visit-parents": ["unist-util-visit-parents@3.1.1", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^4.0.0" } }, "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg=="],
-
-
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
-
-
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
-
-
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
-
-
"vfile-message": ["vfile-message@2.0.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" } }, "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ=="],
-
-
"vite": ["vite@7.1.3", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw=="],
-
-
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
-
-
"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=="],
-
-
"wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
-
-
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
-
-
"yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
-
-
"yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
-
-
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
-
-
"@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=="],
-
-
"@types/node-schedule/@types/node": ["@types/node@22.17.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA=="],
-
-
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
-
-
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
-
-
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
-
-
"bun-types/@types/node": ["@types/node@22.17.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA=="],
-
-
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
-
-
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
-
-
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
-
-
"p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
-
-
"postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
-
-
"postcss-load-config/lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
-
-
"postcss-nested/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=="],
-
-
"protobufjs/@types/node": ["@types/node@22.17.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA=="],
-
-
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
-
-
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
-
-
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
-
-
"svelte-eslint-parser/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="],
-
-
"tailwindcss/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
-
-
"tailwindcss/postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["postcss", "ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
-
-
"tailwindcss/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=="],
-
-
"vite/fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
-
-
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
-
-
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
-
-
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
-
-
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
-
-
"glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
-
-
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
-
-
"tailwindcss/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
-
-
"tailwindcss/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
-
-
"tailwindcss/postcss-load-config/yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="],
-
-
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
-
-
"wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
-
-
"tailwindcss/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
-
}
-
}
+4
deno.json
···
+
{
+
"workspace": ["./eunomia"],
+
"nodeModulesDir": "auto"
+
}
+2772
deno.lock
···
+
{
+
"version": "5",
+
"specifiers": {
+
"npm:@jsr/std__toml@*": "1.0.11",
+
"npm:@neodrag/svelte@^2.3.3": "2.3.3_svelte@5.45.2__acorn@8.15.0",
+
"npm:@rowanmanning/feed-parser@^2.1.1": "2.1.1",
+
"npm:@skyware/bot@0.4": "0.4.0",
+
"npm:@sveltejs/adapter-node@^5.4.0": "5.4.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.45.2____acorn@8.15.0___vite@7.2.4____@types+node@24.10.1____picomatch@4.0.3___@types+node@24.10.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__acorn@8.15.0__@types+node@24.10.1_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1",
+
"npm:@sveltejs/kit@^2.49.0": "2.49.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_acorn@8.15.0_@types+node@24.10.1",
+
"npm:@sveltejs/vite-plugin-svelte@^6.1.3": "6.2.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1",
+
"npm:@tailwindcss/forms@~0.5.10": "0.5.10_tailwindcss@3.4.18__postcss@8.5.6__jiti@1.21.7",
+
"npm:@tailwindcss/typography@~0.5.16": "0.5.19_tailwindcss@3.4.18__postcss@8.5.6__jiti@1.21.7",
+
"npm:@types/deno@^2.5.0": "2.5.0",
+
"npm:@types/eslint@^9.6.1": "9.6.1",
+
"npm:@types/node-schedule@^2.1.8": "2.1.8",
+
"npm:@types/node@^24.10.1": "24.10.1",
+
"npm:@xterm/addon-canvas@0.7": "0.7.0_@xterm+xterm@5.5.0",
+
"npm:@xterm/addon-fit@0.10": "0.10.0_@xterm+xterm@5.5.0",
+
"npm:@xterm/addon-web-links@0.11": "0.11.0_@xterm+xterm@5.5.0",
+
"npm:@xterm/addon-webgl@0.18": "0.18.0_@xterm+xterm@5.5.0",
+
"npm:@xterm/xterm@^5.5.0": "5.5.0",
+
"npm:autoprefixer@^10.4.22": "10.4.22_postcss@8.5.6",
+
"npm:eslint-config-prettier@^10.1.8": "10.1.8_eslint@9.39.1",
+
"npm:eslint-plugin-svelte@^3.13.0": "3.13.0_eslint@9.39.1_svelte@5.45.2__acorn@8.15.0_postcss@8.5.6",
+
"npm:eslint@^9.39.1": "9.39.1",
+
"npm:globals@^16.5.0": "16.5.0",
+
"npm:mdsvex@~0.12.6": "0.12.6_svelte@5.45.2__acorn@8.15.0",
+
"npm:nanoid@^5.1.5": "5.1.6",
+
"npm:node-fetch@^3.3.2": "3.3.2",
+
"npm:postcss@^8.5.6": "8.5.6",
+
"npm:prettier-plugin-svelte@^3.4.0": "3.4.0_prettier@3.7.1_svelte@5.45.2__acorn@8.15.0",
+
"npm:prettier@^3.7.1": "3.7.1",
+
"npm:prometheus-remote-write@~0.5.1": "0.5.1_node-fetch@3.3.2",
+
"npm:robots-parser@^3.0.1": "3.0.1",
+
"npm:rolldown-vite@7.2.5": "7.2.5_@types+node@24.10.1_picomatch@4.0.3",
+
"npm:steamgriddb@^2.2.0": "2.2.1",
+
"npm:svelte-check@^4.3.4": "4.3.4_svelte@5.45.2__acorn@8.15.0_typescript@5.9.3",
+
"npm:svelte@^5.45.2": "5.45.2_acorn@8.15.0",
+
"npm:sveltekit-rate-limiter@0.7": "0.7.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.45.2____acorn@8.15.0___vite@7.2.4____@types+node@24.10.1____picomatch@4.0.3___@types+node@24.10.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__acorn@8.15.0__@types+node@24.10.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1",
+
"npm:tailwindcss@^3.4.17": "3.4.18_postcss@8.5.6_jiti@1.21.7",
+
"npm:toad-scheduler@^3.1.0": "3.1.0",
+
"npm:tslib@^2.8.1": "2.8.1",
+
"npm:typescript-eslint@^8.48.0": "8.48.0_eslint@9.39.1_typescript@5.9.3_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3",
+
"npm:typescript-svelte-plugin@~0.3.50": "0.3.50_svelte@5.45.2__acorn@8.15.0_typescript@5.9.3",
+
"npm:typescript@^5.9.2": "5.9.3",
+
"npm:typescript@~5.9.3": "5.9.3",
+
"npm:vite-plugin-top-level-await@^1.6.0": "1.6.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1",
+
"npm:vite-plugin-wasm@^3.5.0": "3.5.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1",
+
"npm:vite@^7.2.4": "7.2.4_@types+node@24.10.1_picomatch@4.0.3"
+
},
+
"npm": {
+
"@alloc/quick-lru@5.2.0": {
+
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="
+
},
+
"@atcute/atproto@3.1.9": {
+
"integrity": "sha512-DyWwHCTdR4hY2BPNbLXgVmm7lI+fceOwWbE4LXbGvbvVtSn+ejSVFaAv01Ra3kWDha0whsOmbJL8JP0QPpf1+w==",
+
"dependencies": [
+
"@atcute/lexicons"
+
]
+
},
+
"@atcute/bluesky-richtext-builder@2.0.4": {
+
"integrity": "sha512-ydA9VWBPsBE/gbu1vYbmh7AZ8FLfxp+LE4eH5GgOTCOxwhs7Mgy1oHrHY+Er6gu6PfdoUoGso0uI3Wl3ZF/Mxg==",
+
"dependencies": [
+
"@atcute/bluesky",
+
"@atcute/lexicons"
+
]
+
},
+
"@atcute/bluesky@3.2.11": {
+
"integrity": "sha512-AboS6y4t+zaxIq7E4noue10csSpIuk/Uwo30/l6GgGBDPXrd7STw8Yb5nGZQP+TdG/uC8/c2mm7UnY65SDOh6A==",
+
"dependencies": [
+
"@atcute/atproto",
+
"@atcute/lexicons"
+
]
+
},
+
"@atcute/car@3.1.3": {
+
"integrity": "sha512-WJ13bAEt7TjDMVi09ubjLtvhdljbWInGm9Kfy7Y6NhrmiyC/aZYaA/zHX/bHI6xv1c/h3SQduWqxOr4ae49eqA==",
+
"dependencies": [
+
"@atcute/cbor",
+
"@atcute/cid",
+
"@atcute/uint8array",
+
"@atcute/varint",
+
"yocto-queue@1.2.2"
+
]
+
},
+
"@atcute/cbor@2.2.8": {
+
"integrity": "sha512-UzOAN9BuN6JCXgn0ryV8qZuRJUDrNqrbLd6EFM8jc6RYssjRyGRxNy6RZ1NU/07Hd8Tq/0pz8+nQiMu5Zai5uw==",
+
"dependencies": [
+
"@atcute/cid",
+
"@atcute/multibase",
+
"@atcute/uint8array"
+
]
+
},
+
"@atcute/cid@2.2.6": {
+
"integrity": "sha512-bTAHHbJ24p+E//V4KCS4xdmd39o211jJswvqQOevj7vk+5IYcgDLx1ryZWZ1sEPOo9x875li/kj5gpKL14RDwQ==",
+
"dependencies": [
+
"@atcute/multibase",
+
"@atcute/uint8array"
+
]
+
},
+
"@atcute/client@4.1.0": {
+
"integrity": "sha512-AYhSu3RSDA2VDkVGOmad320NRbUUUf5pCFWJcOzlk25YC/4kyzmMFfpzhf1jjjEcY+anNBXGGhav/kKB1evggQ==",
+
"dependencies": [
+
"@atcute/identity",
+
"@atcute/lexicons"
+
]
+
},
+
"@atcute/identity@1.1.3": {
+
"integrity": "sha512-oIqPoI8TwWeQxvcLmFEZLdN2XdWcaLVtlm8pNk0E72As9HNzzD9pwKPrLr3rmTLRIoULPPFmq9iFNsTeCIU9ng==",
+
"dependencies": [
+
"@atcute/lexicons",
+
"@badrap/valita"
+
]
+
},
+
"@atcute/lexicons@1.2.5": {
+
"integrity": "sha512-9yO9WdgxW8jZ7SbzUycH710z+JmsQ9W9n5S6i6eghYju32kkluFmgBeS47r8e8p2+Dv4DemS7o/3SUGsX9FR5Q==",
+
"dependencies": [
+
"@standard-schema/spec",
+
"esm-env"
+
]
+
},
+
"@atcute/multibase@1.1.6": {
+
"integrity": "sha512-HBxuCgYLKPPxETV0Rot4VP9e24vKl8JdzGCZOVsDaOXJgbRZoRIF67Lp0H/OgnJeH/Xpva8Z5ReoTNJE5dn3kg==",
+
"dependencies": [
+
"@atcute/uint8array"
+
]
+
},
+
"@atcute/ozone@3.1.12": {
+
"integrity": "sha512-YMsyZtEG6n3+JfU/2Hdl1niZ7mCS9qM3hfNV1ihGRkJniDAtGxcQDRa2wf0Gd9GrhoIaLhawl2wtcqZqyutpVg==",
+
"dependencies": [
+
"@atcute/atproto",
+
"@atcute/bluesky",
+
"@atcute/lexicons"
+
]
+
},
+
"@atcute/uint8array@1.0.5": {
+
"integrity": "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="
+
},
+
"@atcute/varint@1.0.3": {
+
"integrity": "sha512-fdvMPyBB+McDT+Ai5e9RwEbwYV4yjZ60S2Dn5PTjGqUyxvoCH1z42viuheDZRUDkmfQehXJTZ5az7dSozVNtog=="
+
},
+
"@badrap/valita@0.4.6": {
+
"integrity": "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg=="
+
},
+
"@emnapi/core@1.7.1": {
+
"integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==",
+
"dependencies": [
+
"@emnapi/wasi-threads",
+
"tslib"
+
]
+
},
+
"@emnapi/runtime@1.7.1": {
+
"integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
+
"dependencies": [
+
"tslib"
+
]
+
},
+
"@emnapi/wasi-threads@1.1.0": {
+
"integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+
"dependencies": [
+
"tslib"
+
]
+
},
+
"@esbuild/aix-ppc64@0.25.12": {
+
"integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+
"os": ["aix"],
+
"cpu": ["ppc64"]
+
},
+
"@esbuild/android-arm64@0.25.12": {
+
"integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+
"os": ["android"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/android-arm@0.25.12": {
+
"integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+
"os": ["android"],
+
"cpu": ["arm"]
+
},
+
"@esbuild/android-x64@0.25.12": {
+
"integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+
"os": ["android"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/darwin-arm64@0.25.12": {
+
"integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+
"os": ["darwin"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/darwin-x64@0.25.12": {
+
"integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+
"os": ["darwin"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/freebsd-arm64@0.25.12": {
+
"integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+
"os": ["freebsd"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/freebsd-x64@0.25.12": {
+
"integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+
"os": ["freebsd"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/linux-arm64@0.25.12": {
+
"integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/linux-arm@0.25.12": {
+
"integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+
"os": ["linux"],
+
"cpu": ["arm"]
+
},
+
"@esbuild/linux-ia32@0.25.12": {
+
"integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+
"os": ["linux"],
+
"cpu": ["ia32"]
+
},
+
"@esbuild/linux-loong64@0.25.12": {
+
"integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+
"os": ["linux"],
+
"cpu": ["loong64"]
+
},
+
"@esbuild/linux-mips64el@0.25.12": {
+
"integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+
"os": ["linux"],
+
"cpu": ["mips64el"]
+
},
+
"@esbuild/linux-ppc64@0.25.12": {
+
"integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+
"os": ["linux"],
+
"cpu": ["ppc64"]
+
},
+
"@esbuild/linux-riscv64@0.25.12": {
+
"integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+
"os": ["linux"],
+
"cpu": ["riscv64"]
+
},
+
"@esbuild/linux-s390x@0.25.12": {
+
"integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+
"os": ["linux"],
+
"cpu": ["s390x"]
+
},
+
"@esbuild/linux-x64@0.25.12": {
+
"integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/netbsd-arm64@0.25.12": {
+
"integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+
"os": ["netbsd"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/netbsd-x64@0.25.12": {
+
"integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+
"os": ["netbsd"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/openbsd-arm64@0.25.12": {
+
"integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+
"os": ["openbsd"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/openbsd-x64@0.25.12": {
+
"integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+
"os": ["openbsd"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/openharmony-arm64@0.25.12": {
+
"integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+
"os": ["openharmony"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/sunos-x64@0.25.12": {
+
"integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+
"os": ["sunos"],
+
"cpu": ["x64"]
+
},
+
"@esbuild/win32-arm64@0.25.12": {
+
"integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+
"os": ["win32"],
+
"cpu": ["arm64"]
+
},
+
"@esbuild/win32-ia32@0.25.12": {
+
"integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+
"os": ["win32"],
+
"cpu": ["ia32"]
+
},
+
"@esbuild/win32-x64@0.25.12": {
+
"integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+
"os": ["win32"],
+
"cpu": ["x64"]
+
},
+
"@eslint-community/eslint-utils@4.9.0_eslint@9.39.1": {
+
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+
"dependencies": [
+
"eslint",
+
"eslint-visitor-keys@3.4.3"
+
]
+
},
+
"@eslint-community/regexpp@4.12.2": {
+
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="
+
},
+
"@eslint/config-array@0.21.1": {
+
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
+
"dependencies": [
+
"@eslint/object-schema",
+
"debug",
+
"minimatch@3.1.2"
+
]
+
},
+
"@eslint/config-helpers@0.4.2": {
+
"integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+
"dependencies": [
+
"@eslint/core"
+
]
+
},
+
"@eslint/core@0.17.0": {
+
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+
"dependencies": [
+
"@types/json-schema"
+
]
+
},
+
"@eslint/eslintrc@3.3.1": {
+
"integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+
"dependencies": [
+
"ajv",
+
"debug",
+
"espree",
+
"globals@14.0.0",
+
"ignore@5.3.2",
+
"import-fresh",
+
"js-yaml",
+
"minimatch@3.1.2",
+
"strip-json-comments"
+
]
+
},
+
"@eslint/js@9.39.1": {
+
"integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw=="
+
},
+
"@eslint/object-schema@2.1.7": {
+
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="
+
},
+
"@eslint/plugin-kit@0.4.1": {
+
"integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+
"dependencies": [
+
"@eslint/core",
+
"levn"
+
]
+
},
+
"@humanfs/core@0.19.1": {
+
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="
+
},
+
"@humanfs/node@0.16.7": {
+
"integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+
"dependencies": [
+
"@humanfs/core",
+
"@humanwhocodes/retry"
+
]
+
},
+
"@humanwhocodes/module-importer@1.0.1": {
+
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="
+
},
+
"@humanwhocodes/retry@0.4.3": {
+
"integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="
+
},
+
"@isaacs/ttlcache@1.4.1": {
+
"integrity": "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="
+
},
+
"@jridgewell/gen-mapping@0.3.13": {
+
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+
"dependencies": [
+
"@jridgewell/sourcemap-codec",
+
"@jridgewell/trace-mapping"
+
]
+
},
+
"@jridgewell/remapping@2.3.5": {
+
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
+
"dependencies": [
+
"@jridgewell/gen-mapping",
+
"@jridgewell/trace-mapping"
+
]
+
},
+
"@jridgewell/resolve-uri@3.1.2": {
+
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="
+
},
+
"@jridgewell/sourcemap-codec@1.5.5": {
+
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="
+
},
+
"@jridgewell/trace-mapping@0.3.31": {
+
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+
"dependencies": [
+
"@jridgewell/resolve-uri",
+
"@jridgewell/sourcemap-codec"
+
]
+
},
+
"@jsr/std__collections@1.1.3": {
+
"integrity": "sha512-jGG6mv3IjOyxm6PyT1YVbLyAlZL+Gow6LOpBw+84qb1nkdJY0+t6bi7ICEqAwUz87cNjBS0P+yZQ5HHclJhsfw==",
+
"tarball": "https://npm.jsr.io/~/11/@jsr/std__collections/1.1.3.tgz"
+
},
+
"@jsr/std__toml@1.0.11": {
+
"integrity": "sha512-+LZAizoPAPwMDmRZr86/xPrbO8E0Oq0BJ70mr1fNMobJ/6X6v15Jk16ZClFGukWgzBMd8ggiMWnzp24+N3VNZg==",
+
"dependencies": [
+
"@jsr/std__collections"
+
],
+
"tarball": "https://npm.jsr.io/~/11/@jsr/std__toml/1.0.11.tgz"
+
},
+
"@napi-rs/wasm-runtime@1.1.0": {
+
"integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==",
+
"dependencies": [
+
"@emnapi/core",
+
"@emnapi/runtime",
+
"@tybys/wasm-util"
+
]
+
},
+
"@neodrag/svelte@2.3.3_svelte@5.45.2__acorn@8.15.0": {
+
"integrity": "sha512-avXzhrilsBsnMFljhVAQ7h+6hbSIrvRCJ61GCiGbGISkC1QOhjDCNvPZo2+7KVwiYrnUBx4NRH0kTIqrcxv9Lg==",
+
"dependencies": [
+
"svelte"
+
]
+
},
+
"@nodelib/fs.scandir@2.1.5": {
+
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+
"dependencies": [
+
"@nodelib/fs.stat",
+
"run-parallel"
+
]
+
},
+
"@nodelib/fs.stat@2.0.5": {
+
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
+
},
+
"@nodelib/fs.walk@1.2.8": {
+
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+
"dependencies": [
+
"@nodelib/fs.scandir",
+
"fastq"
+
]
+
},
+
"@oxc-project/runtime@0.97.0": {
+
"integrity": "sha512-yH0zw7z+jEws4dZ4IUKoix5Lh3yhqIJWF9Dc8PWvhpo7U7O+lJrv7ZZL4BeRO0la8LBQFwcCewtLBnVV7hPe/w=="
+
},
+
"@oxc-project/types@0.97.0": {
+
"integrity": "sha512-lxmZK4xFrdvU0yZiDwgVQTCvh2gHWBJCBk5ALsrtsBWhs0uDIi+FTOnXRQeQfs304imdvTdaakT/lqwQ8hkOXQ=="
+
},
+
"@polka/url@1.0.0-next.29": {
+
"integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="
+
},
+
"@protobufjs/aspromise@1.1.2": {
+
"integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+
},
+
"@protobufjs/base64@1.1.2": {
+
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+
},
+
"@protobufjs/codegen@2.0.4": {
+
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+
},
+
"@protobufjs/eventemitter@1.1.0": {
+
"integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+
},
+
"@protobufjs/fetch@1.1.0": {
+
"integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+
"dependencies": [
+
"@protobufjs/aspromise",
+
"@protobufjs/inquire"
+
]
+
},
+
"@protobufjs/float@1.0.2": {
+
"integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+
},
+
"@protobufjs/inquire@1.1.0": {
+
"integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+
},
+
"@protobufjs/path@1.1.2": {
+
"integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+
},
+
"@protobufjs/pool@1.1.0": {
+
"integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+
},
+
"@protobufjs/utf8@1.1.0": {
+
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+
},
+
"@rolldown/binding-android-arm64@1.0.0-beta.50": {
+
"integrity": "sha512-XlEkrOIHLyGT3avOgzfTFSjG+f+dZMw+/qd+Y3HLN86wlndrB/gSimrJCk4gOhr1XtRtEKfszpadI3Md4Z4/Ag==",
+
"os": ["android"],
+
"cpu": ["arm64"]
+
},
+
"@rolldown/binding-darwin-arm64@1.0.0-beta.50": {
+
"integrity": "sha512-+JRqKJhoFlt5r9q+DecAGPLZ5PxeLva+wCMtAuoFMWPoZzgcYrr599KQ+Ix0jwll4B4HGP43avu9My8KtSOR+w==",
+
"os": ["darwin"],
+
"cpu": ["arm64"]
+
},
+
"@rolldown/binding-darwin-x64@1.0.0-beta.50": {
+
"integrity": "sha512-fFXDjXnuX7/gQZQm/1FoivVtRcyAzdjSik7Eo+9iwPQ9EgtA5/nB2+jmbzaKtMGG3q+BnZbdKHCtOacmNrkIDA==",
+
"os": ["darwin"],
+
"cpu": ["x64"]
+
},
+
"@rolldown/binding-freebsd-x64@1.0.0-beta.50": {
+
"integrity": "sha512-F1b6vARy49tjmT/hbloplzgJS7GIvwWZqt+tAHEstCh0JIh9sa8FAMVqEmYxDviqKBaAI8iVvUREm/Kh/PD26Q==",
+
"os": ["freebsd"],
+
"cpu": ["x64"]
+
},
+
"@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.50": {
+
"integrity": "sha512-U6cR76N8T8M6lHj7EZrQ3xunLPxSvYYxA8vJsBKZiFZkT8YV4kjgCO3KwMJL0NOjQCPGKyiXO07U+KmJzdPGRw==",
+
"os": ["linux"],
+
"cpu": ["arm"]
+
},
+
"@rolldown/binding-linux-arm64-gnu@1.0.0-beta.50": {
+
"integrity": "sha512-ONgyjofCrrE3bnh5GZb8EINSFyR/hmwTzZ7oVuyUB170lboza1VMCnb8jgE6MsyyRgHYmN8Lb59i3NKGrxrYjw==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@rolldown/binding-linux-arm64-musl@1.0.0-beta.50": {
+
"integrity": "sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@rolldown/binding-linux-x64-gnu@1.0.0-beta.50": {
+
"integrity": "sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@rolldown/binding-linux-x64-musl@1.0.0-beta.50": {
+
"integrity": "sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@rolldown/binding-openharmony-arm64@1.0.0-beta.50": {
+
"integrity": "sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA==",
+
"os": ["openharmony"],
+
"cpu": ["arm64"]
+
},
+
"@rolldown/binding-wasm32-wasi@1.0.0-beta.50": {
+
"integrity": "sha512-nmCN0nIdeUnmgeDXiQ+2HU6FT162o+rxnF7WMkBm4M5Ds8qTU7Dzv2Wrf22bo4ftnlrb2hKK6FSwAJSAe2FWLg==",
+
"dependencies": [
+
"@napi-rs/wasm-runtime"
+
],
+
"cpu": ["wasm32"]
+
},
+
"@rolldown/binding-win32-arm64-msvc@1.0.0-beta.50": {
+
"integrity": "sha512-7kcNLi7Ua59JTTLvbe1dYb028QEPaJPJQHqkmSZ5q3tJueUeb6yjRtx8mw4uIqgWZcnQHAR3PrLN4XRJxvgIkA==",
+
"os": ["win32"],
+
"cpu": ["arm64"]
+
},
+
"@rolldown/binding-win32-ia32-msvc@1.0.0-beta.50": {
+
"integrity": "sha512-lL70VTNvSCdSZkDPPVMwWn/M2yQiYvSoXw9hTLgdIWdUfC3g72UaruezusR6ceRuwHCY1Ayu2LtKqXkBO5LIwg==",
+
"os": ["win32"],
+
"cpu": ["ia32"]
+
},
+
"@rolldown/binding-win32-x64-msvc@1.0.0-beta.50": {
+
"integrity": "sha512-4qU4x5DXWB4JPjyTne/wBNPqkbQU8J45bl21geERBKtEittleonioACBL1R0PsBu0Aq21SwMK5a9zdBkWSlQtQ==",
+
"os": ["win32"],
+
"cpu": ["x64"]
+
},
+
"@rolldown/pluginutils@1.0.0-beta.50": {
+
"integrity": "sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA=="
+
},
+
"@rollup/plugin-commonjs@28.0.9_rollup@4.53.3_picomatch@4.0.3": {
+
"integrity": "sha512-PIR4/OHZ79romx0BVVll/PkwWpJ7e5lsqFa3gFfcrFPWwLXLV39JVUzQV9RKjWerE7B845Hqjj9VYlQeieZ2dA==",
+
"dependencies": [
+
"@rollup/pluginutils",
+
"commondir",
+
"estree-walker",
+
"fdir",
+
"is-reference@1.2.1",
+
"magic-string",
+
"picomatch@4.0.3",
+
"rollup"
+
],
+
"optionalPeers": [
+
"rollup"
+
]
+
},
+
"@rollup/plugin-json@6.1.0_rollup@4.53.3": {
+
"integrity": "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==",
+
"dependencies": [
+
"@rollup/pluginutils",
+
"rollup"
+
],
+
"optionalPeers": [
+
"rollup"
+
]
+
},
+
"@rollup/plugin-node-resolve@16.0.3_rollup@4.53.3": {
+
"integrity": "sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==",
+
"dependencies": [
+
"@rollup/pluginutils",
+
"@types/resolve",
+
"deepmerge",
+
"is-module",
+
"resolve",
+
"rollup"
+
],
+
"optionalPeers": [
+
"rollup"
+
]
+
},
+
"@rollup/plugin-virtual@3.0.2": {
+
"integrity": "sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A=="
+
},
+
"@rollup/pluginutils@5.3.0_rollup@4.53.3": {
+
"integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==",
+
"dependencies": [
+
"@types/estree",
+
"estree-walker",
+
"picomatch@4.0.3",
+
"rollup"
+
],
+
"optionalPeers": [
+
"rollup"
+
]
+
},
+
"@rollup/rollup-android-arm-eabi@4.53.3": {
+
"integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
+
"os": ["android"],
+
"cpu": ["arm"]
+
},
+
"@rollup/rollup-android-arm64@4.53.3": {
+
"integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
+
"os": ["android"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-darwin-arm64@4.53.3": {
+
"integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
+
"os": ["darwin"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-darwin-x64@4.53.3": {
+
"integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
+
"os": ["darwin"],
+
"cpu": ["x64"]
+
},
+
"@rollup/rollup-freebsd-arm64@4.53.3": {
+
"integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
+
"os": ["freebsd"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-freebsd-x64@4.53.3": {
+
"integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
+
"os": ["freebsd"],
+
"cpu": ["x64"]
+
},
+
"@rollup/rollup-linux-arm-gnueabihf@4.53.3": {
+
"integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
+
"os": ["linux"],
+
"cpu": ["arm"]
+
},
+
"@rollup/rollup-linux-arm-musleabihf@4.53.3": {
+
"integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
+
"os": ["linux"],
+
"cpu": ["arm"]
+
},
+
"@rollup/rollup-linux-arm64-gnu@4.53.3": {
+
"integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-linux-arm64-musl@4.53.3": {
+
"integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-linux-loong64-gnu@4.53.3": {
+
"integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
+
"os": ["linux"],
+
"cpu": ["loong64"]
+
},
+
"@rollup/rollup-linux-ppc64-gnu@4.53.3": {
+
"integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
+
"os": ["linux"],
+
"cpu": ["ppc64"]
+
},
+
"@rollup/rollup-linux-riscv64-gnu@4.53.3": {
+
"integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
+
"os": ["linux"],
+
"cpu": ["riscv64"]
+
},
+
"@rollup/rollup-linux-riscv64-musl@4.53.3": {
+
"integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
+
"os": ["linux"],
+
"cpu": ["riscv64"]
+
},
+
"@rollup/rollup-linux-s390x-gnu@4.53.3": {
+
"integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
+
"os": ["linux"],
+
"cpu": ["s390x"]
+
},
+
"@rollup/rollup-linux-x64-gnu@4.53.3": {
+
"integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@rollup/rollup-linux-x64-musl@4.53.3": {
+
"integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@rollup/rollup-openharmony-arm64@4.53.3": {
+
"integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
+
"os": ["openharmony"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-win32-arm64-msvc@4.53.3": {
+
"integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
+
"os": ["win32"],
+
"cpu": ["arm64"]
+
},
+
"@rollup/rollup-win32-ia32-msvc@4.53.3": {
+
"integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
+
"os": ["win32"],
+
"cpu": ["ia32"]
+
},
+
"@rollup/rollup-win32-x64-gnu@4.53.3": {
+
"integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
+
"os": ["win32"],
+
"cpu": ["x64"]
+
},
+
"@rollup/rollup-win32-x64-msvc@4.53.3": {
+
"integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
+
"os": ["win32"],
+
"cpu": ["x64"]
+
},
+
"@rowanmanning/feed-parser@2.1.1": {
+
"integrity": "sha512-OFxb37OaQ8ki1VQt/FtrDw74nY2epU9He0QOCzkfc/FxbeulCJo7SbZNiDw2ruwnISuO7PhDsZ69DdWzCVEIsA==",
+
"dependencies": [
+
"fast-xml-parser",
+
"html-entities"
+
]
+
},
+
"@skyware/bot@0.4.0": {
+
"integrity": "sha512-xbodXxB0PRqOwaB/llbdX1sZ9wqIXZhTxwPl77XL9BAP5/SI1DbM0wvo7qwkmI4CBBakE6Hp7ZYj0pyYDb81Uw==",
+
"dependencies": [
+
"@atcute/atproto",
+
"@atcute/bluesky",
+
"@atcute/bluesky-richtext-builder",
+
"@atcute/client",
+
"@atcute/lexicons",
+
"@atcute/ozone",
+
"quick-lru",
+
"rate-limit-threshold"
+
],
+
"optionalDependencies": [
+
"@skyware/firehose",
+
"@skyware/jetstream"
+
]
+
},
+
"@skyware/firehose@0.5.2": {
+
"integrity": "sha512-Ayg/cF0BkakBNQVA51ClDka0+nC96WiARNrGElMQxfqbwao0PBaCXkunfr8qS4DWS3TqLnR6hA9mvm1vAYlxJQ==",
+
"dependencies": [
+
"@atcute/car",
+
"@atcute/cbor",
+
"nanoevents"
+
]
+
},
+
"@skyware/jetstream@0.2.5": {
+
"integrity": "sha512-fM/zs03DLwqRyzZZJFWN20e76KrdqIp97Tlm8Cek+vxn96+tu5d/fx79V6H85L0QN6HvGiX2l9A8hWFqHvYlOA==",
+
"dependencies": [
+
"@atcute/atproto",
+
"@atcute/bluesky",
+
"@atcute/lexicons",
+
"partysocket",
+
"tiny-emitter"
+
]
+
},
+
"@standard-schema/spec@1.0.0": {
+
"integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="
+
},
+
"@sveltejs/acorn-typescript@1.0.7_acorn@8.15.0": {
+
"integrity": "sha512-znp1A/Y1Jj4l/Zy7PX5DZKBE0ZNY+5QBngiE21NJkfSTyzzC5iKNWOtwFXKtIrn7MXEFBck4jD95iBNkGjK92Q==",
+
"dependencies": [
+
"acorn"
+
]
+
},
+
"@sveltejs/adapter-node@5.4.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.45.2____acorn@8.15.0___vite@7.2.4____@types+node@24.10.1____picomatch@4.0.3___@types+node@24.10.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__acorn@8.15.0__@types+node@24.10.1_rollup@4.53.3_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-NMsrwGVPEn+J73zH83Uhss/hYYZN6zT3u31R3IHAn3MiKC3h8fjmIAhLfTSOeNHr5wPYfjjMg8E+1gyFgyrEcQ==",
+
"dependencies": [
+
"@rollup/plugin-commonjs",
+
"@rollup/plugin-json",
+
"@rollup/plugin-node-resolve",
+
"@sveltejs/kit",
+
"rollup"
+
]
+
},
+
"@sveltejs/kit@2.49.0_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_acorn@8.15.0_@types+node@24.10.1": {
+
"integrity": "sha512-oH8tXw7EZnie8FdOWYrF7Yn4IKrqTFHhXvl8YxXxbKwTMcD/5NNCryUSEXRk2ZR4ojnub0P8rNrsVGHXWqIDtA==",
+
"dependencies": [
+
"@standard-schema/spec",
+
"@sveltejs/acorn-typescript",
+
"@sveltejs/vite-plugin-svelte",
+
"@types/cookie",
+
"acorn",
+
"cookie",
+
"devalue",
+
"esm-env",
+
"kleur",
+
"magic-string",
+
"mrmime",
+
"sade",
+
"set-cookie-parser",
+
"sirv",
+
"svelte",
+
"vite"
+
],
+
"bin": true
+
},
+
"@sveltejs/vite-plugin-svelte-inspector@5.0.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-ubWshlMk4bc8mkwWbg6vNvCeT7lGQojE3ijDh3QTR6Zr/R+GXxsGbyH4PExEPpiFmqPhYiVSVmHBjUcVc1JIrA==",
+
"dependencies": [
+
"@sveltejs/vite-plugin-svelte",
+
"debug",
+
"svelte",
+
"vite"
+
]
+
},
+
"@sveltejs/vite-plugin-svelte@6.2.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ==",
+
"dependencies": [
+
"@sveltejs/vite-plugin-svelte-inspector",
+
"debug",
+
"deepmerge",
+
"magic-string",
+
"svelte",
+
"vite",
+
"vitefu"
+
]
+
},
+
"@swc/core-darwin-arm64@1.15.3": {
+
"integrity": "sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ==",
+
"os": ["darwin"],
+
"cpu": ["arm64"]
+
},
+
"@swc/core-darwin-x64@1.15.3": {
+
"integrity": "sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A==",
+
"os": ["darwin"],
+
"cpu": ["x64"]
+
},
+
"@swc/core-linux-arm-gnueabihf@1.15.3": {
+
"integrity": "sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg==",
+
"os": ["linux"],
+
"cpu": ["arm"]
+
},
+
"@swc/core-linux-arm64-gnu@1.15.3": {
+
"integrity": "sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@swc/core-linux-arm64-musl@1.15.3": {
+
"integrity": "sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"@swc/core-linux-x64-gnu@1.15.3": {
+
"integrity": "sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@swc/core-linux-x64-musl@1.15.3": {
+
"integrity": "sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"@swc/core-win32-arm64-msvc@1.15.3": {
+
"integrity": "sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==",
+
"os": ["win32"],
+
"cpu": ["arm64"]
+
},
+
"@swc/core-win32-ia32-msvc@1.15.3": {
+
"integrity": "sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw==",
+
"os": ["win32"],
+
"cpu": ["ia32"]
+
},
+
"@swc/core-win32-x64-msvc@1.15.3": {
+
"integrity": "sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog==",
+
"os": ["win32"],
+
"cpu": ["x64"]
+
},
+
"@swc/core@1.15.3": {
+
"integrity": "sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q==",
+
"dependencies": [
+
"@swc/counter",
+
"@swc/types"
+
],
+
"optionalDependencies": [
+
"@swc/core-darwin-arm64",
+
"@swc/core-darwin-x64",
+
"@swc/core-linux-arm-gnueabihf",
+
"@swc/core-linux-arm64-gnu",
+
"@swc/core-linux-arm64-musl",
+
"@swc/core-linux-x64-gnu",
+
"@swc/core-linux-x64-musl",
+
"@swc/core-win32-arm64-msvc",
+
"@swc/core-win32-ia32-msvc",
+
"@swc/core-win32-x64-msvc"
+
],
+
"scripts": true
+
},
+
"@swc/counter@0.1.3": {
+
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
+
},
+
"@swc/types@0.1.25": {
+
"integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
+
"dependencies": [
+
"@swc/counter"
+
]
+
},
+
"@swc/wasm@1.15.3": {
+
"integrity": "sha512-NrjGmAplk+v4wokIaLxp1oLoCMVqdQcWoBXopQg57QqyPRcJXLKe+kg5ehhW6z8XaU4Bu5cRkDxUTDY5P0Zy9Q=="
+
},
+
"@tailwindcss/forms@0.5.10_tailwindcss@3.4.18__postcss@8.5.6__jiti@1.21.7": {
+
"integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==",
+
"dependencies": [
+
"mini-svg-data-uri",
+
"tailwindcss"
+
]
+
},
+
"@tailwindcss/typography@0.5.19_tailwindcss@3.4.18__postcss@8.5.6__jiti@1.21.7": {
+
"integrity": "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==",
+
"dependencies": [
+
"postcss-selector-parser@6.0.10",
+
"tailwindcss"
+
]
+
},
+
"@tybys/wasm-util@0.10.1": {
+
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+
"dependencies": [
+
"tslib"
+
]
+
},
+
"@types/cookie@0.6.0": {
+
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
+
},
+
"@types/deno@2.5.0": {
+
"integrity": "sha512-g8JS38vmc0S87jKsFzre+0ZyMOUDHPVokEJymSCRlL57h6f/FdKPWBXgdFh3Z8Ees9sz11qt9VWELU9Y9ZkiVw=="
+
},
+
"@types/eslint@9.6.1": {
+
"integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
+
"dependencies": [
+
"@types/estree",
+
"@types/json-schema"
+
]
+
},
+
"@types/estree@1.0.8": {
+
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="
+
},
+
"@types/json-schema@7.0.15": {
+
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
+
},
+
"@types/mdast@4.0.4": {
+
"integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+
"dependencies": [
+
"@types/unist"
+
]
+
},
+
"@types/node-schedule@2.1.8": {
+
"integrity": "sha512-k00g6Yj/oUg/CDC+MeLHUzu0+OFxWbIqrFfDiLi6OPKxTujvpv29mHGM8GtKr7B+9Vv92FcK/8mRqi1DK5f3hA==",
+
"dependencies": [
+
"@types/node@22.15.15"
+
]
+
},
+
"@types/node@22.15.15": {
+
"integrity": "sha512-R5muMcZob3/Jjchn5LcO8jdKwSCbzqmPB6ruBxMcf9kbxtniZHP327s6C37iOfuw8mbKK3cAQa7sEl7afLrQ8A==",
+
"dependencies": [
+
"undici-types@6.21.0"
+
]
+
},
+
"@types/node@24.10.1": {
+
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
+
"dependencies": [
+
"undici-types@7.16.0"
+
]
+
},
+
"@types/resolve@1.20.2": {
+
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
+
},
+
"@types/unist@2.0.11": {
+
"integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="
+
},
+
"@typescript-eslint/eslint-plugin@8.48.0_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3_eslint@9.39.1_typescript@5.9.3": {
+
"integrity": "sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==",
+
"dependencies": [
+
"@eslint-community/regexpp",
+
"@typescript-eslint/parser",
+
"@typescript-eslint/scope-manager",
+
"@typescript-eslint/type-utils",
+
"@typescript-eslint/utils",
+
"@typescript-eslint/visitor-keys",
+
"eslint",
+
"graphemer",
+
"ignore@7.0.5",
+
"natural-compare",
+
"ts-api-utils",
+
"typescript"
+
]
+
},
+
"@typescript-eslint/parser@8.48.0_eslint@9.39.1_typescript@5.9.3": {
+
"integrity": "sha512-jCzKdm/QK0Kg4V4IK/oMlRZlY+QOcdjv89U2NgKHZk1CYTj82/RVSx1mV/0gqCVMJ/DA+Zf/S4NBWNF8GQ+eqQ==",
+
"dependencies": [
+
"@typescript-eslint/scope-manager",
+
"@typescript-eslint/types",
+
"@typescript-eslint/typescript-estree",
+
"@typescript-eslint/visitor-keys",
+
"debug",
+
"eslint",
+
"typescript"
+
]
+
},
+
"@typescript-eslint/project-service@8.48.0_typescript@5.9.3": {
+
"integrity": "sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==",
+
"dependencies": [
+
"@typescript-eslint/tsconfig-utils",
+
"@typescript-eslint/types",
+
"debug",
+
"typescript"
+
]
+
},
+
"@typescript-eslint/scope-manager@8.48.0": {
+
"integrity": "sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==",
+
"dependencies": [
+
"@typescript-eslint/types",
+
"@typescript-eslint/visitor-keys"
+
]
+
},
+
"@typescript-eslint/tsconfig-utils@8.48.0_typescript@5.9.3": {
+
"integrity": "sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==",
+
"dependencies": [
+
"typescript"
+
]
+
},
+
"@typescript-eslint/type-utils@8.48.0_eslint@9.39.1_typescript@5.9.3": {
+
"integrity": "sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==",
+
"dependencies": [
+
"@typescript-eslint/types",
+
"@typescript-eslint/typescript-estree",
+
"@typescript-eslint/utils",
+
"debug",
+
"eslint",
+
"ts-api-utils",
+
"typescript"
+
]
+
},
+
"@typescript-eslint/types@8.48.0": {
+
"integrity": "sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA=="
+
},
+
"@typescript-eslint/typescript-estree@8.48.0_typescript@5.9.3": {
+
"integrity": "sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==",
+
"dependencies": [
+
"@typescript-eslint/project-service",
+
"@typescript-eslint/tsconfig-utils",
+
"@typescript-eslint/types",
+
"@typescript-eslint/visitor-keys",
+
"debug",
+
"minimatch@9.0.5",
+
"semver",
+
"tinyglobby",
+
"ts-api-utils",
+
"typescript"
+
]
+
},
+
"@typescript-eslint/utils@8.48.0_eslint@9.39.1_typescript@5.9.3": {
+
"integrity": "sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==",
+
"dependencies": [
+
"@eslint-community/eslint-utils",
+
"@typescript-eslint/scope-manager",
+
"@typescript-eslint/types",
+
"@typescript-eslint/typescript-estree",
+
"eslint",
+
"typescript"
+
]
+
},
+
"@typescript-eslint/visitor-keys@8.48.0": {
+
"integrity": "sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==",
+
"dependencies": [
+
"@typescript-eslint/types",
+
"eslint-visitor-keys@4.2.1"
+
]
+
},
+
"@xterm/addon-canvas@0.7.0_@xterm+xterm@5.5.0": {
+
"integrity": "sha512-LF5LYcfvefJuJ7QotNRdRSPc9YASAVDeoT5uyXS/nZshZXjYplGXRECBGiznwvhNL2I8bq1Lf5MzRwstsYQ2Iw==",
+
"dependencies": [
+
"@xterm/xterm"
+
]
+
},
+
"@xterm/addon-fit@0.10.0_@xterm+xterm@5.5.0": {
+
"integrity": "sha512-UFYkDm4HUahf2lnEyHvio51TNGiLK66mqP2JoATy7hRZeXaGMRDr00JiSF7m63vR5WKATF605yEggJKsw0JpMQ==",
+
"dependencies": [
+
"@xterm/xterm"
+
]
+
},
+
"@xterm/addon-web-links@0.11.0_@xterm+xterm@5.5.0": {
+
"integrity": "sha512-nIHQ38pQI+a5kXnRaTgwqSHnX7KE6+4SVoceompgHL26unAxdfP6IPqUTSYPQgSwM56hsElfoNrrW5V7BUED/Q==",
+
"dependencies": [
+
"@xterm/xterm"
+
]
+
},
+
"@xterm/addon-webgl@0.18.0_@xterm+xterm@5.5.0": {
+
"integrity": "sha512-xCnfMBTI+/HKPdRnSOHaJDRqEpq2Ugy8LEj9GiY4J3zJObo3joylIFaMvzBwbYRg8zLtkO0KQaStCeSfoaI2/w==",
+
"dependencies": [
+
"@xterm/xterm"
+
]
+
},
+
"@xterm/xterm@5.5.0": {
+
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A=="
+
},
+
"acorn-jsx@5.3.2_acorn@8.15.0": {
+
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+
"dependencies": [
+
"acorn"
+
]
+
},
+
"acorn@8.15.0": {
+
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+
"bin": true
+
},
+
"ajv@6.12.6": {
+
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+
"dependencies": [
+
"fast-deep-equal",
+
"fast-json-stable-stringify",
+
"json-schema-traverse",
+
"uri-js"
+
]
+
},
+
"ansi-styles@4.3.0": {
+
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+
"dependencies": [
+
"color-convert"
+
]
+
},
+
"any-promise@1.3.0": {
+
"integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
+
},
+
"anymatch@3.1.3": {
+
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+
"dependencies": [
+
"normalize-path",
+
"picomatch@2.3.1"
+
]
+
},
+
"arg@5.0.2": {
+
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="
+
},
+
"argparse@2.0.1": {
+
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+
},
+
"aria-query@5.3.2": {
+
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="
+
},
+
"asynckit@0.4.0": {
+
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+
},
+
"autoprefixer@10.4.22_postcss@8.5.6": {
+
"integrity": "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==",
+
"dependencies": [
+
"browserslist",
+
"caniuse-lite",
+
"fraction.js",
+
"normalize-range",
+
"picocolors",
+
"postcss",
+
"postcss-value-parser"
+
],
+
"bin": true
+
},
+
"axios@1.13.2": {
+
"integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==",
+
"dependencies": [
+
"follow-redirects",
+
"form-data",
+
"proxy-from-env"
+
]
+
},
+
"axobject-query@4.1.0": {
+
"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="
+
},
+
"balanced-match@1.0.2": {
+
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+
},
+
"baseline-browser-mapping@2.8.31": {
+
"integrity": "sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==",
+
"bin": true
+
},
+
"binary-extensions@2.3.0": {
+
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
+
},
+
"brace-expansion@1.1.12": {
+
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+
"dependencies": [
+
"balanced-match",
+
"concat-map"
+
]
+
},
+
"brace-expansion@2.0.2": {
+
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+
"dependencies": [
+
"balanced-match"
+
]
+
},
+
"braces@3.0.3": {
+
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+
"dependencies": [
+
"fill-range"
+
]
+
},
+
"browserslist@4.28.0": {
+
"integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==",
+
"dependencies": [
+
"baseline-browser-mapping",
+
"caniuse-lite",
+
"electron-to-chromium",
+
"node-releases",
+
"update-browserslist-db"
+
],
+
"bin": true
+
},
+
"call-bind-apply-helpers@1.0.2": {
+
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+
"dependencies": [
+
"es-errors",
+
"function-bind"
+
]
+
},
+
"callsites@3.1.0": {
+
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
+
},
+
"camelcase-css@2.0.1": {
+
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="
+
},
+
"caniuse-lite@1.0.30001757": {
+
"integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ=="
+
},
+
"chalk@4.1.2": {
+
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+
"dependencies": [
+
"ansi-styles",
+
"supports-color"
+
]
+
},
+
"chokidar@3.6.0": {
+
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+
"dependencies": [
+
"anymatch",
+
"braces",
+
"glob-parent@5.1.2",
+
"is-binary-path",
+
"is-glob",
+
"normalize-path",
+
"readdirp@3.6.0"
+
],
+
"optionalDependencies": [
+
"fsevents"
+
]
+
},
+
"chokidar@4.0.3": {
+
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+
"dependencies": [
+
"readdirp@4.1.2"
+
]
+
},
+
"clsx@2.1.1": {
+
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="
+
},
+
"color-convert@2.0.1": {
+
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+
"dependencies": [
+
"color-name"
+
]
+
},
+
"color-name@1.1.4": {
+
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+
},
+
"combined-stream@1.0.8": {
+
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+
"dependencies": [
+
"delayed-stream"
+
]
+
},
+
"commander@4.1.1": {
+
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="
+
},
+
"commondir@1.0.1": {
+
"integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="
+
},
+
"concat-map@0.0.1": {
+
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+
},
+
"cookie@0.6.0": {
+
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="
+
},
+
"croner@8.1.2": {
+
"integrity": "sha512-ypfPFcAXHuAZRCzo3vJL6ltENzniTjwe/qsLleH1V2/7SRDjgvRQyrLmumFTLmjFax4IuSxfGXEn79fozXcJog=="
+
},
+
"cross-spawn@7.0.6": {
+
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+
"dependencies": [
+
"path-key",
+
"shebang-command",
+
"which"
+
]
+
},
+
"cssesc@3.0.0": {
+
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+
"bin": true
+
},
+
"data-uri-to-buffer@4.0.1": {
+
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="
+
},
+
"debug@4.4.3": {
+
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+
"dependencies": [
+
"ms"
+
]
+
},
+
"dedent-js@1.0.1": {
+
"integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ=="
+
},
+
"deep-is@0.1.4": {
+
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+
},
+
"deepmerge@4.3.1": {
+
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
+
},
+
"delayed-stream@1.0.0": {
+
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+
},
+
"detect-libc@2.1.2": {
+
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="
+
},
+
"devalue@5.5.0": {
+
"integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w=="
+
},
+
"didyoumean@1.2.2": {
+
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="
+
},
+
"dlv@1.1.3": {
+
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
+
},
+
"dunder-proto@1.0.1": {
+
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+
"dependencies": [
+
"call-bind-apply-helpers",
+
"es-errors",
+
"gopd"
+
]
+
},
+
"electron-to-chromium@1.5.262": {
+
"integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ=="
+
},
+
"es-define-property@1.0.1": {
+
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
+
},
+
"es-errors@1.3.0": {
+
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
+
},
+
"es-object-atoms@1.1.1": {
+
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+
"dependencies": [
+
"es-errors"
+
]
+
},
+
"es-set-tostringtag@2.1.0": {
+
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+
"dependencies": [
+
"es-errors",
+
"get-intrinsic",
+
"has-tostringtag",
+
"hasown"
+
]
+
},
+
"esbuild@0.25.12": {
+
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+
"optionalDependencies": [
+
"@esbuild/aix-ppc64",
+
"@esbuild/android-arm",
+
"@esbuild/android-arm64",
+
"@esbuild/android-x64",
+
"@esbuild/darwin-arm64",
+
"@esbuild/darwin-x64",
+
"@esbuild/freebsd-arm64",
+
"@esbuild/freebsd-x64",
+
"@esbuild/linux-arm",
+
"@esbuild/linux-arm64",
+
"@esbuild/linux-ia32",
+
"@esbuild/linux-loong64",
+
"@esbuild/linux-mips64el",
+
"@esbuild/linux-ppc64",
+
"@esbuild/linux-riscv64",
+
"@esbuild/linux-s390x",
+
"@esbuild/linux-x64",
+
"@esbuild/netbsd-arm64",
+
"@esbuild/netbsd-x64",
+
"@esbuild/openbsd-arm64",
+
"@esbuild/openbsd-x64",
+
"@esbuild/openharmony-arm64",
+
"@esbuild/sunos-x64",
+
"@esbuild/win32-arm64",
+
"@esbuild/win32-ia32",
+
"@esbuild/win32-x64"
+
],
+
"scripts": true,
+
"bin": true
+
},
+
"escalade@3.2.0": {
+
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="
+
},
+
"escape-string-regexp@4.0.0": {
+
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+
},
+
"eslint-config-prettier@10.1.8_eslint@9.39.1": {
+
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+
"dependencies": [
+
"eslint"
+
],
+
"bin": true
+
},
+
"eslint-plugin-svelte@3.13.0_eslint@9.39.1_svelte@5.45.2__acorn@8.15.0_postcss@8.5.6": {
+
"integrity": "sha512-2ohCCQJJTNbIpQCSDSTWj+FN0OVfPmSO03lmSNT7ytqMaWF6kpT86LdzDqtm4sh7TVPl/OEWJ/d7R87bXP2Vjg==",
+
"dependencies": [
+
"@eslint-community/eslint-utils",
+
"@jridgewell/sourcemap-codec",
+
"eslint",
+
"esutils",
+
"globals@16.5.0",
+
"known-css-properties",
+
"postcss",
+
"postcss-load-config@3.1.4_postcss@8.5.6",
+
"postcss-safe-parser",
+
"semver",
+
"svelte",
+
"svelte-eslint-parser"
+
],
+
"optionalPeers": [
+
"svelte"
+
]
+
},
+
"eslint-scope@8.4.0": {
+
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+
"dependencies": [
+
"esrecurse",
+
"estraverse"
+
]
+
},
+
"eslint-visitor-keys@3.4.3": {
+
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="
+
},
+
"eslint-visitor-keys@4.2.1": {
+
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="
+
},
+
"eslint@9.39.1": {
+
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
+
"dependencies": [
+
"@eslint-community/eslint-utils",
+
"@eslint-community/regexpp",
+
"@eslint/config-array",
+
"@eslint/config-helpers",
+
"@eslint/core",
+
"@eslint/eslintrc",
+
"@eslint/js",
+
"@eslint/plugin-kit",
+
"@humanfs/node",
+
"@humanwhocodes/module-importer",
+
"@humanwhocodes/retry",
+
"@types/estree",
+
"ajv",
+
"chalk",
+
"cross-spawn",
+
"debug",
+
"escape-string-regexp",
+
"eslint-scope",
+
"eslint-visitor-keys@4.2.1",
+
"espree",
+
"esquery",
+
"esutils",
+
"fast-deep-equal",
+
"file-entry-cache",
+
"find-up",
+
"glob-parent@6.0.2",
+
"ignore@5.3.2",
+
"imurmurhash",
+
"is-glob",
+
"json-stable-stringify-without-jsonify",
+
"lodash.merge",
+
"minimatch@3.1.2",
+
"natural-compare",
+
"optionator"
+
],
+
"bin": true
+
},
+
"esm-env@1.2.2": {
+
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="
+
},
+
"espree@10.4.0_acorn@8.15.0": {
+
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+
"dependencies": [
+
"acorn",
+
"acorn-jsx",
+
"eslint-visitor-keys@4.2.1"
+
]
+
},
+
"esquery@1.6.0": {
+
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+
"dependencies": [
+
"estraverse"
+
]
+
},
+
"esrap@2.2.0": {
+
"integrity": "sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==",
+
"dependencies": [
+
"@jridgewell/sourcemap-codec"
+
]
+
},
+
"esrecurse@4.3.0": {
+
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+
"dependencies": [
+
"estraverse"
+
]
+
},
+
"estraverse@5.3.0": {
+
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+
},
+
"estree-walker@2.0.2": {
+
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
+
},
+
"esutils@2.0.3": {
+
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+
},
+
"event-target-polyfill@0.0.4": {
+
"integrity": "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ=="
+
},
+
"fast-deep-equal@3.1.3": {
+
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+
},
+
"fast-glob@3.3.3": {
+
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+
"dependencies": [
+
"@nodelib/fs.stat",
+
"@nodelib/fs.walk",
+
"glob-parent@5.1.2",
+
"merge2",
+
"micromatch"
+
]
+
},
+
"fast-json-stable-stringify@2.1.0": {
+
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+
},
+
"fast-levenshtein@2.0.6": {
+
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
+
},
+
"fast-xml-parser@5.3.2": {
+
"integrity": "sha512-n8v8b6p4Z1sMgqRmqLJm3awW4NX7NkaKPfb3uJIBTSH7Pdvufi3PQ3/lJLQrvxcMYl7JI2jnDO90siPEpD8JBA==",
+
"dependencies": [
+
"strnum"
+
],
+
"bin": true
+
},
+
"fastq@1.19.1": {
+
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+
"dependencies": [
+
"reusify"
+
]
+
},
+
"fdir@6.5.0_picomatch@4.0.3": {
+
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+
"dependencies": [
+
"picomatch@4.0.3"
+
],
+
"optionalPeers": [
+
"picomatch@4.0.3"
+
]
+
},
+
"fetch-blob@3.2.0": {
+
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+
"dependencies": [
+
"node-domexception",
+
"web-streams-polyfill"
+
]
+
},
+
"file-entry-cache@8.0.0": {
+
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+
"dependencies": [
+
"flat-cache"
+
]
+
},
+
"fill-range@7.1.1": {
+
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+
"dependencies": [
+
"to-regex-range"
+
]
+
},
+
"find-up@5.0.0": {
+
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+
"dependencies": [
+
"locate-path",
+
"path-exists"
+
]
+
},
+
"flat-cache@4.0.1": {
+
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+
"dependencies": [
+
"flatted",
+
"keyv"
+
]
+
},
+
"flatted@3.3.3": {
+
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="
+
},
+
"follow-redirects@1.15.11": {
+
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="
+
},
+
"form-data@4.0.5": {
+
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+
"dependencies": [
+
"asynckit",
+
"combined-stream",
+
"es-set-tostringtag",
+
"hasown",
+
"mime-types"
+
]
+
},
+
"formdata-polyfill@4.0.10": {
+
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+
"dependencies": [
+
"fetch-blob"
+
]
+
},
+
"fraction.js@5.3.4": {
+
"integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="
+
},
+
"fsevents@2.3.3": {
+
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+
"os": ["darwin"],
+
"scripts": true
+
},
+
"function-bind@1.1.2": {
+
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
+
},
+
"get-intrinsic@1.3.0": {
+
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+
"dependencies": [
+
"call-bind-apply-helpers",
+
"es-define-property",
+
"es-errors",
+
"es-object-atoms",
+
"function-bind",
+
"get-proto",
+
"gopd",
+
"has-symbols",
+
"hasown",
+
"math-intrinsics"
+
]
+
},
+
"get-proto@1.0.1": {
+
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+
"dependencies": [
+
"dunder-proto",
+
"es-object-atoms"
+
]
+
},
+
"glob-parent@5.1.2": {
+
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+
"dependencies": [
+
"is-glob"
+
]
+
},
+
"glob-parent@6.0.2": {
+
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+
"dependencies": [
+
"is-glob"
+
]
+
},
+
"globals@14.0.0": {
+
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="
+
},
+
"globals@16.5.0": {
+
"integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="
+
},
+
"gopd@1.2.0": {
+
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
+
},
+
"graphemer@1.4.0": {
+
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
+
},
+
"has-flag@4.0.0": {
+
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+
},
+
"has-symbols@1.1.0": {
+
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
+
},
+
"has-tostringtag@1.0.2": {
+
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+
"dependencies": [
+
"has-symbols"
+
]
+
},
+
"hasown@2.0.2": {
+
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+
"dependencies": [
+
"function-bind"
+
]
+
},
+
"html-entities@2.6.0": {
+
"integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ=="
+
},
+
"ignore@5.3.2": {
+
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="
+
},
+
"ignore@7.0.5": {
+
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="
+
},
+
"import-fresh@3.3.1": {
+
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+
"dependencies": [
+
"parent-module",
+
"resolve-from"
+
]
+
},
+
"imurmurhash@0.1.4": {
+
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
+
},
+
"is-binary-path@2.1.0": {
+
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+
"dependencies": [
+
"binary-extensions"
+
]
+
},
+
"is-core-module@2.16.1": {
+
"integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
+
"dependencies": [
+
"hasown"
+
]
+
},
+
"is-extglob@2.1.1": {
+
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+
},
+
"is-glob@4.0.3": {
+
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+
"dependencies": [
+
"is-extglob"
+
]
+
},
+
"is-module@1.0.0": {
+
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
+
},
+
"is-number@7.0.0": {
+
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+
},
+
"is-reference@1.2.1": {
+
"integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
+
"dependencies": [
+
"@types/estree"
+
]
+
},
+
"is-reference@3.0.3": {
+
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
+
"dependencies": [
+
"@types/estree"
+
]
+
},
+
"isexe@2.0.0": {
+
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+
},
+
"jiti@1.21.7": {
+
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+
"bin": true
+
},
+
"js-yaml@4.1.1": {
+
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+
"dependencies": [
+
"argparse"
+
],
+
"bin": true
+
},
+
"json-buffer@3.0.1": {
+
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
+
},
+
"json-schema-traverse@0.4.1": {
+
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+
},
+
"json-stable-stringify-without-jsonify@1.0.1": {
+
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
+
},
+
"keyv@4.5.4": {
+
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+
"dependencies": [
+
"json-buffer"
+
]
+
},
+
"kleur@4.1.5": {
+
"integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="
+
},
+
"known-css-properties@0.37.0": {
+
"integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="
+
},
+
"levn@0.4.1": {
+
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+
"dependencies": [
+
"prelude-ls",
+
"type-check"
+
]
+
},
+
"lightningcss-android-arm64@1.30.2": {
+
"integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
+
"os": ["android"],
+
"cpu": ["arm64"]
+
},
+
"lightningcss-darwin-arm64@1.30.2": {
+
"integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
+
"os": ["darwin"],
+
"cpu": ["arm64"]
+
},
+
"lightningcss-darwin-x64@1.30.2": {
+
"integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
+
"os": ["darwin"],
+
"cpu": ["x64"]
+
},
+
"lightningcss-freebsd-x64@1.30.2": {
+
"integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
+
"os": ["freebsd"],
+
"cpu": ["x64"]
+
},
+
"lightningcss-linux-arm-gnueabihf@1.30.2": {
+
"integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
+
"os": ["linux"],
+
"cpu": ["arm"]
+
},
+
"lightningcss-linux-arm64-gnu@1.30.2": {
+
"integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"lightningcss-linux-arm64-musl@1.30.2": {
+
"integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
+
"os": ["linux"],
+
"cpu": ["arm64"]
+
},
+
"lightningcss-linux-x64-gnu@1.30.2": {
+
"integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"lightningcss-linux-x64-musl@1.30.2": {
+
"integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
+
"os": ["linux"],
+
"cpu": ["x64"]
+
},
+
"lightningcss-win32-arm64-msvc@1.30.2": {
+
"integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
+
"os": ["win32"],
+
"cpu": ["arm64"]
+
},
+
"lightningcss-win32-x64-msvc@1.30.2": {
+
"integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
+
"os": ["win32"],
+
"cpu": ["x64"]
+
},
+
"lightningcss@1.30.2": {
+
"integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
+
"dependencies": [
+
"detect-libc"
+
],
+
"optionalDependencies": [
+
"lightningcss-android-arm64",
+
"lightningcss-darwin-arm64",
+
"lightningcss-darwin-x64",
+
"lightningcss-freebsd-x64",
+
"lightningcss-linux-arm-gnueabihf",
+
"lightningcss-linux-arm64-gnu",
+
"lightningcss-linux-arm64-musl",
+
"lightningcss-linux-x64-gnu",
+
"lightningcss-linux-x64-musl",
+
"lightningcss-win32-arm64-msvc",
+
"lightningcss-win32-x64-msvc"
+
]
+
},
+
"lilconfig@2.1.0": {
+
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="
+
},
+
"lilconfig@3.1.3": {
+
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="
+
},
+
"lines-and-columns@1.2.4": {
+
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
+
},
+
"locate-character@3.0.0": {
+
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="
+
},
+
"locate-path@6.0.0": {
+
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+
"dependencies": [
+
"p-locate"
+
]
+
},
+
"lodash.merge@4.6.2": {
+
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+
},
+
"long@5.3.2": {
+
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
+
},
+
"magic-string@0.30.21": {
+
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+
"dependencies": [
+
"@jridgewell/sourcemap-codec"
+
]
+
},
+
"math-intrinsics@1.1.0": {
+
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
+
},
+
"mdsvex@0.12.6_svelte@5.45.2__acorn@8.15.0": {
+
"integrity": "sha512-pupx2gzWh3hDtm/iDW4WuCpljmyHbHi34r7ktOqpPGvyiM4MyfNgdJ3qMizXdgCErmvYC9Nn/qyjePy+4ss9Wg==",
+
"dependencies": [
+
"@types/mdast",
+
"@types/unist",
+
"prism-svelte",
+
"prismjs",
+
"svelte",
+
"unist-util-visit",
+
"vfile-message"
+
]
+
},
+
"merge2@1.4.1": {
+
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
+
},
+
"micromatch@4.0.8": {
+
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+
"dependencies": [
+
"braces",
+
"picomatch@2.3.1"
+
]
+
},
+
"mime-db@1.52.0": {
+
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+
},
+
"mime-types@2.1.35": {
+
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+
"dependencies": [
+
"mime-db"
+
]
+
},
+
"mini-svg-data-uri@1.4.4": {
+
"integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==",
+
"bin": true
+
},
+
"minimatch@3.1.2": {
+
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+
"dependencies": [
+
"brace-expansion@1.1.12"
+
]
+
},
+
"minimatch@9.0.5": {
+
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+
"dependencies": [
+
"brace-expansion@2.0.2"
+
]
+
},
+
"mri@1.2.0": {
+
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="
+
},
+
"mrmime@2.0.1": {
+
"integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="
+
},
+
"ms@2.1.3": {
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+
},
+
"mz@2.7.0": {
+
"integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+
"dependencies": [
+
"any-promise",
+
"object-assign",
+
"thenify-all"
+
]
+
},
+
"nanoevents@9.1.0": {
+
"integrity": "sha512-Jd0fILWG44a9luj8v5kED4WI+zfkkgwKyRQKItTtlPfEsh7Lznfi1kr8/iZ+XAIss4Qq5GqRB0qtWbaz9ceO/A=="
+
},
+
"nanoid@3.3.11": {
+
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+
"bin": true
+
},
+
"nanoid@5.1.6": {
+
"integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==",
+
"bin": true
+
},
+
"natural-compare@1.4.0": {
+
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
+
},
+
"node-domexception@1.0.0": {
+
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+
"deprecated": true
+
},
+
"node-fetch@3.3.2": {
+
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+
"dependencies": [
+
"data-uri-to-buffer",
+
"fetch-blob",
+
"formdata-polyfill"
+
]
+
},
+
"node-releases@2.0.27": {
+
"integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="
+
},
+
"normalize-path@3.0.0": {
+
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
+
},
+
"normalize-range@0.1.2": {
+
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="
+
},
+
"object-assign@4.1.1": {
+
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+
},
+
"object-hash@3.0.0": {
+
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="
+
},
+
"optionator@0.9.4": {
+
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+
"dependencies": [
+
"deep-is",
+
"fast-levenshtein",
+
"levn",
+
"prelude-ls",
+
"type-check",
+
"word-wrap"
+
]
+
},
+
"p-limit@3.1.0": {
+
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+
"dependencies": [
+
"yocto-queue@0.1.0"
+
]
+
},
+
"p-locate@5.0.0": {
+
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+
"dependencies": [
+
"p-limit"
+
]
+
},
+
"parent-module@1.0.1": {
+
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+
"dependencies": [
+
"callsites"
+
]
+
},
+
"partysocket@1.1.6": {
+
"integrity": "sha512-LkEk8N9hMDDsDT0iDK0zuwUDFVrVMUXFXCeN3850Ng8wtjPqPBeJlwdeY6ROlJSEh3tPoTTasXoSBYH76y118w==",
+
"dependencies": [
+
"event-target-polyfill"
+
]
+
},
+
"path-exists@4.0.0": {
+
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+
},
+
"path-key@3.1.1": {
+
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
+
},
+
"path-parse@1.0.7": {
+
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+
},
+
"picocolors@1.1.1": {
+
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+
},
+
"picomatch@2.3.1": {
+
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+
},
+
"picomatch@4.0.3": {
+
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="
+
},
+
"pify@2.3.0": {
+
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="
+
},
+
"pirates@4.0.7": {
+
"integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="
+
},
+
"postcss-import@15.1.0_postcss@8.5.6": {
+
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+
"dependencies": [
+
"postcss",
+
"postcss-value-parser",
+
"read-cache",
+
"resolve"
+
]
+
},
+
"postcss-js@4.1.0_postcss@8.5.6": {
+
"integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
+
"dependencies": [
+
"camelcase-css",
+
"postcss"
+
]
+
},
+
"postcss-load-config@3.1.4_postcss@8.5.6": {
+
"integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
+
"dependencies": [
+
"lilconfig@2.1.0",
+
"postcss",
+
"yaml"
+
],
+
"optionalPeers": [
+
"postcss"
+
]
+
},
+
"postcss-load-config@6.0.1_jiti@1.21.7_postcss@8.5.6": {
+
"integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==",
+
"dependencies": [
+
"jiti",
+
"lilconfig@3.1.3",
+
"postcss"
+
],
+
"optionalPeers": [
+
"jiti",
+
"postcss"
+
]
+
},
+
"postcss-nested@6.2.0_postcss@8.5.6": {
+
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+
"dependencies": [
+
"postcss",
+
"postcss-selector-parser@6.1.2"
+
]
+
},
+
"postcss-safe-parser@7.0.1_postcss@8.5.6": {
+
"integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
+
"dependencies": [
+
"postcss"
+
]
+
},
+
"postcss-scss@4.0.9_postcss@8.5.6": {
+
"integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
+
"dependencies": [
+
"postcss"
+
]
+
},
+
"postcss-selector-parser@6.0.10": {
+
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
+
"dependencies": [
+
"cssesc",
+
"util-deprecate"
+
]
+
},
+
"postcss-selector-parser@6.1.2": {
+
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+
"dependencies": [
+
"cssesc",
+
"util-deprecate"
+
]
+
},
+
"postcss-selector-parser@7.1.1": {
+
"integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==",
+
"dependencies": [
+
"cssesc",
+
"util-deprecate"
+
]
+
},
+
"postcss-value-parser@4.2.0": {
+
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+
},
+
"postcss@8.5.6": {
+
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+
"dependencies": [
+
"nanoid@3.3.11",
+
"picocolors",
+
"source-map-js"
+
]
+
},
+
"prelude-ls@1.2.1": {
+
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
+
},
+
"prettier-plugin-svelte@3.4.0_prettier@3.7.1_svelte@5.45.2__acorn@8.15.0": {
+
"integrity": "sha512-pn1ra/0mPObzqoIQn/vUTR3ZZI6UuZ0sHqMK5x2jMLGrs53h0sXhkVuDcrlssHwIMk7FYrMjHBPoUSyyEEDlBQ==",
+
"dependencies": [
+
"prettier",
+
"svelte"
+
]
+
},
+
"prettier@3.7.1": {
+
"integrity": "sha512-RWKXE4qB3u5Z6yz7omJkjWwmTfLdcbv44jUVHC5NpfXwFGzvpQM798FGv/6WNK879tc+Cn0AAyherCl1KjbyZQ==",
+
"bin": true
+
},
+
"prism-svelte@0.4.7": {
+
"integrity": "sha512-yABh19CYbM24V7aS7TuPYRNMqthxwbvx6FF/Rw920YbyBWO3tnyPIqRMgHuSVsLmuHkkBS1Akyof463FVdkeDQ=="
+
},
+
"prismjs@1.30.0": {
+
"integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="
+
},
+
"prometheus-remote-write@0.5.1_node-fetch@3.3.2": {
+
"integrity": "sha512-wCQk35u4EWIzGQyCeBKKaVdUefiTyFA8X/SU8B5KQX82k4vwDQW4LMb8pYmyBLZWAUBHcxSoacwosPRE2VvW+w==",
+
"dependencies": [
+
"node-fetch",
+
"protobufjs",
+
"snappyjs"
+
],
+
"optionalPeers": [
+
"node-fetch"
+
]
+
},
+
"protobufjs@7.5.4": {
+
"integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
+
"dependencies": [
+
"@protobufjs/aspromise",
+
"@protobufjs/base64",
+
"@protobufjs/codegen",
+
"@protobufjs/eventemitter",
+
"@protobufjs/fetch",
+
"@protobufjs/float",
+
"@protobufjs/inquire",
+
"@protobufjs/path",
+
"@protobufjs/pool",
+
"@protobufjs/utf8",
+
"@types/node@24.10.1",
+
"long"
+
],
+
"scripts": true
+
},
+
"proxy-from-env@1.1.0": {
+
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+
},
+
"punycode@2.3.1": {
+
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
+
},
+
"queue-microtask@1.2.3": {
+
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
+
},
+
"quick-lru@7.3.0": {
+
"integrity": "sha512-k9lSsjl36EJdK7I06v7APZCbyGT2vMTsYSRX1Q2nbYmnkBqgUhRkAuzH08Ciotteu/PLJmIF2+tti7o3C/ts2g=="
+
},
+
"rate-limit-threshold@0.1.5": {
+
"integrity": "sha512-75vpvXC/ZqQJrFDp0dVtfoXZi8kxQP2eBuxVYFvGDfnHhcgE+ZG870u4ItQhWQh54Y6nNwOaaq5g3AL9n27lTg=="
+
},
+
"read-cache@1.0.0": {
+
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+
"dependencies": [
+
"pify"
+
]
+
},
+
"readdirp@3.6.0": {
+
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+
"dependencies": [
+
"picomatch@2.3.1"
+
]
+
},
+
"readdirp@4.1.2": {
+
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="
+
},
+
"resolve-from@4.0.0": {
+
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
+
},
+
"resolve@1.22.11": {
+
"integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==",
+
"dependencies": [
+
"is-core-module",
+
"path-parse",
+
"supports-preserve-symlinks-flag"
+
],
+
"bin": true
+
},
+
"reusify@1.1.0": {
+
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="
+
},
+
"robots-parser@3.0.1": {
+
"integrity": "sha512-s+pyvQeIKIZ0dx5iJiQk1tPLJAWln39+MI5jtM8wnyws+G5azk+dMnMX0qfbqNetKKNgcWWOdi0sfm+FbQbgdQ=="
+
},
+
"rolldown-vite@7.2.5_@types+node@24.10.1_picomatch@4.0.3": {
+
"integrity": "sha512-u09tdk/huMiN8xwoiBbig197jKdCamQTtOruSalOzbqGje3jdHiV0njQlAW0YvzoahkirFePNQ4RYlfnRQpXZA==",
+
"dependencies": [
+
"@oxc-project/runtime",
+
"@types/node@24.10.1",
+
"fdir",
+
"lightningcss",
+
"picomatch@4.0.3",
+
"postcss",
+
"rolldown",
+
"tinyglobby"
+
],
+
"optionalDependencies": [
+
"fsevents"
+
],
+
"optionalPeers": [
+
"@types/node@24.10.1"
+
],
+
"bin": true
+
},
+
"rolldown@1.0.0-beta.50": {
+
"integrity": "sha512-JFULvCNl/anKn99eKjOSEubi0lLmNqQDAjyEMME2T4CwezUDL0i6t1O9xZsu2OMehPnV2caNefWpGF+8TnzB6A==",
+
"dependencies": [
+
"@oxc-project/types",
+
"@rolldown/pluginutils"
+
],
+
"optionalDependencies": [
+
"@rolldown/binding-android-arm64",
+
"@rolldown/binding-darwin-arm64",
+
"@rolldown/binding-darwin-x64",
+
"@rolldown/binding-freebsd-x64",
+
"@rolldown/binding-linux-arm-gnueabihf",
+
"@rolldown/binding-linux-arm64-gnu",
+
"@rolldown/binding-linux-arm64-musl",
+
"@rolldown/binding-linux-x64-gnu",
+
"@rolldown/binding-linux-x64-musl",
+
"@rolldown/binding-openharmony-arm64",
+
"@rolldown/binding-wasm32-wasi",
+
"@rolldown/binding-win32-arm64-msvc",
+
"@rolldown/binding-win32-ia32-msvc",
+
"@rolldown/binding-win32-x64-msvc"
+
],
+
"bin": true
+
},
+
"rollup@4.53.3": {
+
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
+
"dependencies": [
+
"@types/estree"
+
],
+
"optionalDependencies": [
+
"@rollup/rollup-android-arm-eabi",
+
"@rollup/rollup-android-arm64",
+
"@rollup/rollup-darwin-arm64",
+
"@rollup/rollup-darwin-x64",
+
"@rollup/rollup-freebsd-arm64",
+
"@rollup/rollup-freebsd-x64",
+
"@rollup/rollup-linux-arm-gnueabihf",
+
"@rollup/rollup-linux-arm-musleabihf",
+
"@rollup/rollup-linux-arm64-gnu",
+
"@rollup/rollup-linux-arm64-musl",
+
"@rollup/rollup-linux-loong64-gnu",
+
"@rollup/rollup-linux-ppc64-gnu",
+
"@rollup/rollup-linux-riscv64-gnu",
+
"@rollup/rollup-linux-riscv64-musl",
+
"@rollup/rollup-linux-s390x-gnu",
+
"@rollup/rollup-linux-x64-gnu",
+
"@rollup/rollup-linux-x64-musl",
+
"@rollup/rollup-openharmony-arm64",
+
"@rollup/rollup-win32-arm64-msvc",
+
"@rollup/rollup-win32-ia32-msvc",
+
"@rollup/rollup-win32-x64-gnu",
+
"@rollup/rollup-win32-x64-msvc",
+
"fsevents"
+
],
+
"bin": true
+
},
+
"run-parallel@1.2.0": {
+
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+
"dependencies": [
+
"queue-microtask"
+
]
+
},
+
"sade@1.8.1": {
+
"integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+
"dependencies": [
+
"mri"
+
]
+
},
+
"scule@1.3.0": {
+
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g=="
+
},
+
"semver@7.7.3": {
+
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+
"bin": true
+
},
+
"set-cookie-parser@2.7.2": {
+
"integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw=="
+
},
+
"shebang-command@2.0.0": {
+
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+
"dependencies": [
+
"shebang-regex"
+
]
+
},
+
"shebang-regex@3.0.0": {
+
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
+
},
+
"sirv@3.0.2": {
+
"integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==",
+
"dependencies": [
+
"@polka/url",
+
"mrmime",
+
"totalist"
+
]
+
},
+
"snappyjs@0.6.1": {
+
"integrity": "sha512-YIK6I2lsH072UE0aOFxxY1dPDCS43I5ktqHpeAsuLNYWkE5pGxRGWfDM4/vSUfNzXjC1Ivzt3qx31PCLmc9yqg=="
+
},
+
"source-map-js@1.2.1": {
+
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
+
},
+
"steamgriddb@2.2.1": {
+
"integrity": "sha512-Gw1rwgIYlYrTZaxvm6l+1AvSidh4qNkdDhAmYhck7JCSXDxrSHPsYYEXicD7601i6xXxA6qKW2lLcbH/gKVwHw==",
+
"dependencies": [
+
"axios"
+
]
+
},
+
"strip-json-comments@3.1.1": {
+
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
+
},
+
"strnum@2.1.1": {
+
"integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw=="
+
},
+
"sucrase@3.35.1": {
+
"integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
+
"dependencies": [
+
"@jridgewell/gen-mapping",
+
"commander",
+
"lines-and-columns",
+
"mz",
+
"pirates",
+
"tinyglobby",
+
"ts-interface-checker"
+
],
+
"bin": true
+
},
+
"supports-color@7.2.0": {
+
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+
"dependencies": [
+
"has-flag"
+
]
+
},
+
"supports-preserve-symlinks-flag@1.0.0": {
+
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+
},
+
"svelte-check@4.3.4_svelte@5.45.2__acorn@8.15.0_typescript@5.9.3": {
+
"integrity": "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw==",
+
"dependencies": [
+
"@jridgewell/trace-mapping",
+
"chokidar@4.0.3",
+
"fdir",
+
"picocolors",
+
"sade",
+
"svelte",
+
"typescript"
+
],
+
"bin": true
+
},
+
"svelte-eslint-parser@1.4.0_svelte@5.45.2__acorn@8.15.0_postcss@8.5.6": {
+
"integrity": "sha512-fjPzOfipR5S7gQ/JvI9r2H8y9gMGXO3JtmrylHLLyahEMquXI0lrebcjT+9/hNgDej0H7abTyox5HpHmW1PSWA==",
+
"dependencies": [
+
"eslint-scope",
+
"eslint-visitor-keys@4.2.1",
+
"espree",
+
"postcss",
+
"postcss-scss",
+
"postcss-selector-parser@7.1.1",
+
"svelte"
+
],
+
"optionalPeers": [
+
"svelte"
+
]
+
},
+
"svelte2tsx@0.7.45_svelte@5.45.2__acorn@8.15.0_typescript@5.9.3": {
+
"integrity": "sha512-cSci+mYGygYBHIZLHlm/jYlEc1acjAHqaQaDFHdEBpUueM9kSTnPpvPtSl5VkJOU1qSJ7h1K+6F/LIUYiqC8VA==",
+
"dependencies": [
+
"dedent-js",
+
"scule",
+
"svelte",
+
"typescript"
+
]
+
},
+
"svelte@5.45.2_acorn@8.15.0": {
+
"integrity": "sha512-yyXdW2u3H0H/zxxWoGwJoQlRgaSJLp+Vhktv12iRw2WRDlKqUPT54Fi0K/PkXqrdkcQ98aBazpy0AH4BCBVfoA==",
+
"dependencies": [
+
"@jridgewell/remapping",
+
"@jridgewell/sourcemap-codec",
+
"@sveltejs/acorn-typescript",
+
"@types/estree",
+
"acorn",
+
"aria-query",
+
"axobject-query",
+
"clsx",
+
"devalue",
+
"esm-env",
+
"esrap",
+
"is-reference@3.0.3",
+
"locate-character",
+
"magic-string",
+
"zimmerframe"
+
]
+
},
+
"sveltekit-rate-limiter@0.7.0_@sveltejs+kit@2.49.0__@sveltejs+vite-plugin-svelte@6.2.1___svelte@5.45.2____acorn@8.15.0___vite@7.2.4____@types+node@24.10.1____picomatch@4.0.3___@types+node@24.10.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__acorn@8.15.0__@types+node@24.10.1_@sveltejs+vite-plugin-svelte@6.2.1__svelte@5.45.2___acorn@8.15.0__vite@7.2.4___@types+node@24.10.1___picomatch@4.0.3__@types+node@24.10.1_svelte@5.45.2__acorn@8.15.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-aQI8Y1dTWKsB4YiZMBYORMDwy2SaFA2J5t848dEPVNkXWzhqrHqHUBb7QiNiLWqAeWvOJBwD+MZnsbmvbhGQdg==",
+
"dependencies": [
+
"@isaacs/ttlcache",
+
"@sveltejs/kit"
+
]
+
},
+
"tailwindcss@3.4.18_postcss@8.5.6_jiti@1.21.7": {
+
"integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
+
"dependencies": [
+
"@alloc/quick-lru",
+
"arg",
+
"chokidar@3.6.0",
+
"didyoumean",
+
"dlv",
+
"fast-glob",
+
"glob-parent@6.0.2",
+
"is-glob",
+
"jiti",
+
"lilconfig@3.1.3",
+
"micromatch",
+
"normalize-path",
+
"object-hash",
+
"picocolors",
+
"postcss",
+
"postcss-import",
+
"postcss-js",
+
"postcss-load-config@6.0.1_jiti@1.21.7_postcss@8.5.6",
+
"postcss-nested",
+
"postcss-selector-parser@6.1.2",
+
"resolve",
+
"sucrase"
+
],
+
"bin": true
+
},
+
"thenify-all@1.6.0": {
+
"integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+
"dependencies": [
+
"thenify"
+
]
+
},
+
"thenify@3.3.1": {
+
"integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+
"dependencies": [
+
"any-promise"
+
]
+
},
+
"tiny-emitter@2.1.0": {
+
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
+
},
+
"tinyglobby@0.2.15_picomatch@4.0.3": {
+
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+
"dependencies": [
+
"fdir",
+
"picomatch@4.0.3"
+
]
+
},
+
"to-regex-range@5.0.1": {
+
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+
"dependencies": [
+
"is-number"
+
]
+
},
+
"toad-scheduler@3.1.0": {
+
"integrity": "sha512-ZTwsGMWyKTOokgTmIvjPIvkT3ZiPFgkAi8L0OLONOcSc/BUDPRzNMOfVWZzugIAxyntvY0Nzy1etNk+31Q4FXQ==",
+
"dependencies": [
+
"croner"
+
]
+
},
+
"totalist@3.0.1": {
+
"integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="
+
},
+
"ts-api-utils@2.1.0_typescript@5.9.3": {
+
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+
"dependencies": [
+
"typescript"
+
]
+
},
+
"ts-interface-checker@0.1.13": {
+
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
+
},
+
"tslib@2.8.1": {
+
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
+
},
+
"type-check@0.4.0": {
+
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+
"dependencies": [
+
"prelude-ls"
+
]
+
},
+
"typescript-eslint@8.48.0_eslint@9.39.1_typescript@5.9.3_@typescript-eslint+parser@8.48.0__eslint@9.39.1__typescript@5.9.3": {
+
"integrity": "sha512-fcKOvQD9GUn3Xw63EgiDqhvWJ5jsyZUaekl3KVpGsDJnN46WJTe3jWxtQP9lMZm1LJNkFLlTaWAxK2vUQR+cqw==",
+
"dependencies": [
+
"@typescript-eslint/eslint-plugin",
+
"@typescript-eslint/parser",
+
"@typescript-eslint/typescript-estree",
+
"@typescript-eslint/utils",
+
"eslint",
+
"typescript"
+
]
+
},
+
"typescript-svelte-plugin@0.3.50_svelte@5.45.2__acorn@8.15.0_typescript@5.9.3": {
+
"integrity": "sha512-CD6jMNAYJwqCyQ5zZBDRuveeJvAgIogLwXMf5eXAl4K36wD8W+Npw49h6j5fXnpd7SKcG3uptGpeCGETED6WSA==",
+
"dependencies": [
+
"@jridgewell/sourcemap-codec",
+
"svelte2tsx"
+
]
+
},
+
"typescript@5.9.3": {
+
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+
"bin": true
+
},
+
"undici-types@6.21.0": {
+
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="
+
},
+
"undici-types@7.16.0": {
+
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="
+
},
+
"unist-util-is@4.1.0": {
+
"integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg=="
+
},
+
"unist-util-stringify-position@2.0.3": {
+
"integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==",
+
"dependencies": [
+
"@types/unist"
+
]
+
},
+
"unist-util-visit-parents@3.1.1": {
+
"integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==",
+
"dependencies": [
+
"@types/unist",
+
"unist-util-is"
+
]
+
},
+
"unist-util-visit@2.0.3": {
+
"integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==",
+
"dependencies": [
+
"@types/unist",
+
"unist-util-is",
+
"unist-util-visit-parents"
+
]
+
},
+
"update-browserslist-db@1.1.4_browserslist@4.28.0": {
+
"integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==",
+
"dependencies": [
+
"browserslist",
+
"escalade",
+
"picocolors"
+
],
+
"bin": true
+
},
+
"uri-js@4.4.1": {
+
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+
"dependencies": [
+
"punycode"
+
]
+
},
+
"util-deprecate@1.0.2": {
+
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+
},
+
"uuid@10.0.0": {
+
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
+
"bin": true
+
},
+
"vfile-message@2.0.4": {
+
"integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==",
+
"dependencies": [
+
"@types/unist",
+
"unist-util-stringify-position"
+
]
+
},
+
"vite-plugin-top-level-await@1.6.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-bNhUreLamTIkoulCR9aDXbTbhLk6n1YE8NJUTTxl5RYskNRtzOR0ASzSjBVRtNdjIfngDXo11qOsybGLNsrdww==",
+
"dependencies": [
+
"@rollup/plugin-virtual",
+
"@swc/core",
+
"@swc/wasm",
+
"uuid",
+
"vite"
+
]
+
},
+
"vite-plugin-wasm@3.5.0_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-X5VWgCnqiQEGb+omhlBVsvTfxikKtoOgAzQ95+BZ8gQ+VfMHIjSHr0wyvXFQCa0eKQ0fKyaL0kWcEnYqBac4lQ==",
+
"dependencies": [
+
"vite"
+
]
+
},
+
"vite@7.2.4_@types+node@24.10.1_picomatch@4.0.3": {
+
"integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==",
+
"dependencies": [
+
"@types/node@24.10.1",
+
"esbuild",
+
"fdir",
+
"picomatch@4.0.3",
+
"postcss",
+
"rollup",
+
"tinyglobby"
+
],
+
"optionalDependencies": [
+
"fsevents"
+
],
+
"optionalPeers": [
+
"@types/node@24.10.1"
+
],
+
"bin": true
+
},
+
"vitefu@1.1.1_vite@7.2.4__@types+node@24.10.1__picomatch@4.0.3_@types+node@24.10.1": {
+
"integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==",
+
"dependencies": [
+
"vite"
+
],
+
"optionalPeers": [
+
"vite"
+
]
+
},
+
"web-streams-polyfill@3.3.3": {
+
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="
+
},
+
"which@2.0.2": {
+
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+
"dependencies": [
+
"isexe"
+
],
+
"bin": true
+
},
+
"word-wrap@1.2.5": {
+
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="
+
},
+
"yaml@1.10.2": {
+
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="
+
},
+
"yocto-queue@0.1.0": {
+
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
+
},
+
"yocto-queue@1.2.2": {
+
"integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ=="
+
},
+
"zimmerframe@1.1.4": {
+
"integrity": "sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ=="
+
}
+
},
+
"workspace": {
+
"members": {
+
"dysnomia/www": {
+
"packageJson": {
+
"dependencies": [
+
"npm:@jsr/std__toml@*",
+
"npm:@xterm/addon-canvas@0.7",
+
"npm:@xterm/addon-fit@0.10",
+
"npm:@xterm/addon-web-links@0.11",
+
"npm:@xterm/addon-webgl@0.18",
+
"npm:@xterm/xterm@^5.5.0",
+
"npm:rolldown-vite@7.2.5",
+
"npm:typescript@~5.9.3",
+
"npm:vite-plugin-top-level-await@^1.6.0",
+
"npm:vite-plugin-wasm@^3.5.0"
+
]
+
}
+
},
+
"eunomia": {
+
"packageJson": {
+
"dependencies": [
+
"npm:@jsr/std__toml@*",
+
"npm:@neodrag/svelte@^2.3.3",
+
"npm:@rowanmanning/feed-parser@^2.1.1",
+
"npm:@skyware/bot@0.4",
+
"npm:@sveltejs/adapter-node@^5.4.0",
+
"npm:@sveltejs/kit@^2.49.0",
+
"npm:@sveltejs/vite-plugin-svelte@^6.1.3",
+
"npm:@tailwindcss/forms@~0.5.10",
+
"npm:@tailwindcss/typography@~0.5.16",
+
"npm:@types/deno@^2.5.0",
+
"npm:@types/eslint@^9.6.1",
+
"npm:@types/node-schedule@^2.1.8",
+
"npm:@types/node@^24.10.1",
+
"npm:autoprefixer@^10.4.22",
+
"npm:eslint-config-prettier@^10.1.8",
+
"npm:eslint-plugin-svelte@^3.13.0",
+
"npm:eslint@^9.39.1",
+
"npm:globals@^16.5.0",
+
"npm:mdsvex@~0.12.6",
+
"npm:nanoid@^5.1.5",
+
"npm:node-fetch@^3.3.2",
+
"npm:postcss@^8.5.6",
+
"npm:prettier-plugin-svelte@^3.4.0",
+
"npm:prettier@^3.7.1",
+
"npm:prometheus-remote-write@~0.5.1",
+
"npm:robots-parser@^3.0.1",
+
"npm:steamgriddb@^2.2.0",
+
"npm:svelte-check@^4.3.4",
+
"npm:svelte@^5.45.2",
+
"npm:sveltekit-rate-limiter@0.7",
+
"npm:tailwindcss@^3.4.17",
+
"npm:toad-scheduler@^3.1.0",
+
"npm:tslib@^2.8.1",
+
"npm:typescript-eslint@^8.48.0",
+
"npm:typescript-svelte-plugin@~0.3.50",
+
"npm:typescript@^5.9.2",
+
"npm:vite@^7.2.4"
+
]
+
}
+
}
+
}
+
}
+
}
-33
eslint.config.js
···
-
import js from '@eslint/js';
-
import ts from 'typescript-eslint';
-
import svelte from 'eslint-plugin-svelte';
-
import prettier from 'eslint-config-prettier';
-
import globals from 'globals';
-
-
/** @type {import('eslint').Linter.FlatConfig[]} */
-
export default [
-
js.configs.recommended,
-
...ts.configs.recommended,
-
...svelte.configs['flat/recommended'],
-
prettier,
-
...svelte.configs['flat/prettier'],
-
{
-
languageOptions: {
-
globals: {
-
...globals.browser,
-
...globals.node
-
}
-
}
-
},
-
{
-
files: ['**/*.svelte'],
-
languageOptions: {
-
parserOptions: {
-
parser: ts.parser
-
}
-
}
-
},
-
{
-
ignores: ['build/', '.svelte-kit/', 'dist/']
-
}
-
];
+4
eunomia/.prettierignore
···
+
# Package Managers
+
package-lock.json
+
pnpm-lock.yaml
+
yarn.lock
+8
eunomia/.prettierrc
···
+
{
+
"useTabs": true,
+
"singleQuote": true,
+
"trailingComma": "none",
+
"printWidth": 100,
+
"plugins": ["prettier-plugin-svelte"],
+
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
+
}
+9
eunomia/README.md
···
+
code for one of its (90008) human-facing data endpoints (aka a website.)
+
+
- the website itself uses sveltekit (w/ typescript) and tailwindcss. it's served with bun.
+
- the logs and guestbook show posts from its bsky account and a guestbook account respectively, hosted on its pds.
+
- it's deployed to a server with nix, so it's packaged with nix (see flake.nix).
+
+
notes to itself:
+
+
- don't use tags starting with h- (same goes for p-) in root layout or page, this causes hcard parsers to trip up
+1
eunomia/deno.json
···
+
{}
+33
eunomia/eslint.config.js
···
+
import js from '@eslint/js';
+
import ts from 'typescript-eslint';
+
import svelte from 'eslint-plugin-svelte';
+
import prettier from 'eslint-config-prettier';
+
import globals from 'globals';
+
+
/** @type {import('eslint').Linter.FlatConfig[]} */
+
export default [
+
js.configs.recommended,
+
...ts.configs.recommended,
+
...svelte.configs['flat/recommended'],
+
prettier,
+
...svelte.configs['flat/prettier'],
+
{
+
languageOptions: {
+
globals: {
+
...globals.browser,
+
...globals.node
+
}
+
}
+
},
+
{
+
files: ['**/*.svelte'],
+
languageOptions: {
+
parserOptions: {
+
parser: ts.parser
+
}
+
}
+
},
+
{
+
ignores: ['build/', '.svelte-kit/', 'dist/']
+
}
+
];
+59
eunomia/package.json
···
+
{
+
"name": "eunomia",
+
"version": "0.0.1",
+
"private": true,
+
"scripts": {
+
"dev": "vite dev",
+
"build": "vite build",
+
"preview": "vite preview"
+
},
+
"devDependencies": {
+
"@sveltejs/adapter-node": "^5.4.0",
+
"@sveltejs/kit": "^2.49.0",
+
"@sveltejs/vite-plugin-svelte": "^6.1.3",
+
"@tailwindcss/forms": "^0.5.10",
+
"@tailwindcss/typography": "^0.5.16",
+
"@types/deno": "^2.5.0",
+
"@types/eslint": "^9.6.1",
+
"@types/node": "^24.10.1",
+
"autoprefixer": "^10.4.22",
+
"eslint": "^9.39.1",
+
"eslint-config-prettier": "^10.1.8",
+
"eslint-plugin-svelte": "^3.13.0",
+
"globals": "^16.5.0",
+
"mdsvex": "^0.12.6",
+
"postcss": "^8.5.6",
+
"prettier": "^3.7.1",
+
"prettier-plugin-svelte": "^3.4.0",
+
"svelte": "^5.45.2",
+
"svelte-check": "^4.3.4",
+
"sveltekit-rate-limiter": "^0.7.0",
+
"tailwindcss": "^3.4.17",
+
"tslib": "^2.8.1",
+
"typescript": "^5.9.2",
+
"typescript-eslint": "^8.48.0",
+
"typescript-svelte-plugin": "^0.3.50",
+
"vite": "^7.2.4"
+
},
+
"type": "module",
+
"dependencies": {
+
"@neodrag/svelte": "^2.3.3",
+
"@rowanmanning/feed-parser": "^2.1.1",
+
"@skyware/bot": "^0.4.0",
+
"@std/toml": "npm:@jsr/std__toml",
+
"@types/node-schedule": "^2.1.8",
+
"nanoid": "^5.1.5",
+
"node-fetch": "^3.3.2",
+
"prometheus-remote-write": "^0.5.1",
+
"robots-parser": "^3.0.1",
+
"steamgriddb": "^2.2.0",
+
"toad-scheduler": "^3.1.0"
+
},
+
"trustedDependencies": [
+
"@sveltejs/kit",
+
"esbuild",
+
"protobufjs",
+
"sharp",
+
"svelte-preprocess"
+
]
+
}
+6
eunomia/postcss.config.js
···
+
export default {
+
plugins: {
+
tailwindcss: {},
+
autoprefixer: {},
+
},
+
}
+13
eunomia/src/app.d.ts
···
+
// See https://kit.svelte.dev/docs/types#app
+
// for information about these interfaces
+
declare global {
+
namespace App {
+
// interface Error {}
+
// interface Locals {}
+
// interface PageData {}
+
// interface PageState {}
+
// interface Platform {}
+
}
+
}
+
+
export {};
+12
eunomia/src/app.html
···
+
<!doctype html>
+
<html lang="en">
+
<head>
+
<meta charset="utf-8" />
+
<link rel="icon" href="%sveltekit.assets%/icons/gaze_site.webp" />
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
+
%sveltekit.head%
+
</head>
+
<body class="md:overflow-hidden">
+
<div style="display: contents">%sveltekit.body%</div>
+
</body>
+
</html>
+19
eunomia/src/components/_window_layout.svelte
···
+
<script lang="ts">
+
import Window from './window.svelte';
+
import '../styles/app.css';
+
+
interface Props {
+
title: string;
+
sticky: boolean;
+
prose?: boolean;
+
children?: import('svelte').Snippet;
+
}
+
+
let { title, sticky, prose = true, children }: Props = $props();
+
</script>
+
+
<Window {title} {sticky}>
+
<div class={prose ? 'prose prose-ralsei leading-6 prose-ul:leading-5' : ''}>
+
{@render children?.()}
+
</div>
+
</Window>
+75
eunomia/src/components/eye.svelte
···
+
<script lang="ts">
+
import { genDollcode } from '$lib/dollcode';
+
+
interface Props {
+
top: number;
+
left: number;
+
kind?: string;
+
visits: number[];
+
id: string;
+
}
+
+
let { top, left, kind = 'normal', visits }: Props = $props();
+
+
let rotation = $state((Math.random() - 0.5) * 0.4);
+
const opacity = Math.min(Math.random() * 0.3 + 0.4, 0.7);
+
+
let closed = $state(false);
+
let look = $state('forward');
+
const looks = ['left', 'forward', 'right'];
+
const pickLook = $derived(() => {
+
const pickable = looks.filter((l) => {
+
return l !== look;
+
});
+
return pickable.at(Math.floor(Math.random() * pickable.length)) ?? 'forward';
+
});
+
const randomizeLook = () => {
+
look = pickLook();
+
rotation = (Math.random() - 0.5) * 0.4;
+
setTimeout(randomizeLook, 2000 + Math.random() * 6000);
+
};
+
+
let src = $derived(closed ? `/eyes/closed.webp` : `/eyes/${kind}_${look}.webp`);
+
+
// generate dollcode based on time, but mod by 3 hours
+
const timeDollcode = genDollcode((visits[0] / 1000) % (60 * 60 * 24));
+
const visitsDollcode = genDollcode(visits.length);
+
+
randomizeLook();
+
</script>
+
+
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
+
<div
+
class="group flex gap-4 items-center scale-[0.75]"
+
style="
+
position: fixed;
+
top: {top}vh;
+
left: {left}%;
+
opacity: {opacity};
+
flex-direction: column-reverse;
+
"
+
onmouseover={() => {
+
closed = true;
+
}}
+
onmouseleave={() => {
+
closed = false;
+
}}
+
>
+
<span class="eye-text !text-base">{visitsDollcode}</span>
+
<!-- svelte-ignore a11y_missing_attribute -->
+
<img class="w-24 eye-image" style="transform: rotate({rotation}rad);" {src} />
+
<span class="eye-text">{timeDollcode}</span>
+
</div>
+
+
<style lang="postcss">
+
.eye-text {
+
@apply text-sm [font-family:Doll_Mono] opacity-30 group-hover:opacity-80;
+
}
+
.eye-image {
+
@apply opacity-50 group-hover:opacity-100;
+
image-rendering: pixelated !important;
+
filter: drop-shadow(4px 4px 0 theme(colors.ralsei.green.light))
+
drop-shadow(-4px -4px 0 theme(colors.ralsei.pink.neon));
+
}
+
</style>
+31
eunomia/src/components/navButton.svelte
···
+
<script lang="ts">
+
interface Props {
+
highlight?: boolean;
+
name: string;
+
href: string;
+
iconUri: string;
+
}
+
+
let { highlight = false, name, href, iconUri }: Props = $props();
+
</script>
+
+
<a
+
class="
+
max-w-36 p-0.5 pr-1.5 border-ralsei-white border-4
+
{highlight
+
? 'min-w-36 bg-gradient-to-l to-ralsei-pink-neon/30 from-ralsei-pink-regular/20 from-30% border-ridge motion-safe:animate-pulse hover:animate-none'
+
: 'w-fit border-double hover:border-solid animate-bounce-reverse hover:underline'}
+
flex gap-1 items-center justify-center align-middle text-center
+
{highlight ? 'text-ralsei-pink-regular app-selected-route' : 'text-ralsei-green-light'}
+
"
+
title={name}
+
href="/{href}"
+
data-sveltekit-preload-data="tap"
+
>
+
<img class="max-w-4" style="image-rendering: pixelated;" src={iconUri} alt={name} />
+
<div
+
class="font-monospace text-sm/3 overflow-hidden text-ellipsis text-nowrap [text-decoration-line:inherit]"
+
>
+
{name}
+
</div>
+
</a>
+127
eunomia/src/components/note.svelte
···
+
<script module lang="ts">
+
import type { Post } from '@skyware/bot';
+
+
export interface OutgoingLink {
+
name: string;
+
link: string;
+
}
+
+
export interface NoteData {
+
content: string;
+
published: number;
+
hasMedia: boolean;
+
hasQuote: boolean;
+
outgoingLinks?: OutgoingLink[];
+
purposeAction?: string;
+
children?: NoteData[];
+
depth?: number;
+
}
+
+
export const flattenNotes = (note: NoteData, currentDepth: number = 0): NoteData[] => {
+
note.depth = currentDepth;
+
const flattened = [note];
+
if (note.children) {
+
note.children.forEach((child) => {
+
flattened.push(...flattenNotes(child, currentDepth + 1));
+
});
+
}
+
return flattened;
+
};
+
+
export const noteFromBskyPost = (post: Post): NoteData => {
+
return {
+
content: post.text,
+
published: post.createdAt.getTime(),
+
outgoingLinks: [{ name: 'bsky', link: post.uri }],
+
hasMedia:
+
(post.embed?.isImages() || post.embed?.isVideo() || post.embed?.isRecordWithMedia()) ??
+
false,
+
hasQuote: (post.embed?.isRecord() || post.embed?.isRecordWithMedia()) ?? false
+
};
+
};
+
</script>
+
+
<script lang="ts">
+
import Token from './token.svelte';
+
import { renderDate, renderRelativeDate } from '$lib/dateFmt';
+
+
interface Props {
+
rootNote: NoteData;
+
isHighlighted?: boolean;
+
onlyContent?: boolean;
+
showOutgoing?: boolean;
+
mapOutgoingNames?: Record<string, string>;
+
}
+
+
let {
+
rootNote,
+
isHighlighted = false,
+
onlyContent = false,
+
showOutgoing = true,
+
mapOutgoingNames = {}
+
}: Props = $props();
+
+
const getOutgoingLink = ({ name, link }: { name: string; link: string }) => {
+
if (name.startsWith('bsky')) {
+
// Parse the atproto URI to extract DID and rkey
+
const match = link.match(/at:\/\/(did:[^/]+)\/[^/]+\/([^/]+)/);
+
if (match && match.length >= 3) {
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
+
const [_, did, rkey] = match;
+
link = `https://bsky.app/profile/${did}/post/${rkey}`;
+
}
+
if (name === 'bsky-reply') {
+
return ['reply', link];
+
} else {
+
return [name, link];
+
}
+
}
+
return [name, link];
+
};
+
// this is ASS this should be a tailwind class
+
const getTextShadowStyle = (color: string) => {
+
return `text-shadow: 0 0 1px theme(colors.ralsei.black), 0 0 5px ${color};`;
+
};
+
const outgoingLinkColors: Record<string, string> = {
+
bsky: 'rgb(0, 133, 255)',
+
reply: 'rgb(0, 133, 255)'
+
};
+
</script>
+
+
{#each flattenNotes(rootNote) as note}
+
<p class="m-0 max-w-[70ch] text-wrap break-words leading-tight align-middle">
+
{#if note.depth ?? 0 > 0}
+
<span class="inline-block">|{'=='.repeat(note.depth ?? 0)}</span>&gt;
+
{/if}
+
{#if !onlyContent}
+
{#if (note.purposeAction ?? '').length > 0}
+
<Token v="({note.purposeAction!})" small={!isHighlighted} funct />
+
{/if}
+
{#if note.purposeAction !== 'reply'}
+
<Token
+
title={renderDate(note.published)}
+
v={renderRelativeDate(note.published)}
+
small={!isHighlighted}
+
/>
+
{/if}
+
{/if}
+
<Token v={note.content} str />
+
{#if note.hasMedia}<Token v="-contains media-" keywd small />{/if}
+
{#if note.hasQuote}<Token v="-contains quote-" keywd small />{/if}
+
{#if showOutgoing}
+
{#each (note.outgoingLinks ?? []).map(getOutgoingLink) as [name, link]}
+
{@const color = outgoingLinkColors[name]}
+
{@const viewName = mapOutgoingNames[name] ?? name}
+
{#if viewName.length > 0}
+
<span class="text-sm"
+
><Token v="(" punct /><a
+
class="hover:motion-safe:animate-squiggle hover:underline"
+
style="color: {color};{getTextShadowStyle(color)}"
+
href={link}>{viewName}</a
+
><Token v=")" punct /></span
+
>
+
{/if}
+
{/each}
+
{/if}
+
</p>
+
{/each}
+304
eunomia/src/components/pet.svelte
···
+
<script module lang="ts">
+
import { get, writable } from 'svelte/store';
+
+
export const localDistanceTravelled = writable(0.0);
+
export const localBounces = writable(0);
+
</script>
+
+
<script lang="ts">
+
import { draggable } from '@neodrag/svelte';
+
import { browser } from '$app/environment';
+
+
interface Props {
+
apiToken: string;
+
}
+
+
let { apiToken }: Props = $props();
+
+
let lastDragged = 0;
+
let mouseX = 0;
+
let mouseY = 0;
+
+
let position = $state({ x: 0, y: 0 });
+
let rotation = $state(0.0);
+
let sprite = $state('/pet/idle.webp');
+
let flip = $state(false);
+
let dragged = $state(false);
+
+
let targetX = 120;
+
let speed = 10.0;
+
let tickRate = 20;
+
let delta = 1.0 / tickRate;
+
+
let strideRadius = 4.0;
+
let strideAngle = 0;
+
+
const turnStrideWheel = (by: number) => {
+
strideAngle += by / strideRadius;
+
if (strideAngle > Math.PI * 2) {
+
strideAngle -= Math.PI * 2;
+
} else if (strideAngle < 0) {
+
strideAngle += Math.PI * 2;
+
}
+
};
+
+
let targetRotation = 0.0;
+
let rotationVelocity = 0.0;
+
let springStiffness = 20.0; // How quickly rotation returns to target
+
let springDamping = 0.2; // Damping factor to prevent oscillation
+
+
const updateRotationSpring = () => {
+
// Spring physics: calculate force based on distance from target
+
const springForce = (targetRotation - rotation) * springStiffness;
+
+
// Apply damping to velocity
+
rotationVelocity = rotationVelocity * (1 - springDamping) + springForce * delta;
+
+
// Update rotation based on velocity
+
rotation += rotationVelocity * delta;
+
+
// If we're very close to target and barely moving, just snap to target
+
if (Math.abs(rotation - targetRotation) < 0.01 && Math.abs(rotationVelocity) < 0.01) {
+
rotation = targetRotation;
+
rotationVelocity = 0;
+
}
+
};
+
+
// Add spring update to the move function
+
if (browser) setInterval(updateRotationSpring, tickRate);
+
+
const moveTowards = (from: number, to: number, by: number) => {
+
let d = (to - from) * 1.0;
+
let l = Math.abs(d);
+
let s = Math.sign(d);
+
let moveBy = s * Math.min(l, by) * delta;
+
return moveBy;
+
};
+
+
// Physics constants
+
let velocityX = 0;
+
let velocityY = 0;
+
let gravity = 200.0; // Gravity strength (positive because -Y is up)
+
let friction = 0.96; // Air friction
+
let groundFriction = 0.9; // Ground friction
+
let bounciness = 0.8; // How much energy is preserved on bounce
+
+
const sendBounceMetrics = () => {
+
fetch(`/_api/pet/bounce?_token=${apiToken}`);
+
localBounces.set(get(localBounces) + 1);
+
};
+
+
let deltaTravelled = 0.0;
+
let deltaTravelledTotal = 0.0;
+
const updateDistanceTravelled = () => {
+
if (deltaTravelled > 0.1 || deltaTravelled < -0.1) {
+
localDistanceTravelled.update((n) => {
+
n += deltaTravelled;
+
return n;
+
});
+
deltaTravelledTotal += deltaTravelled;
+
}
+
deltaTravelled = 0.0;
+
};
+
+
const sendTotalDistance = () => {
+
fetch(`/_api/pet/distance?_token=${apiToken}`, {
+
method: 'POST',
+
body: deltaTravelledTotal.toString()
+
});
+
deltaTravelledTotal = 0.0;
+
};
+
+
// sending every 5 seconds is probably reliable enough
+
if (browser) setInterval(sendTotalDistance, 1000 * 5);
+
+
const move = () => {
+
if (dragged) return;
+
+
// Apply physics when pet is in motion
+
if (velocityX !== 0 || velocityY !== 0 || position.y !== 0) {
+
// Apply gravity (remember negative Y is upward)
+
velocityY += gravity * delta;
+
+
// Apply friction
+
const fric = position.y === 0 ? groundFriction : friction;
+
velocityX *= fric;
+
velocityY *= fric;
+
+
// Update position
+
const moveX = velocityX * delta;
+
const moveY = velocityY * delta;
+
position.x += moveX;
+
position.y += moveY;
+
+
deltaTravelled += Math.sqrt(moveX ** 2 + moveY ** 2);
+
updateDistanceTravelled();
+
+
// Handle window boundaries
+
const viewportWidth = window.innerWidth;
+
+
// Bounce off sides
+
if (position.x < 0) {
+
position.x = 0;
+
velocityX = -velocityX * bounciness;
+
sendBounceMetrics();
+
} else if (position.x > viewportWidth) {
+
position.x = viewportWidth;
+
velocityX = -velocityX * bounciness;
+
sendBounceMetrics();
+
}
+
+
// Bounce off bottom (floor)
+
if (position.y > 0) {
+
position.y = 0;
+
velocityY = -velocityY * bounciness;
+
// Only bounce if velocity is significant
+
if (Math.abs(velocityY) < 80) {
+
velocityY = 0;
+
position.y = 0;
+
} else {
+
sendBounceMetrics();
+
}
+
}
+
+
// reset velocity
+
if (Math.abs(velocityX) < 5 && Math.abs(velocityY) < 5) {
+
velocityX = 0;
+
velocityY = 0;
+
}
+
+
// Update flip based on velocity
+
if (Math.abs(velocityX) > 0.5) {
+
flip = velocityX < 0;
+
}
+
+
targetRotation = velocityX * 0.02 + velocityY * 0.01;
+
+
return;
+
}
+
+
// Normal movement when not physics-based
+
let moveByX = moveTowards(position.x, targetX, speed * ((self.innerWidth ?? 1600.0) / 1600.0));
+
position.x += moveByX;
+
+
turnStrideWheel(moveByX);
+
+
flip = moveByX < 0.0;
+
if (moveByX > 0.1 || moveByX < -0.1) {
+
sprite = strideAngle % Math.PI < Math.PI * 0.5 ? '/pet/walk1.webp' : '/pet/walk2.webp';
+
} else {
+
sprite = '/pet/idle.webp';
+
}
+
+
deltaTravelled += Math.abs(moveByX);
+
updateDistanceTravelled();
+
};
+
+
if (browser) setInterval(move, tickRate);
+
+
const shake = (event: DeviceMotionEvent) => {
+
const accel = event.acceleration ?? event.accelerationIncludingGravity;
+
if (accel === null || accel.x === null || accel.y === null) return;
+
if (Math.abs(accel.x) + Math.abs(accel.y) < 40.0) return;
+
// make it so that it amplifies motion proportionally to the window size
+
const windowRatio = (window.innerWidth * 1.0) / (window.innerHeight * 1.0);
+
velocityX += accel.x * windowRatio * 5.0;
+
velocityY += accel.y * (1.0 / windowRatio) * 5.0;
+
sprite = '/pet/pick.webp';
+
};
+
+
if (browser) self.ondevicemotion = shake;
+
+
// this is for ios
+
const askForShakePermission = () => {
+
if (
+
typeof DeviceMotionEvent !== 'undefined' &&
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
typeof (DeviceMotionEvent as any).requestPermission === 'function'
+
) {
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
(DeviceMotionEvent as any)
+
.requestPermission()
+
.then((permissionState: string) => {
+
if (permissionState === 'granted') {
+
self.ondevicemotion = shake;
+
}
+
})
+
.catch(console.error);
+
}
+
};
+
+
const pickNewTargetX = () => {
+
const viewportWidth = self.innerWidth || null;
+
if (viewportWidth !== null && Math.abs(position.x - targetX) < 5) {
+
targetX = Math.max(
+
Math.min(targetX + (Math.random() - 0.5) * (viewportWidth * 0.5), viewportWidth * 0.9),
+
viewportWidth * 0.1
+
);
+
}
+
// Set a random interval for the next target update (between 4-10 seconds)
+
const randomDelay = Math.floor(Math.random() * 6000) + 4000;
+
setTimeout(pickNewTargetX, randomDelay);
+
};
+
+
// Start the process
+
if (browser) setTimeout(pickNewTargetX, 1000);
+
</script>
+
+
<!-- svelte-ignore a11y_missing_attribute -->
+
<div
+
use:draggable={{
+
position,
+
applyUserSelectHack: true,
+
handle: 'img',
+
bounds: {
+
bottom: (window.innerHeight / 100) * 5.5
+
},
+
onDragStart: () => {
+
sprite = '/pet/pick.webp';
+
dragged = true;
+
},
+
onDrag: ({ offsetX, offsetY, event }) => {
+
position.x = offsetX;
+
position.y = offsetY;
+
const mouseXD = event.movementX * delta;
+
const mouseYD = event.movementY * delta;
+
deltaTravelled += Math.sqrt(mouseXD ** 2 + mouseYD ** 2);
+
// reset mouse movement if it's not moving in the same direction so it doesnt accumulate its weird!@!@
+
mouseX = Math.sign(mouseXD) != Math.sign(mouseX) ? mouseXD : mouseX + mouseXD;
+
mouseY = Math.sign(mouseYD) != Math.sign(mouseY) ? mouseYD : mouseY + mouseYD;
+
rotationVelocity += mouseXD + mouseYD;
+
lastDragged = Date.now();
+
},
+
onDragEnd: () => {
+
// reset mouse movement if we stopped for longer than some time
+
if (Date.now() - lastDragged > 50) {
+
mouseX = 0.0;
+
mouseY = 0.0;
+
}
+
// apply velocity based on rotation since we already keep track of that
+
velocityX = mouseX * 70.0;
+
velocityY = mouseY * 50.0;
+
updateDistanceTravelled();
+
// reset mouse movement we dont want it to accumulate
+
mouseX = 0.0;
+
mouseY = 0.0;
+
dragged = false;
+
}
+
}}
+
class="fixed bottom-[5vh] z-[1000] hover:animate-squiggle"
+
style="cursor: url('/icons/gaze.webp'), pointer;"
+
>
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
+
<img
+
draggable="false"
+
onclick={askForShakePermission}
+
style="
+
image-rendering: pixelated !important;
+
transform: rotate({rotation}rad) scaleX({flip ? -1 : 1});
+
filter: invert(100%) drop-shadow(2px 2px 0 black) drop-shadow(-2px -2px 0 black);
+
"
+
src={sprite}
+
/>
+
</div>
+32
eunomia/src/components/token.svelte
···
+
<script lang="ts">
+
+
+
interface Props {
+
punct?: boolean;
+
keywd?: boolean;
+
funct?: boolean;
+
str?: boolean;
+
small?: boolean;
+
v: string;
+
title?: string;
+
}
+
+
let {
+
punct = false,
+
keywd = false,
+
funct = false,
+
str = false,
+
small = false,
+
title,
+
v
+
}: Props = $props();
+
+
const ty =
+
punct ? "punctuation"
+
: keywd ? "keyword"
+
: funct ? "function"
+
: str ? "string"
+
: ""
+
</script>
+
+
<span {title} class="token {ty} {small ? "text-sm" : ""}">{v}</span>
+34
eunomia/src/components/tooltip.svelte
···
+
<script lang="ts">
+
import Window from './window.svelte';
+
+
interface Props {
+
x?: string;
+
y?: string;
+
targetY?: string;
+
targetX?: string;
+
tooltipContent?: import('svelte').Snippet;
+
children?: import('svelte').Snippet;
+
style?: string;
+
}
+
+
let {
+
x = 'translate-x-none',
+
y = 'translate-y-full',
+
targetY = 'group-hover:-translate-y-[105%]',
+
targetX = 'group-hover:-translate-x-2/3',
+
tooltipContent,
+
children,
+
style = ''
+
}: Props = $props();
+
</script>
+
+
<div class="group" {style}>
+
<div
+
class="z-10 absolute scale-0 transition-all [transition-timing-function:cubic-bezier(0.4,0,0.2,1.6)] [transition-duration:300ms] opacity-0 group-hover:scale-100 group-hover:opacity-100 {y} {x} {targetY} {targetX}"
+
>
+
<Window tooltip>
+
{#if tooltipContent}{@render tooltipContent()}{:else}Hello world!{/if}
+
</Window>
+
</div>
+
{@render children?.()}
+
</div>
+124
eunomia/src/components/window.svelte
···
+
<script lang="ts">
+
import { highestZIndex, isMobile } from '$lib/window.ts';
+
import { draggable } from '@neodrag/svelte';
+
+
interface Props {
+
title?: string;
+
iconUri?: string;
+
id?: string;
+
sticky?: boolean;
+
entry?: boolean;
+
removePadding?: boolean;
+
center?: boolean;
+
layered?: boolean;
+
style?: string;
+
tooltip?: boolean;
+
children?: import('svelte').Snippet;
+
}
+
+
let {
+
title = undefined,
+
iconUri = '',
+
id = '',
+
sticky = false,
+
entry = false,
+
removePadding = false,
+
center = false,
+
layered = false,
+
style = '',
+
tooltip = false,
+
children
+
}: Props = $props();
+
+
const scaleKeyframes = [
+
'window-open',
+
'window-open-vertical',
+
'window-open-vertical',
+
'window-open-horizontal',
+
'window-open-horizontal',
+
'window-open-move-up',
+
'window-open-move-down',
+
'window-open-move-left',
+
'window-open-move-right'
+
];
+
let chosenKeyframe = $derived(
+
scaleKeyframes.at(Math.floor(Math.random() * scaleKeyframes.length))
+
);
+
+
const isOnMobile = isMobile();
+
const _draggable = isOnMobile ? () => {} : draggable;
+
+
const focusWindow = (node: HTMLElement) => {
+
if (isOnMobile) return;
+
$highestZIndex += 1;
+
node.style.zIndex = $highestZIndex.toString();
+
};
+
</script>
+
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
+
<div
+
use:_draggable={{
+
disabled: isOnMobile,
+
applyUserSelectHack: true,
+
handle: '.window-titlebar',
+
onDragStart: (data) => {
+
focusWindow(data.currentNode);
+
}
+
}}
+
onclick={(data) => {
+
focusWindow(data.currentTarget);
+
}}
+
class="
+
relative flex flex-col w-full md:w-fit [height:fit-content]
+
{center ? 'mx-auto' : ''}
+
{layered ? 'col-[1] row-[1]' : ''}
+
{sticky ? 'md:sticky md:-top-9' : ''}
+
max-w-screen-sm lg:max-w-screen-md xl:max-w-screen-lg 2xl:max-w-screen-xl
+
{tooltip ? 'min-w-fit' : ''}
+
bg-ralsei-black border-ralsei-white border-ridge
+
{tooltip ? 'border-[6px] border-t-[9px]' : 'border-[7px] border-t-[12px]'}
+
{isOnMobile || tooltip ? '' : 'hover:-translate-x-1 hover:translate-y-1'}
+
animate-{chosenKeyframe} drop-shadow-[24px_24px_24px_rgba(1,1,1,0.8)]
+
{style}
+
"
+
{id}
+
>
+
{#if title !== undefined}
+
<div
+
class="
+
window-titlebar p-1 border-ralsei-white border-8
+
bg-gradient-to-l from-ralsei-pink-neon to-ralsei-black to-75%
+
{!isOnMobile ? 'cursor-move' : ''}
+
"
+
style="border-style: hidden hidden ridge hidden;"
+
>
+
<div class="flex bg-opacity-100 pixelate-bg">
+
<h1
+
class="
+
font-monospace text-xl text-ralsei-pink-regular
+
grow justify-self-start self-center {entry ? 'p-name' : ''}
+
"
+
>
+
{title}
+
</h1>
+
{#if iconUri !== ''}
+
<img
+
class="justify-self-end self-center max-h-7"
+
style="image-rendering: pixelated;"
+
src={iconUri}
+
alt={iconUri}
+
/>
+
{/if}
+
</div>
+
</div>
+
{/if}
+
<div
+
class="
+
{removePadding ? '' : tooltip ? 'p-1' : 'p-2'} bg-gradient-to-tl
+
to-ralsei-pink-neon/15 from-ralsei-pink-regular/20
+
"
+
>
+
{@render children?.()}
+
</div>
+
</div>
+142
eunomia/src/hooks.server.ts
···
+
import { updateLastPosts } from '$lib/bluesky';
+
import { getLastTrack, updateNowPlayingTrack } from '$lib/lastfm';
+
import { steamReadLastGame, steamUpdateNowPlaying } from '$lib/steam';
+
import { updateCommits } from '$lib/activity';
+
import { ToadScheduler, SimpleIntervalJob, Task, AsyncTask } from 'toad-scheduler';
+
import {
+
incrementFakeVisitCount,
+
incrementLegitVisitCount,
+
pushMetric,
+
sendAllMetrics
+
} from '$lib/metrics';
+
import {
+
addLastVisitor,
+
decrementVisitCount,
+
incrementVisitCount,
+
notifyDarkVisitors,
+
removeLastVisitor
+
} from '$lib/visits';
+
import { testUa } from '$lib/robots';
+
import { error, type Handle } from '@sveltejs/kit';
+
import { _fetchEntries } from './routes/(site)/guestbook/+page.server';
+
import { sequence } from '@sveltejs/kit/hooks';
+
+
const updateNowPlaying = async () => {
+
try {
+
await Promise.all([steamUpdateNowPlaying(), updateNowPlayingTrack()]);
+
} catch (err) {
+
console.log(`error while updating: ${err}`);
+
}
+
};
+
const refreshContent = async () => {
+
try {
+
await Promise.all([updateLastPosts(), _fetchEntries(), updateCommits(), sendAllMetrics()]);
+
} catch (err) {
+
console.log(`error while updating: ${err}`);
+
}
+
};
+
+
await Promise.all([updateNowPlaying(), refreshContent()]);
+
+
const scheduler = new ToadScheduler();
+
scheduler.addSimpleIntervalJob(
+
new SimpleIntervalJob(
+
{ seconds: 5 },
+
new AsyncTask('updateNowPlaying task', updateNowPlaying, (err) =>
+
console.log(`error while updateNowPlaying: ${err}`)
+
)
+
)
+
);
+
scheduler.addSimpleIntervalJob(
+
new SimpleIntervalJob(
+
{ seconds: 30 },
+
new AsyncTask('refreshContent task', refreshContent, (err) =>
+
console.log(`error while refreshContent: ${err}`)
+
)
+
)
+
);
+
+
const corsHandler = (allowedOrigins = ['*']) => {
+
return async ({ event, resolve }: Parameters<Handle>[0]) => {
+
const origin = event.request.headers.get('origin');
+
+
const corsHeaders: Record<string, string> = {
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
+
};
+
+
if (allowedOrigins.includes('*'))
+
corsHeaders['Access-Control-Allow-Origin'] = '*';
+
else if (origin && allowedOrigins.includes(origin)) {
+
corsHeaders['Access-Control-Allow-Origin'] = origin;
+
corsHeaders['Access-Control-Allow-Credentials'] = 'true';
+
}
+
+
if (event.request.method === 'OPTIONS')
+
return new Response(null, { headers: corsHeaders });
+
+
const response = await resolve(event);
+
+
Object.entries(corsHeaders).forEach(([key, value]) => {
+
response.headers.set(key, value);
+
});
+
+
return response;
+
};
+
}
+
+
const handler = async ({ event, resolve }: Parameters<Handle>[0]) => {
+
notifyDarkVisitors(event.url, event.request); // no await so it doesnt block
+
+
const isPrefetch = () => {
+
return (
+
event.request.headers.get('Sec-Purpose')?.includes('prefetch') ||
+
event.request.headers.get('Purpose')?.includes('prefetch') ||
+
event.request.headers.get('x-purpose')?.includes('preview') ||
+
event.request.headers.get('x-moz')?.includes('prefetch')
+
);
+
};
+
const isApi = () => {
+
return event.url.pathname.startsWith('/_api');
+
};
+
const isRss = () => {
+
return event.url.pathname.endsWith('/_rss');
+
};
+
+
// block any requests if the user agent is disallowed by our robots txt
+
const isFakeVisit =
+
(await testUa(event.url.toString(), event.request.headers.get('user-agent') ?? '')) === false;
+
if (isFakeVisit) {
+
pushMetric({ gazesys_visit_fake_total: await incrementFakeVisitCount() });
+
throw error(403, 'get a better user agent silly');
+
}
+
+
// only push metric if legit page visit (still want rss to count here though)
+
const isPageVisit = !isApi() && !isPrefetch();
+
if (isPageVisit) pushMetric({ gazesys_visit_real_total: await incrementLegitVisitCount() });
+
+
// only add visitors if its a "legit" page visit
+
let id = null;
+
let valid = false;
+
if (isPageVisit && !isRss()) {
+
id = addLastVisitor(event.request, event.cookies);
+
valid = await incrementVisitCount(event.request, event.cookies);
+
}
+
+
// actually resolve event
+
const resp = await resolve(event);
+
// remove visitors if it was a 404
+
if (resp.status === 404) {
+
if (id !== null) removeLastVisitor(id);
+
if (valid) decrementVisitCount();
+
}
+
+
return resp;
+
};
+
+
const allowedOrigins = [
+
"https://gaze.systems",
+
"https://ptr.pet",
+
"https://poor.dog",
+
];
+
export const handle = sequence(corsHandler(allowedOrigins), handler);
+123
eunomia/src/lib/activity.ts
···
+
import { get, writable } from 'svelte/store';
+
import { parseFeed } from '@rowanmanning/feed-parser';
+
+
const lastCommits = writable<Activity[]>([]);
+
+
export const updateCommits = async () => {
+
try {
+
const githubFeed = await parseFeedToActivity('https://github.com/90-008.atom');
+
const codebergFeed = await parseFeedToActivity('https://codeberg.org/90-008.atom');
+
const tangledFeed = await fetchTangledActivity();
+
const mergedFeed = sortActivities(
+
githubFeed.concat(codebergFeed).concat(tangledFeed)
+
).slice(0, 7);
+
lastCommits.set(mergedFeed);
+
} catch (why) {
+
console.log('could not fetch git activity: ', why);
+
}
+
};
+
+
export const getLastActivity = () => {
+
return get(lastCommits);
+
};
+
+
type Activity = {
+
source: string;
+
description: string;
+
link: string | null;
+
date: Date | null;
+
};
+
+
const toHex = (bytes: number[]): string => {
+
return bytes.map((b) => b.toString(16).padStart(2, '0')).join('');
+
};
+
+
const fetchTangledActivity = async (): Promise<Activity[]> => {
+
// todo: auto resolve pds and knots
+
const did = 'did:plc:dfl62fgb7wtjj3fcbb72naae';
+
const pds = 'https://zwsp.xyz';
+
const knot = 'https://knot.gaze.systems';
+
const activities: Activity[] = [];
+
+
try {
+
// todo: fetch until we exhaust
+
const listRes = await fetch(
+
`${pds}/xrpc/com.atproto.repo.listRecords?repo=${did}&collection=sh.tangled.repo`
+
);
+
if (!listRes.ok) return [];
+
const listData = await listRes.json();
+
+
for (const record of listData.records || []) {
+
const repoName = record.value.name;
+
if (!repoName) continue;
+
+
try {
+
const logRes = await fetch(
+
`${knot}/xrpc/sh.tangled.repo.log?repo=${did}/${repoName}`
+
);
+
if (!logRes.ok) continue;
+
const logData = await logRes.json();
+
+
const commits = logData.commits || [];
+
+
for (const commit of commits) {
+
const hash = commit.Hash ? toHex(commit.Hash) : '';
+
const message = commit.Message || '';
+
const dateStr = commit.Author?.When;
+
+
activities.push({
+
source: 'tangled',
+
description: `pushed ${repoName}: ${message}`,
+
link: `https://tangled.sh/${did}/${repoName}/commit/${hash}`,
+
date: dateStr ? new Date(dateStr) : null
+
});
+
}
+
} catch (err) {
+
console.log(`could not fetch tangled log for ${repoName}:`, err);
+
}
+
}
+
} catch (err) {
+
console.log('could not fetch tangled repos:', err);
+
}
+
return activities;
+
};
+
+
const parseFeedToActivity = async (url: string) => {
+
const response = await fetch(url);
+
const feed = parseFeed(await response.text());
+
+
const source = new URL(url).host.split('.')[0];
+
const results: Activity[] = [];
+
for (const item of feed.items) {
+
const description: string | null = item.description || item.title;
+
if (description === null) continue;
+
// dont count mirrored repos
+
// TODO: probably can implement a deduplication algorithm
+
if (
+
['90-008/ark', '90-008/website', 'ark', 'website'].some((repo) =>
+
description.includes(repo)
+
)
+
)
+
continue;
+
// dont show activity that is just chore
+
if (item.content?.includes('chore')) continue;
+
const desc = description.split('</a>').at(1) || description.split('</a>').pop() || '';
+
results.push({
+
source,
+
description: desc.replace(/^90-008 /, ""),
+
link: item.url,
+
date: item.published || item.updated
+
});
+
}
+
+
return results;
+
};
+
+
const sortActivities = (activities: Array<Activity>) => {
+
return activities.sort((a, b) => {
+
if (a.date === null && b.date === null) return 0;
+
if (a.date === null) return 1;
+
if (b.date === null) return -1;
+
return b.date.getTime() - a.date.getTime();
+
});
+
};
+26
eunomia/src/lib/apiToken.ts
···
+
import { nanoid } from 'nanoid';
+
import { get, writable } from 'svelte/store';
+
+
const tokens = writable<Map<string, number>>(new Map());
+
+
export const newToken = () => {
+
const token = nanoid(100);
+
tokens.update((v) => v.set(token, Date.now()));
+
return token;
+
};
+
export const useToken = (token: string) => {
+
const _tokens = get(tokens);
+
// delete older tokens
+
for (const [_token, timestamp] of _tokens) {
+
if (Date.now() - timestamp > 30 * 60 * 1000) {
+
_tokens.delete(_token);
+
}
+
}
+
tokens.set(_tokens);
+
return _tokens.has(token);
+
};
+
+
export const checkUrl = (url: URL) => {
+
const token = url.searchParams.get('_token');
+
return token !== null && useToken(token);
+
};
+60
eunomia/src/lib/bluesky.ts
···
+
import { env } from '$env/dynamic/private';
+
import { Bot, type Post } from '@skyware/bot';
+
import { get, writable } from 'svelte/store';
+
+
const bskyClient = writable<null | Bot>(null);
+
+
export const getBskyClient = async () => {
+
let client = get(bskyClient);
+
if (client === null) {
+
client = await loginToBsky();
+
bskyClient.set(client);
+
}
+
return client;
+
};
+
+
const loginToBsky = async () => {
+
const password = env.BSKY_PASSWORD ?? null;
+
if (password === null) {
+
throw new Error('no password provided');
+
}
+
const bot = new Bot({ service: 'https://gaze.systems' });
+
await bot.login({ identifier: 'guestbook.gaze.systems', password });
+
return bot;
+
};
+
+
export const getUserPosts = async (
+
did: string,
+
count: number = 10,
+
cursor: string | null = null
+
) => {
+
const client = await getBskyClient();
+
let feedCursor: string | null | undefined = cursor;
+
const posts: Post[] = [];
+
// fetch requested amount of posts
+
while (posts.length < count - 1 && (typeof feedCursor === 'string' || feedCursor === null)) {
+
const feedData = await client.getUserPosts(did, {
+
limit: count,
+
filter: 'posts_no_replies',
+
cursor: feedCursor === null ? undefined : feedCursor
+
});
+
posts.push(...feedData.posts.filter((post) => post.author.did === did));
+
feedCursor = feedData.cursor;
+
}
+
return { posts, cursor: feedCursor === null ? undefined : feedCursor };
+
};
+
+
const lastPosts = writable<Post[]>([]);
+
+
export const updateLastPosts = async () => {
+
try {
+
const { posts } = await getUserPosts('did:plc:dfl62fgb7wtjj3fcbb72naae', 10);
+
lastPosts.set(posts);
+
} catch (err) {
+
console.log(`can't update last posts ${err}`);
+
}
+
};
+
+
export const getLastPosts = () => {
+
return get(lastPosts);
+
};
+22
eunomia/src/lib/convertDate.ts
···
+
const months = [
+
'Jan',
+
'Feb',
+
'Mar',
+
'Apr',
+
'May',
+
'Jun',
+
'Jul',
+
'Aug',
+
'Sep',
+
'Oct',
+
'Nov',
+
'Dec'
+
];
+
+
const convertDate = (published: string) => {
+
const date = published.substring(0, 10);
+
const [year, month, day] = date.split('-');
+
return `${day} ${months[parseInt(month) - 1]} ${year}`;
+
};
+
+
export default convertDate;
+35
eunomia/src/lib/counter.ts
···
+
import { get, writable } from 'svelte/store';
+
+
/**
+
* Creates a persistent counter that is stored in a file
+
* @param fileName The name of the file to store the count in
+
* @param initialValue The initial value if the file doesn't exist
+
* @returns An object with methods to get, increment, and set the count
+
*/
+
export const createFileCounter = async (filePath: string, initialValue: number = 0) => {
+
let countRaw: string | null = null;
+
try {
+
countRaw = await Deno.readTextFile(filePath);
+
} catch {}
+
+
const counter = writable(parseInt(countRaw ?? initialValue.toString()));
+
+
const saveToFile = async (value: number) => {
+
await Deno.writeTextFile(filePath, value.toString());
+
return value;
+
};
+
+
return {
+
get: () => get(counter),
+
increment: (amount: number = 1) => {
+
const currentValue = get(counter) + amount;
+
counter.set(currentValue);
+
return saveToFile(currentValue);
+
},
+
set: (value: number) => {
+
counter.set(value);
+
return saveToFile(value);
+
},
+
subscribe: counter.subscribe
+
};
+
};
+25
eunomia/src/lib/dateFmt.ts
···
+
export const renderRelativeDate = (timestamp: number) => {
+
const elapsed = timestamp - new Date().getTime();
+
const units: Record<string, number> = {
+
year: 24 * 60 * 60 * 1000 * 365,
+
month: (24 * 60 * 60 * 1000 * 365) / 12,
+
day: 24 * 60 * 60 * 1000,
+
hour: 60 * 60 * 1000,
+
minute: 60 * 1000,
+
second: 1000
+
};
+
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
+
for (const unit in units)
+
if (Math.abs(elapsed) > units[unit] || unit == 'second')
+
return rtf.format(Math.round(elapsed / units[unit]), unit as Intl.RelativeTimeFormatUnit);
+
return '';
+
};
+
export const renderDate = (timestamp: number) => {
+
return new Date(timestamp).toLocaleString('en-GB', {
+
year: '2-digit',
+
month: '2-digit',
+
day: '2-digit',
+
hour: '2-digit',
+
minute: '2-digit'
+
});
+
};
+23
eunomia/src/lib/dollcode.ts
···
+
// https://noe.sh/dollcode/
+
const charmap = ['โ–Œ', 'โ––', 'โ–˜'];
+
export const genDollcode = (number: number) => {
+
const output = [];
+
let window = number;
+
let loopProtection = 1000;
+
+
while (loopProtection > 0 && window > 0) {
+
const mod = window % 3;
+
+
if (mod == 0) {
+
window = (window - 3) / 3;
+
} else {
+
window = (window - mod) / 3;
+
}
+
+
output.unshift(charmap[mod]);
+
+
loopProtection--;
+
}
+
+
return output.join('');
+
};
+11
eunomia/src/lib/getTitle.ts
···
+
const getTitle = (path: string) => {
+
let sl = path.split('/');
+
sl = sl.splice(1);
+
if (sl.length > 2) {
+
sl[0] = sl[0][0];
+
}
+
const newPath = sl.join('/');
+
return '//โ‹†โ˜€๏ธŽ. /' + newPath;
+
};
+
+
export default getTitle;
+28
eunomia/src/lib/index.ts
···
+
import type { Cookies } from '@sveltejs/kit';
+
import { hash } from 'node:crypto';
+
+
export const scopeCookies = (cookies: Cookies, path: string) => {
+
return {
+
get: (key: string) => {
+
return cookies.get(key);
+
},
+
set: (key: string, value: string, props: Omit<Parameters<Cookies['set']>[2], 'path'> = {}) => {
+
cookies.set(key, value, { ...props, path });
+
},
+
delete: (key: string, props: Omit<Parameters<Cookies['delete']>[1], 'path'> = {}) => {
+
cookies.delete(key, { ...props, path });
+
}
+
};
+
};
+
+
const cipherChars = ['#', '%', '+', '=', '//'];
+
export const fancyText = (input: string) => {
+
const hashed = hash('sha256', input, 'hex');
+
let result = '';
+
let idx = 0;
+
while (idx < hashed.length) {
+
result += cipherChars[hashed.charCodeAt(idx) % cipherChars.length];
+
idx += 1;
+
}
+
return result;
+
};
+103
eunomia/src/lib/lastfm.ts
···
+
import { env } from '$env/dynamic/private';
+
import { get, writable } from 'svelte/store';
+
+
const DID = 'did:plc:dfl62fgb7wtjj3fcbb72naae';
+
const PDS = 'https://zwsp.xyz';
+
const LAST_TRACK_FILE = `${env.WEBSITE_DATA_DIR}/last_track.json`;
+
+
type LastTrack = {
+
name: string;
+
artist: string;
+
album: string;
+
images: {
+
mb: string | null;
+
yt: string | null;
+
};
+
link: string | null;
+
when: number;
+
status: 'playing' | 'played';
+
};
+
const lastTrack = writable<LastTrack | null>(null);
+
+
export const getLastTrack = async () => {
+
try {
+
const data = await Deno.readTextFile(LAST_TRACK_FILE);
+
lastTrack.set(JSON.parse(data));
+
} catch (why) {
+
console.log('could not read last track: ', why);
+
lastTrack.set(null);
+
}
+
};
+
+
const getTrackCoverArt = (releaseMbId: string | null | undefined, originUrl: string | null | undefined) => {
+
let mb: string | null = null;
+
let yt: string | null = null;
+
+
if (releaseMbId) mb = `https://coverartarchive.org/release/${releaseMbId}/front-250`;
+
+
try {
+
if (originUrl) {
+
let videoId: string | null = null;
+
if (originUrl.includes('youtube.com') || originUrl.includes('music.youtube.com')) {
+
videoId = new URL(originUrl).searchParams.get('v');
+
} else if (originUrl.includes('youtu.be')) {
+
videoId = originUrl.split('youtu.be/')[1]?.split('?')[0];
+
}
+
if (videoId) yt = `https://img.youtube.com/vi/${videoId}/mqdefault.jpg`;
+
}
+
} catch {
+
}
+
+
return { mb, yt };
+
};
+
+
const joinArtists = (artists: any[]) => {
+
if (!artists || artists.length === 0) return null;
+
return artists.map((a) => a.artistName).join(', ');
+
};
+
+
export const updateNowPlayingTrack = async () => {
+
try {
+
let track: any = null;
+
let when: number = Date.now();
+
let status: 'playing' | 'played' = 'played';
+
+
try {
+
const statusRes = await fetch(
+
`${PDS}/xrpc/com.atproto.repo.getRecord?repo=${DID}&collection=fm.teal.alpha.actor.status&rkey=self`
+
);
+
if (statusRes.ok) {
+
const statusData = await statusRes.json();
+
if (statusData.value?.item) {
+
const metadata = statusData.value;
+
track = statusData.value.item;
+
if (track.playedTime) when = new Date(track.playedTime).getTime();
+
status = ((Date.now() / 1000) >= (parseInt(metadata.time) + track.duration)) ? 'played' : 'playing';
+
}
+
}
+
} catch (err) {
+
console.log('could not fetch teal status:', err);
+
}
+
+
if (!track) return;
+
+
const data: LastTrack = {
+
name: track.trackName,
+
artist: joinArtists(track.artists) ?? 'Unknown Artist',
+
album: track.releaseName ?? 'Unknown Album',
+
images: getTrackCoverArt(track.releaseMbId, track.originUrl),
+
link: track.originUrl ?? null,
+
when: when,
+
status: status
+
};
+
+
lastTrack.set(data);
+
await Deno.writeTextFile(LAST_TRACK_FILE, JSON.stringify(data));
+
} catch (why) {
+
console.log('could not fetch teal fm: ', why);
+
}
+
};
+
+
export const getNowPlayingTrack = () => {
+
return get(lastTrack);
+
};
+52
eunomia/src/lib/metrics.ts
···
+
import { env } from '$env/dynamic/private';
+
import { pushMetrics } from 'prometheus-remote-write';
+
import { createFileCounter } from './counter';
+
+
const endpoint = env.PROMETHEUS_URL;
+
+
export const pushMetric = async (
+
metrics: Record<string, number>,
+
labels: Record<string, string> = {}
+
) => {
+
if (endpoint === undefined) return;
+
try {
+
const result = await pushMetrics(metrics, {
+
url: endpoint,
+
labels: {
+
service: 'website',
+
...labels
+
}
+
});
+
if (result.status != 204) {
+
throw new Error(`failed to push metrics: ${result.status} ${result.errorMessage}`);
+
}
+
} catch (err) {
+
console.log(`failed to push metrics: ${err}`);
+
}
+
};
+
+
export const sendAllMetrics = async () => {
+
try {
+
await pushMetric({
+
gazesys_pet_bounce_total: bounceCount.get(),
+
gazesys_visit_fake_total: fakeVisitCount.get(),
+
gazesys_visit_real_total: legitVisitCount.get(),
+
gazesys_pet_distance_total: distanceTravelled.get()
+
});
+
} catch (error) {
+
console.log(`failed to push metrics: ${error}`);
+
}
+
};
+
+
export const bounceCount = await createFileCounter(`${env.WEBSITE_DATA_DIR}/bouncecount`);
+
export const incrementBounceCount = bounceCount.increment;
+
+
export const legitVisitCount = await createFileCounter(`${env.WEBSITE_DATA_DIR}/legitvisitcount`);
+
export const incrementLegitVisitCount = legitVisitCount.increment;
+
+
export const fakeVisitCount = await createFileCounter(`${env.WEBSITE_DATA_DIR}/fakevisitcount`);
+
export const incrementFakeVisitCount = fakeVisitCount.increment;
+
+
export const distanceTravelled = await createFileCounter(
+
`${env.WEBSITE_DATA_DIR}/distancetravelled`
+
);
+32
eunomia/src/lib/pushnotif.ts
···
+
import { env } from '$env/dynamic/private';
+
+
export const pushNotification = (_content: string) => {
+
const content = encodeURIComponent(_content);
+
try {
+
// post to phone
+
fetch(
+
`https://api.day.app/${env.BARK_DEVICE_ID}/gaze.systems/${content}?icon=https://gaze.systems/icons/gaze_site.webp`
+
);
+
// post to discord
+
fetch(env.DISCORD_NOTIF_WEBHOOK || '', {
+
method: 'POST',
+
headers: {
+
'content-type': 'application/json'
+
},
+
body: JSON.stringify({
+
content: '<@853064602904166430>',
+
embeds: [
+
{
+
id: 677465216,
+
title: _content,
+
footer: {
+
text: 'notif from gaze.systems'
+
}
+
}
+
]
+
})
+
});
+
} catch (err) {
+
console.log(`failed to push notification: ${err}`);
+
}
+
};
+54
eunomia/src/lib/robots.ts
···
+
import { env } from '$env/dynamic/private'
+
import { get, writable } from 'svelte/store'
+
import { type Robot } from 'robots-parser'
+
import robotsParser from 'robots-parser'
+
import { PUBLIC_BASE_URL } from '$env/static/public'
+
+
const cachedParsedRobots = writable<Robot | null>(null)
+
const cachedRobots = writable<string>("")
+
const lastFetched = writable<number>(Date.now())
+
+
const fetchRobotsTxt = async () => {
+
const robotsTxtResp = await fetch(
+
"https://api.darkvisitors.com/robots-txts",
+
{
+
method: "POST",
+
headers: {
+
"Authorization": `Bearer ${env.DARK_VISITORS_TOKEN}`,
+
"Content-Type": "application/json"
+
},
+
body: JSON.stringify({
+
agent_types: [
+
"AI Assistant",
+
"AI Data Scraper",
+
"AI Search Crawler",
+
"Undocumented AI Agent",
+
],
+
disallow: "/"
+
})
+
}
+
)
+
const robotsTxt = await robotsTxtResp.text()
+
lastFetched.set(Date.now())
+
return robotsTxt
+
}
+
+
export const getRobotsTxt = async () => {
+
let robotsTxt = get(cachedRobots)
+
if (robotsTxt.length === 0 || Date.now() - get(lastFetched) > 1000 * 60 * 60 * 24) {
+
robotsTxt = await fetchRobotsTxt()
+
cachedRobots.set(robotsTxt)
+
cachedParsedRobots.set(robotsParser(`${PUBLIC_BASE_URL}/robots.txt`, robotsTxt))
+
}
+
return robotsTxt
+
}
+
+
export const testUa = async (url: string, ua: string) => {
+
if (ua.length === 0) return false
+
let parsedRobots = get(cachedParsedRobots)
+
if (parsedRobots === null) {
+
parsedRobots = robotsParser(`${PUBLIC_BASE_URL}/robots.txt`, await getRobotsTxt())
+
cachedParsedRobots.set(parsedRobots)
+
}
+
return parsedRobots.isAllowed(url, ua)
+
}
+73
eunomia/src/lib/steam.ts
···
+
import { env } from '$env/dynamic/private';
+
import SGDB from 'steamgriddb';
+
import { get, writable } from 'svelte/store';
+
+
const STEAM_ID = '76561198106829949';
+
const GET_PLAYER_SUMMARY_ENDPOINT = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${env.STEAM_API_KEY}&steamids=${STEAM_ID}&format=json`;
+
const LAST_GAME_FILE = `${env.WEBSITE_DATA_DIR}/last_game.json`;
+
+
type LastGame = {
+
name: string;
+
link: string;
+
icon: string;
+
pfp: string;
+
when: number;
+
playing: boolean;
+
};
+
+
const steamgriddbClient = writable<SGDB | null>(null);
+
const lastGame = writable<LastGame | null>(null);
+
+
export const steamReadLastGame = async () => {
+
try {
+
const data = await Deno.readTextFile(LAST_GAME_FILE);
+
lastGame.set(JSON.parse(data));
+
} catch (why) {
+
console.log('could not read last game: ', why);
+
lastGame.set(null);
+
}
+
};
+
+
export const steamUpdateNowPlaying = async () => {
+
let griddbClient = get(steamgriddbClient);
+
if (griddbClient === null) {
+
griddbClient = new SGDB(env.STEAMGRIDDB_API_KEY);
+
steamgriddbClient.set(griddbClient);
+
}
+
try {
+
const profile = (await (await fetch(GET_PLAYER_SUMMARY_ENDPOINT)).json()).response.players[0];
+
if (!profile.gameid) {
+
lastGame.update((t) => {
+
if (t !== null) {
+
t.playing = false;
+
}
+
return t;
+
});
+
return;
+
}
+
const icons = await griddbClient.getIconsBySteamAppId(profile.gameid, ['official', 'custom']);
+
//console.log(icons)
+
const game: LastGame = {
+
name: profile.gameextrainfo,
+
link: `https://store.steampowered.com/app/${profile.gameid}`,
+
icon: icons[0].thumb.toString(),
+
pfp: profile.avatarmedium,
+
when: Date.now(),
+
playing: true
+
};
+
lastGame.set(game);
+
await Deno.writeTextFile(LAST_GAME_FILE, JSON.stringify(game));
+
} catch (why) {
+
console.log('could not fetch steam: ', why);
+
lastGame.update((t) => {
+
if (t !== null) {
+
t.playing = false;
+
}
+
return t;
+
});
+
}
+
};
+
+
export const getLastGame = () => {
+
return get(lastGame);
+
};
+140
eunomia/src/lib/visits.ts
···
+
import { env } from '$env/dynamic/private';
+
import { scopeCookies } from '$lib';
+
import type { Cookies } from '@sveltejs/kit';
+
import { nanoid } from 'nanoid';
+
import { get, writable } from 'svelte/store';
+
+
const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount`;
+
const readVisitCount = async () => {
+
try {
+
return parseInt(await Deno.readTextFile(visitCountFile));
+
} catch {
+
return 0;
+
}
+
};
+
export const visitCount = writable(await readVisitCount());
+
+
export type Visitor = { visits: number[] };
+
export const lastVisitors = writable<Map<string, Visitor>>(new Map());
+
const VISITOR_EXPIRY_SECONDS = 60 * 60; // an hour seems reasonable
+
+
export const decrementVisitCount = () => {
+
visitCount.set(get(visitCount) - 1);
+
};
+
+
export const incrementVisitCount = async (request: Request, cookies: Cookies) => {
+
let currentVisitCount = get(visitCount);
+
// check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots)
+
if (isBot(request)) return false;
+
const scopedCookies = scopeCookies(cookies, '/');
+
// parse the last visit timestamp from cookies if it exists
+
const visitedTimestamp = parseInt(scopedCookies.get('visitedTimestamp') || '0');
+
// get unix timestamp
+
const currentTime = Date.now();
+
const timeSinceVisit = currentTime - visitedTimestamp;
+
// check if this is the first time a client is visiting or if an hour has passed since they last visited
+
if (visitedTimestamp === 0 || timeSinceVisit > 1000 * 60 * 60 * 24) {
+
// increment current and write to the store
+
currentVisitCount += 1;
+
visitCount.set(currentVisitCount);
+
// update the cookie with the current timestamp
+
scopedCookies.set('visitedTimestamp', currentTime.toString());
+
// write the visit count to a file so we can load it later again
+
await Deno.writeTextFile(visitCountFile, currentVisitCount.toString());
+
}
+
return true;
+
};
+
+
export const removeLastVisitor = (id: string) => {
+
const visitors = get(lastVisitors);
+
if (visitors.has(id)) {
+
const visitor = visitors.get(id) ?? { visits: [] };
+
visitor?.visits.shift();
+
// if not enough visits remove
+
if (visitor?.visits.length === 0) {
+
visitors.delete(id);
+
} else {
+
visitors.set(id, visitor);
+
}
+
}
+
lastVisitors.set(visitors);
+
};
+
+
export const addLastVisitor = (request: Request, cookies: Cookies) => {
+
const { visitors, visitorId } = _addLastVisitor(get(lastVisitors), request, cookies);
+
lastVisitors.set(visitors);
+
return visitorId;
+
};
+
+
export const getVisitorId = (cookies: Cookies) => {
+
const scopedCookies = scopeCookies(cookies, '/');
+
// parse the last visit timestamp from cookies if it exists
+
return scopedCookies.get('visitorId');
+
};
+
+
// why not use this for incrementVisitCount? cuz i wanna have separate visit counts (one per hour and one per day, per hour being recent visitors)
+
const _addLastVisitor = (visitors: Map<string, Visitor>, request: Request, cookies: Cookies) => {
+
const currentTime = Date.now();
+
// filter out old entries
+
visitors.forEach((visitor, id, map) => {
+
if (currentTime - visitor.visits[0] > 1000 * VISITOR_EXPIRY_SECONDS) map.delete(id);
+
else {
+
visitor.visits = visitor.visits.filter((since) => {
+
return currentTime - since < 1000 * VISITOR_EXPIRY_SECONDS;
+
});
+
map.set(id, visitor);
+
}
+
});
+
// check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots)
+
if (isBot(request)) return { visitors, visitorId: null };
+
const scopedCookies = scopeCookies(cookies, '/');
+
// parse the last visit timestamp from cookies if it exists
+
let visitorId = scopedCookies.get('visitorId') || '';
+
// if no such id exists, create one and assign it to the client
+
if (!visitors.has(visitorId)) {
+
visitorId = nanoid();
+
scopedCookies.set('visitorId', visitorId);
+
console.log(`new client visitor id ${visitorId}`);
+
}
+
// update the entry
+
const visitorEntry = visitors.get(visitorId) || { visits: [] };
+
// put new visit in the front
+
visitorEntry.visits = [currentTime].concat(visitorEntry.visits);
+
visitors.set(visitorId, visitorEntry);
+
return {
+
visitors,
+
visitorId
+
};
+
};
+
+
export const isBot = (request: Request) => {
+
const ua = request.headers.get('user-agent');
+
return ua
+
? ua.toLowerCase().match(/(bot|crawl|spider|walk|fetch|scrap|proxy|image)/) !== null
+
: true;
+
};
+
+
export const notifyDarkVisitors = (url: URL, request: Request) => {
+
fetch('https://api.darkvisitors.com/visits', {
+
method: 'POST',
+
headers: {
+
authorization: `Bearer ${env.DARK_VISITORS_TOKEN}`,
+
'content-type': 'application/json'
+
},
+
body: JSON.stringify({
+
request_path: url.pathname,
+
request_method: request.method,
+
request_headers: request.headers
+
})
+
})
+
.catch((why) => {
+
console.log('failed sending dark visitors analytics:', why);
+
return null;
+
})
+
.then((resp) => {
+
if (resp !== null) {
+
const host = `(${request.headers.get('host')}|${request.headers.get('x-real-ip')}|${request.headers.get('user-agent')})`;
+
console.log(`sent visitor analytic to dark visitors: ${resp.statusText}; ${host}`);
+
}
+
});
+
};
+20
eunomia/src/lib/window.ts
···
+
/* eslint-disable no-useless-escape */
+
import { writable } from 'svelte/store';
+
+
export const highestZIndex = writable(0);
+
+
export const isMobile = () => {
+
let check = false;
+
(function (a) {
+
if (
+
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
+
a
+
) ||
+
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
+
a.slice(0, 4)
+
)
+
)
+
check = true;
+
})(navigator.userAgent || navigator.vendor);
+
return check;
+
};
+67
eunomia/src/routes/(site)/+layout.server.ts
···
+
import { newToken as getApiToken } from '$lib/apiToken.js';
+
import { bounceCount, distanceTravelled } from '$lib/metrics.js';
+
import { lastVisitors, visitCount } from '$lib/visits.js';
+
import { get } from 'svelte/store';
+
+
export const csr = true;
+
export const ssr = true;
+
export const prerender = false;
+
export const trailingSlash = 'always';
+
+
export async function load({ url }) {
+
const visitors = get(lastVisitors);
+
let recentVisitCount = 0;
+
for (const [, visitor] of visitors) {
+
recentVisitCount += visitor.visits.length;
+
}
+
+
const eyePositions = [];
+
const usedPositions = [];
+
for (let i = 0; i < Math.min(visitors.size, 10); i++) {
+
let maxMinDistance = 0;
+
let bestPosition = null;
+
+
// Try multiple positions and keep the one with largest minimum distance to existing points
+
for (let attempt = 0; attempt < 50; attempt++) {
+
const sidePreference = Math.random() < 0.5;
+
const testLeft = sidePreference
+
? Math.random() * 30 // Left side
+
: 60 + Math.random() * 30; // Right side
+
const testTop = Math.random() * 80;
+
+
let currentMinDistance = Infinity;
+
+
// Calculate minimum distance to all existing points
+
for (const pos of usedPositions) {
+
const distance = Math.sqrt(
+
Math.pow(testLeft - pos.left, 2) + Math.pow(testTop - pos.top, 2)
+
);
+
currentMinDistance = Math.min(currentMinDistance, distance);
+
}
+
+
// If this position has a larger minimum distance, keep it
+
if (currentMinDistance > maxMinDistance) {
+
maxMinDistance = currentMinDistance;
+
bestPosition = { left: testLeft, top: testTop };
+
}
+
}
+
+
// Use the best position found
+
const left = bestPosition ? bestPosition.left : Math.random() * 90;
+
const top = bestPosition ? bestPosition.top : Math.random() * 80;
+
+
usedPositions.push({ left, top });
+
eyePositions.push([top, left]);
+
}
+
+
return {
+
route: url.pathname,
+
petTotalBounce: bounceCount.get(),
+
petTotalDistance: distanceTravelled.get(),
+
visitCount: get(visitCount),
+
lastVisitors: visitors,
+
recentVisitCount,
+
eyePositions,
+
apiToken: getApiToken()
+
};
+
}
+284
eunomia/src/routes/(site)/+layout.svelte
···
+
<script lang="ts">
+
import { browser } from '$app/environment';
+
import getTitle from '$lib/getTitle';
+
import Eye from '$components/eye.svelte';
+
import NavButton from '$components/navButton.svelte';
+
import Pet, { localBounces, localDistanceTravelled } from '$components/pet.svelte';
+
import Tooltip from '$components/tooltip.svelte';
+
import '$styles/app.css';
+
+
interface Props {
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
data: any;
+
children?: import('svelte').Snippet;
+
}
+
+
let { data, children }: Props = $props();
+
+
interface MenuItem {
+
href: string;
+
name: string;
+
iconUri: string;
+
}
+
+
const menuItems: MenuItem[] = [
+
{ href: '', name: 'home', iconUri: '/icons/home.webp' },
+
{ href: 'entries', name: 'entries', iconUri: '/icons/entries.webp' },
+
{ href: 'guestbook', name: 'guestbook', iconUri: '/icons/guestbook.webp' },
+
{ href: 'about', name: 'about', iconUri: '/icons/about.webp' }
+
];
+
+
let routeComponents = $derived(data.route.split('/'));
+
let isEntryPage = $derived(routeComponents.length > 3 && routeComponents[1] === 'entries');
+
let isResumePage = $derived(routeComponents[1] === 'resume');
+
let isRoute = $derived((_route: string) => {
+
if (isEntryPage) {
+
if (_route === 'entries') {
+
return false;
+
} else if (_route.startsWith('entries/')) {
+
return true;
+
}
+
}
+
return _route === routeComponents[1];
+
});
+
+
let title = $derived(getTitle(data.route));
+
+
const svgSquiggles = [[2], [3], [2], [3], [1]];
+
+
// svelte-ignore non_reactive_update
+
let eyePositions = null;
+
if (eyePositions === null) {
+
eyePositions = data.eyePositions;
+
}
+
</script>
+
+
<svelte:head>
+
<title>{title}</title>
+
<meta property="og:site_name" content="gaze.systems" />
+
<meta property="og:url" content="https://gaze.systems/" />
+
<meta property="og:image" content="https://gaze.systems/icons/gaze_website.webp" />
+
</svelte:head>
+
+
<div
+
class="
+
app-grid-background motion-safe:app-grid-background-anim
+
fixed -z-10 w-full [height:100%] top-0 left-0
+
"
+
></div>
+
<div
+
class="
+
app-grid-background-second-layer motion-safe:app-grid-background-second-layer-anim
+
fixed -z-20 w-full [height:100%] top-0 left-0
+
"
+
></div>
+
+
<svg
+
xmlns="http://www.w3.org/2000/svg"
+
version="1.1"
+
class="absolute -z-50"
+
image-rendering="optimizeSpeed"
+
>
+
<defs>
+
{#each svgSquiggles as [scale], index (index)}
+
<filter id="squiggly-{index}">
+
<feTurbulence
+
id="turbulence"
+
baseFrequency="0.03"
+
numOctaves="3"
+
result="noise"
+
seed={index}
+
/>
+
<feDisplacementMap in="SourceGraphic" in2="noise" {scale} />
+
</filter>
+
{/each}
+
<filter id="pixelate" color-interpolation-filters="linearRGB" x="0" y="0">
+
<feFlood x="4" y="4" height="2" width="2" />
+
<feComposite width="10" height="10" />
+
<feTile result="a" />
+
<feComposite in="SourceGraphic" in2="a" operator="in" />
+
<feMorphology operator="dilate" radius="5" />
+
</filter>
+
<filter id="dither" color-interpolation-filters="sRGB" x="0" y="0" width="100%" height="100%">
+
<feImage
+
width="4"
+
height="4"
+
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAASElEQVR42gXBgQAAIAxFwW8QwhBCCCGEIYQQQgghhBBCCEMYwutOkphzYmbsvdG9l9YaEYG7o1or5xxKKay1UGYyxuC9R++dD7yGJkTj6F0HAAAAAElFTkSuQmCC"
+
/>
+
<feTile />
+
<feComposite operator="arithmetic" k1="0" k2="1" k3="1" k4="-0.5" in="SourceGraphic" />
+
<feComponentTransfer>
+
<feFuncR type="discrete" tableValues="0 1" />
+
<feFuncG type="discrete" tableValues="0 1" />
+
<feFuncB type="discrete" tableValues="0 1" />
+
</feComponentTransfer>
+
</filter>
+
<filter
+
id="dither-red"
+
color-interpolation-filters="sRGB"
+
x="0"
+
y="0"
+
width="100%"
+
height="100%"
+
>
+
<feFlood flood-color="#000000" flood-opacity="0.50" x="0%" y="0%" result="flood" />
+
<feBlend mode="normal" x="0%" y="0%" in="SourceGraphic" in2="flood" result="blend1" />
+
<feImage
+
class="ditherImage"
+
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVQYlQXBgQbCUABA0fdrk0ySSZJJkiRJMjOTTGZmkiRJZiYzyczMzGQmfdrtHPH7/TgcDuR5zna7pWka9vs9aZqyXq8R0+mU5/OJoihcLhfG4zFBENDtdjmdToj3+81yueTz+WCaJnEcM5/PKcsSXdcRsizjeR6j0YjH40Gr1cJxHAaDAbfbDVHXNbvdjiRJWK1WfL9fLMsiyzI2mw1CVVV836fT6XA8HplMJoRhSK/X43w+I6IoYjabURQFmqbxer1YLBZUVYVhGAhJkrBtm36/z/V6pd1u47ouw+GQ+/3OH4/Fn8FvF/NxAAAAAElFTkSuQmCC"
+
x="0"
+
y="0"
+
width="4"
+
height="4"
+
crossOrigin="anonymous"
+
result="image1"
+
/>
+
<feTile x="0" y="0" in="image1" result="tile" />
+
<feBlend mode="overlay" x="0%" y="0%" in="blend1" in2="tile" result="blend2" />
+
<feColorMatrix type="saturate" values="0" />
+
<feComponentTransfer>
+
<feFuncR type="discrete" tableValues="0 0" />
+
<feFuncG type="discrete" tableValues="0 1" />
+
<feFuncB type="discrete" tableValues="0 1" />
+
</feComponentTransfer>
+
</filter>
+
</defs>
+
</svg>
+
+
{#if !isResumePage}
+
{#each data.lastVisitors as [id, visitor], index (id)}
+
{@const pos = eyePositions.at(index)}
+
{#if pos !== undefined}
+
<Eye visits={visitor.visits} {id} top={pos[0]} left={pos[1]} />
+
{/if}
+
{/each}
+
{/if}
+
+
<div
+
class="md:h-[96vh] pb-[8vh] lg:px-[1vw] 2xl:px-[2vw] lg:pb-[3vh] lg:pt-[1vh] overflow-x-hidden [scrollbar-gutter:stable]"
+
>
+
{@render children?.()}
+
</div>
+
+
{#if !isResumePage}
+
<Pet apiToken={data.apiToken} />
+
{/if}
+
+
<nav class="w-full min-h-[5vh] max-h-[5vh] fixed bottom-0 z-[999] bg-ralsei-black overflow-visible">
+
<div
+
class="
+
max-w-full max-h-fit p-1 z-[999]
+
border-ralsei-white border-8
+
bg-gradient-to-r to-ralsei-pink-neon/30 from-ralsei-pink-regular/20 from-30%
+
"
+
style="border-style: ridge hidden hidden hidden;"
+
>
+
<div class="flex flex-row flex-nowrap gap-2 justify-start overflow-x-auto">
+
{#each menuItems as item, menuIdx (item.href)}
+
{@const highlight = isRoute(item.href)}
+
<NavButton {highlight} {...item} />
+
{#if isEntryPage && menuIdx === 1}
+
<NavButton
+
highlight
+
name={routeComponents[2]}
+
href={data.route.slice(1)}
+
iconUri="/icons/entry.webp"
+
/>
+
{/if}
+
{#if isResumePage && menuIdx === 2}
+
<NavButton highlight name="resume" href="/resume.pdf" iconUri="/icons/about.webp" />
+
{/if}
+
{/each}
+
<div class="hidden md:block grow"></div>
+
<div class="navbox">
+
<a
+
title="previous site"
+
class="hover:underline"
+
href="https://stellophiliac.github.io/roboring/gazesys/previous">โฎœ</a
+
>
+
<a class="hover:underline" href="https://stellophiliac.github.io/roboring">roboring</a>
+
<a
+
title="next site"
+
class="hover:underline"
+
href="https://stellophiliac.github.io/roboring/gazesys/next">โฎž</a
+
>
+
</div>
+
<div class="navbox">
+
<a title="previous site" class="hover:underline" href="https://xn--sr8hvo.ws/previous">โฎœ</a>
+
<a class="hover:underline" href="https://xn--sr8hvo.ws">indieweb</a>
+
<a title="next site" class="hover:underline" href="https://xn--sr8hvo.ws/next">โฎž</a>
+
</div>
+
{#if isRoute('entries') || isRoute('log')}
+
<div class="navbox !gap-1">
+
rss:
+
<a class="align-middle hover:underline" href="/entries/_rss">posts</a>
+
/
+
<a class="align-middle hover:underline" href="/log/_rss">log</a>
+
</div>
+
{/if}
+
<Tooltip>
+
{#snippet tooltipContent()}
+
<p class="font-monospace">
+
<nobr>
+
pet global bounce = <span class="text-ralsei-green-light text-shadow-green"
+
>{data.petTotalBounce.toString().padStart(12, '.')}</span
+
>
+
</nobr>
+
<nobr>
+
pet global travel = <span class="text-ralsei-green-light text-shadow-green"
+
>{data.petTotalDistance.toFixed(0).toString().padStart(12, '.')}</span
+
>
+
</nobr>
+
{#if browser}
+
<nobr>
+
pet local bounce &nbsp;= <span class="text-ralsei-green-light text-shadow-green"
+
>{$localBounces.toFixed(0).toString().padStart(12, '.')}</span
+
>
+
</nobr>
+
<nobr>
+
pet local travel &nbsp;= <span class="text-ralsei-green-light text-shadow-green"
+
>{$localDistanceTravelled.toFixed(0).toString().padStart(12, '.')}</span
+
>
+
</nobr>
+
{/if}
+
</p>
+
{/snippet}
+
<div class="navbox">
+
<p>
+
<span class="text-ralsei-green-light text-shadow-green">*</span>
+
pet stats
+
</p>
+
</div>
+
</Tooltip>
+
<Tooltip>
+
{#snippet tooltipContent()}
+
<p class="font-monospace">
+
<nobr
+
>total visits = <span class="text-ralsei-green-light text-shadow-green"
+
>{data.visitCount.toString().padStart(9, '.')}</span
+
></nobr
+
>
+
<nobr
+
>uniq recent visits = <span class="text-ralsei-green-light text-shadow-green"
+
>{data.lastVisitors.size.toString().padStart(3, '.')}</span
+
></nobr
+
>
+
</p>
+
{/snippet}
+
<div class="navbox">
+
<p>
+
<span class="text-ralsei-green-light text-shadow-green">{data.recentVisitCount}</span> recent
+
clicks
+
</p>
+
</div>
+
</Tooltip>
+
</div>
+
</div>
+
</nav>
+
+
<style lang="postcss">
+
.navbox {
+
@apply flex gap-3 px-1.5 text-nowrap align-middle items-center text-center place-content-center border-ralsei-white border-4;
+
border-style: groove;
+
}
+
</style>
+41
eunomia/src/routes/(site)/+page.server.ts
···
+
import { getLastPosts } from '$lib/bluesky.js';
+
import { getNowPlayingTrack } from '$lib/lastfm';
+
import { getLastGame } from '$lib/steam';
+
import { noteFromBskyPost } from '$components/note.svelte';
+
import { pushNotification } from '$lib/pushnotif';
+
import { getLastActivity } from '$lib/activity.js';
+
import type { RequestEvent } from '@sveltejs/kit';
+
import { useToken as checkApiToken } from '$lib/apiToken.js';
+
+
export const load = async () => {
+
const lastTrack = getNowPlayingTrack();
+
const lastGame = getLastGame();
+
const lastPosts = getLastPosts();
+
const lastNote = lastPosts.length > 0 ? noteFromBskyPost(lastPosts[0]) : null;
+
const lastActivity = getLastActivity();
+
const banners: number[] = [];
+
while (banners.length < 3) {
+
const no = getBannerNo(banners);
+
banners.push(no);
+
}
+
return { banners, lastTrack, lastGame, lastNote, lastActivity };
+
};
+
+
export const actions = {
+
default: async ({ request }: RequestEvent) => {
+
const form = await request.formData();
+
const token = form.get('_token')?.toString() ?? '';
+
if (!checkApiToken(token)) return;
+
const content = form.get('content')?.toString().substring(0, 100);
+
if (content === undefined) return;
+
pushNotification(content);
+
}
+
};
+
+
const getBannerNo = (others: number[]) => {
+
const no = Math.floor(Math.random() * 20) + 1;
+
if (others.includes(no)) {
+
return ((no + Math.floor(Math.random() * 20)) % 20) + 1;
+
}
+
return no;
+
};
+471
eunomia/src/routes/(site)/+page.svelte
···
+
<script lang="ts">
+
import { PUBLIC_BASE_URL } from '$env/static/public';
+
import Note from '$components/note.svelte';
+
import Window from '$components/window.svelte';
+
import { renderDate, renderRelativeDate } from '$lib/dateFmt';
+
import Tooltip from '$components/tooltip.svelte';
+
import '$styles/main.css';
+
+
interface Props {
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
data: any;
+
}
+
+
const trimStr = (str: string, maxLength: number = 32): string => {
+
if (str.length <= maxLength) return str;
+
return str.slice(0, maxLength - 3) + 'โ€ฆ';
+
};
+
+
const wallets: Record<string, string> = {
+
btc: 'bc1q7dgsgxj8jua50d3xjgg28v2c6uhpgpe79vr4ra',
+
eth: '0xF5dC63d340556925Ae2a64e5F0c19e3c2471139F',
+
xmr: '45TJMbHrdyTSPywExKbzL51uuJZGTrDzrLidFufeGU4LA13Un92LTZeWhy2ePCcVaZ64KJdUjSZgMPM9jXfjJcxEQJ8szvw'
+
};
+
+
const buttons = [
+
{
+
name: '250kb club',
+
url: 'https://250kb.club/gaze-systems/',
+
image: '/others/250kb.webp'
+
},
+
{
+
name: 'june',
+
url: 'https://girlboss.ceo',
+
image: 'https://x86.pet/~strawberry/june_88x31.png'
+
},
+
{ name: 'dd', url: 'https://dd86k.space/about/', image: '/others/dd86k.gif' },
+
{ name: 'drew', url: 'https://drewsh.com/', image: '/others/drewsh.gif' },
+
{ name: 'deniz', url: 'https://deniz.blue', image: 'https://deniz.blue/assets/88x31v0.png' },
+
{ name: 'rain', url: 'https://slonk.ing/', image: '/others/slonk.gif' },
+
{
+
name: 'blooym',
+
url: 'https://blooym.dev/',
+
image: 'https://blooym.dev/files/88x31/blooym_mori.webp'
+
},
+
{
+
name: 'elysia',
+
url: 'https://ely.pub.moe/',
+
image: 'https://ely.pub.moe/storage/icons/buttons/elysia.png'
+
},
+
{
+
name: 'vern',
+
url: 'https://vern.cc/',
+
image: 'https://cobra.vern.cc/media/buttons/vern.webp'
+
},
+
{
+
name: "31A05B9C's random site",
+
url: 'https://www.31a05b.net/',
+
image: 'https://www.31a05b.net/a/8831/31a05b.png'
+
},
+
{
+
name: 'candlelitsmiles',
+
url: 'https://candlelitsmiles.neocities.org',
+
image: 'https://candlelitsmiles.neocities.org/candlebuttonone.png'
+
},
+
{
+
name: 'indieweb',
+
url: 'https://indieweb.org/',
+
image: 'https://indieweb.org/images/9/91/indieweb88x31-retro-gif.gif'
+
},
+
{
+
name: 'nixos',
+
url: 'https://nixos.org/',
+
image: '/others/poweredbynixos.webp'
+
},
+
{
+
name: 'godot',
+
url: 'https://godotengine.org/',
+
image: '/others/godot.gif'
+
},
+
{
+
name: 'moonlight',
+
url: 'https://moonlight-mod.github.io/',
+
image: '/others/moonlightnow.gif'
+
},
+
{
+
name: 'desktop!!',
+
url: '/',
+
image: '/others/desktopwebp.webp'
+
},
+
{
+
name: 'defective by design',
+
url: 'https://www.defectivebydesign.org/',
+
image: '/others/dbd.gif'
+
},
+
{
+
name: 'kill fascists',
+
url: '/',
+
image: '/others/killfascists.webp'
+
},
+
{
+
name: 'it/its',
+
url: '/',
+
image: '/others/it.webp'
+
},
+
{
+
name: 'not a person',
+
url: '/',
+
image: '/others/notaperson.webp'
+
}
+
];
+
+
let { data }: Props = $props();
+
</script>
+
+
<div class="flex flex-col-reverse md:flex-row gap-2 md:gap-4 md:h-full h-card">
+
<div class="flex flex-col gap-2 md:gap-6 md:ml-auto place-items-end">
+
<Window title="status" iconUri="/icons/msn.webp" removePadding>
+
{#if data.lastNote}
+
<div class="m-1.5 flex flex-col font-monospace text-sm">
+
<p
+
class="prose prose-ralsei p-1 border-4 text-sm bg-ralsei-black"
+
style="border-style: double double none double;"
+
title={renderDate(data.lastNote.published)}
+
>
+
<a href="/entries">last log wasโ€ฆ</a>
+
published {renderRelativeDate(data.lastNote.published)}!
+
</p>
+
<div class="mt-0 p-1.5 border-4 border-double bg-ralsei-black min-w-full max-w-[60ch]">
+
<Note rootNote={data.lastNote} onlyContent />
+
</div>
+
</div>
+
{/if}
+
{#if data.lastActivity.length > 0}
+
<div class="m-1.5 flex flex-col font-monospace text-sm">
+
<p
+
class="prose prose-ralsei p-1 border-4 text-sm bg-ralsei-black"
+
style="border-style: double double none double;"
+
title={renderDate(data.lastActivity[0].date)}
+
>
+
<a href="/">last git activityโ€ฆ</a>
+
was {renderRelativeDate(data.lastActivity[0].date)}..
+
</p>
+
<div
+
class="prose prose-ralsei mt-0 p-1.5 border-4 border-double bg-ralsei-black min-w-full max-w-[60ch]"
+
>
+
{#each data.lastActivity as activity, index (index)}
+
<div
+
class="text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[60ch]"
+
style="opacity: {1.0 - (index * 1.0) / data.lastActivity.length + index * 0.03};"
+
>
+
<span title={renderDate(activity.date)} class="text-[#f87c32]"
+
>[{activity.source}]</span
+
>
+
<a href={activity.link} title={activity.description}>{activity.description}</a>
+
</div>
+
{/each}
+
</div>
+
</div>
+
{/if}
+
{#if data.lastTrack}
+
{@const images = data.lastTrack.images}
+
{@const initialUrl = images.mb ?? images.yt}
+
<div class="flex flex-row gap-0.5 m-1.5 border-4 border-double bg-ralsei-black">
+
<!-- svelte-ignore a11y_missing_attribute -->
+
<img
+
class="border-4 w-[4.5rem] h-[4.5rem] {initialUrl ? 'object-cover' : 'p-2'}"
+
style="border-style: none double none none; {initialUrl ? '' : 'image-rendering: pixelated;'}"
+
src={initialUrl ?? '/icons/cd_audio.webp'}
+
title={data.lastTrack.album}
+
onerror={(e) => {
+
const img = e.currentTarget as HTMLImageElement;
+
if (images.mb && img.src === images.mb && images.yt)
+
img.src = images.yt;
+
else {
+
img.src = '/icons/cd_audio.webp';
+
img.classList.remove('object-cover');
+
img.classList.add('p-2');
+
img.style.imageRendering = 'pixelated';
+
}
+
}}
+
/>
+
<div class="flex flex-col max-w-[60ch] p-2">
+
<p
+
class="text-shadow-green text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
+
>
+
<span class="text-sm text-shadow-white text-ralsei-white">{data.lastTrack.status === 'playing' ? 'listening to' : 'listened to'}</span>
+
<a
+
title={data.lastTrack.name}
+
href={data.lastTrack.link ?? 'https://tealfm-slice.wisp.place/profile/ptr.pet/scrobbles'}
+
class="hover:underline motion-safe:hover:animate-squiggle">{data.lastTrack.name}</a
+
>
+
</p>
+
<p
+
class="text-shadow-pink text-ralsei-pink-regular text-sm text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
+
>
+
<span class="text-shadow-white text-ralsei-white">by</span>
+
<span title={data.lastTrack.artist}>{data.lastTrack.artist}</span>
+
</p>
+
<p
+
class="text-shadow-white text-ralsei-white text-xs text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
+
>
+
โ€ฆ{renderRelativeDate(data.lastTrack.when)}
+
</p>
+
</div>
+
</div>
+
{/if}
+
{#if data.lastGame}
+
<div class="flex flex-row m-1.5 border-4 border-double bg-ralsei-black">
+
<!-- svelte-ignore a11y_missing_attribute -->
+
<img
+
class="border-4 w-[4.5rem] h-[4.5rem]"
+
style="border-style: none double none none;"
+
width="64"
+
height="64"
+
src={data.lastGame.icon}
+
/>
+
<div class="flex flex-col max-w-[60ch] p-2 gap-0.5 overflow-hidden">
+
<p
+
class="text-shadow-green text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
+
>
+
<span class="text-sm text-shadow-white text-ralsei-white"
+
>{data.lastGame.playing ? 'playing' : 'played'}</span
+
>
+
<a title={data.lastGame.name} class="hover:underline" href={data.lastGame.link}
+
>{data.lastGame.name}</a
+
>
+
</p>
+
<p
+
class="text-shadow-white text-ralsei-white text-xs text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
+
>
+
โ€ฆ{renderRelativeDate(data.lastGame.when)}
+
</p>
+
<!-- svelte-ignore a11y_missing_attribute -->
+
<a
+
href="https://steamcommunity.com/id/090008"
+
class="text-xs hover:underline text-shadow-green text-ralsei-green-light"
+
><img class="inline w-4" src={data.lastGame.pfp} />
+
<span class="align-middle">steam profile</span></a
+
>
+
</div>
+
</div>
+
{/if}
+
</Window>
+
<Window style="md:mr-2" title="cool buttons :>">
+
<a class="fixed" title="skyrina" href="https://skyrina.dev/"
+
><img
+
class="-translate-y-[8.85rem] z-20"
+
style="image-rendering: pixelated !important;"
+
src="/others/skylar.gif"
+
alt="skyrina"
+
/></a
+
>
+
<div class="max-w-[64ch] prose prose-ralsei prose-a:!animate-none prose-img:m-0 leading-snug">
+
<div class="flex flex-row flex-wrap gap-3 place-items-start group">
+
{#each buttons as { name, url, image } (image)}
+
<a title={name} href={url}
+
><img
+
class="relative transition-all group-hover:opacity-50 hover:!opacity-100 hover:!scale-[1.6] hover:z-10"
+
style="image-rendering: pixelated !important;"
+
src={image}
+
alt={name}
+
/></a
+
>
+
{/each}
+
</div>
+
+
<span class="text-sm">feel free to send this one stuff to add here ;3</span>
+
</div>
+
</Window>
+
</div>
+
<div class="flex flex-col gap-2 md:gap-3 md:mr-auto w-full md:w-fit place-items-start">
+
<Window style="md:ml-2" title="readme?" iconUri="/icons/question.webp" removePadding>
+
<div class="flex flex-col p-1.5 gap-1.5 prose prose-ralsei prose-img:m-0 leading-none">
+
<div class="flex flex-row gap-3 mx-auto bg-ralsei-black/20 overflow-hidden">
+
{#each data.banners as bannerNo, index (bannerNo)}
+
{@const hideIfMobile = index === data.banners.length - 1}
+
<img
+
width="150"
+
height="20"
+
title="banners from https://blinkies.cafe/ (refresh to get different ones! :3)"
+
alt="banner"
+
class="
+
{hideIfMobile ? 'hidden' : ''} sm:inline w-[150px] [height:20px]
+
[image-rendering:pixelated_!important] shadow-ralsei-black shadow-[0px_4px_2px_0_rgb(0_0_0_/_0.05)]
+
"
+
src="/banners/{bannerNo}.gif"
+
/>
+
{/each}
+
</div>
+
<div class="flex flex-grow">
+
<Tooltip>
+
{#snippet tooltipContent()}
+
that's its angelsona ^^
+
{/snippet}
+
<div
+
class="w-36 [padding:8px] place-content-center place-self-center bg-ralsei-black/20"
+
>
+
<img
+
class="w-36 u-photo hover:invert transition-all [transition-duration:300ms]"
+
src="/pfp-iojkqpwerojnasduijf.webp"
+
alt="my angelsona"
+
/>
+
</div>
+
</Tooltip>
+
<div
+
class="flex flex-row flex-grow place-content-center ml-1.5 [padding:8px] bg-ralsei-black/20"
+
>
+
<ul
+
class="place-self-center m-0 mr-4 [padding-left:1em] sm:[padding-left:0.5em] leading-none marker:[content:'->'] [list-style-type:'->']"
+
>
+
<li class="[list-style-type:'->'] p-note">trying to do stuff</li>
+
<li class="[list-style-type:'->'] p-note">
+
<Tooltip
+
x="translate-x-none"
+
y="-translate-y-[40%]"
+
targetX="group-hover:translate-x-[40%]"
+
targetY="group-hover:-translate-y-[88%]"
+
>
+
{#snippet tooltipContent()}
+
angelrobotpuppydollthing<br /><br />
+
it/its, 3pp preferred
+
{/snippet}
+
is a <i class="motion-safe:hover:animate-squiggle">thing</i> (it/they)
+
</Tooltip>
+
</li>
+
<li class="[list-style-type:'->']">
+
<span class="p-category">software engineer</span>,
+
<span class="p-category">indie game dev</span>
+
</li>
+
<li class="[list-style-type:'->']">
+
for resume, click <a href="/resume.pdf">here</a>
+
</li>
+
<li class="[list-style-type:'->']">
+
in <span class="p-country-name">turkey</span>
+
<i class="text-[0.5rem]">(get it out)</i>
+
</li>
+
</ul>
+
</div>
+
</div>
+
<div class="flex flex-row [padding:8px] bg-ralsei-black/20">
+
<p class="leading-none m-0 text-sm">
+
hi
+
<img
+
class="relative inline h-5 animate-squiggle pb-1"
+
src="/wavey.gif"
+
alt="wavey"
+
title="says hi :33"
+
/>
+
<i
+
>this is <a class="m-0 [padding:0px] p-name u-url u-uid" href={PUBLIC_BASE_URL}
+
><span>{Math.random() > 0.8 ? 'dusk' : 'dawn'}</span></a
+
></i
+
>
+
</p>
+
<div class="grow"></div>
+
<a
+
class="
+
place-self-end [font-family:'Doll_Mono'] text-ralsei-pink-neon text-shadow-none hover:text-shadow-pink
+
hover:!animate-none hover:!no-underline opacity-20 hover:opacity-100 transition-opacity [transition-duration:300ms]
+
"
+
title="dollcode? sure hope they do"
+
href="https://dollcode.v01dlabs.sh/">โ––โ––โ––โ––โ–˜โ–Œโ–Œโ–Œโ––โ–˜โ–˜</a
+
>
+
</div>
+
</div>
+
</Window>
+
<Window title="notify this one">
+
<form
+
class="flex flex-row gap-1 place-self-center"
+
method="post"
+
onsubmit={(event) => {
+
event.preventDefault();
+
const formData = new FormData(event.currentTarget);
+
try {
+
fetch(
+
`${PUBLIC_BASE_URL}/_api/pushnotif?content=${formData.get('content')}&_token=${data.apiToken}`
+
);
+
} catch (err) {
+
console.log(`failed to send notif: ${err}`);
+
}
+
event.currentTarget.reset();
+
}}
+
>
+
<input
+
type="text"
+
class="entry text-lg p-1 m-0 bg-transparent resize-none text-shadow-white placeholder-shown:[text-shadow:none] border-none"
+
name="content"
+
placeholder="bother it now!!"
+
maxlength="100"
+
required
+
/>
+
<input type="hidden" name="_token" value={data.apiToken} />
+
<input
+
type="submit"
+
value="send!!"
+
class="entry text-ralsei-green-light leading-none hover:underline motion-safe:hover:animate-squiggle p-1 z-50"
+
/>
+
</form>
+
</Window>
+
<Window title="links!" iconUri="/icons/contact.webp">
+
<div
+
class="[width:40ch] prose prose-ralsei prose-ul:px-[0.9rem] prose-ul:mt-2 prose-ul:leading-none prose-headings:leading-none"
+
>
+
<ul>
+
<li>discord: 90.008</li>
+
<li>
+
e-mail:
+
<a class="u-email" href="mailto:90008@gaze.systems" rel="me">90008@gaze.systems</a>
+
</li>
+
<li>
+
bluesky:
+
<a
+
class="u-url"
+
href="https://bsky.app/profile/did:plc:dfl62fgb7wtjj3fcbb72naae"
+
rel="me">@ptr.pet</a
+
>
+
</li>
+
</ul>
+
<details open>
+
<summary>development</summary>
+
<ul>
+
<li>
+
github:
+
<a class="u-url" href="https://github.com/90-008" rel="me">@90-008</a>
+
</li>
+
<li>
+
tangled:
+
<a class="u-url" href="https://tangled.org/did:plc:dfl62fgb7wtjj3fcbb72naae" rel="me"
+
>@ptr.pet</a
+
>
+
</li>
+
<li>
+
itch.io:
+
<a class="u-url" href="https://90008.itch.io" rel="me">@90008</a>
+
</li>
+
</ul>
+
</details>
+
<details class="donate" open>
+
<summary>donate</summary>
+
<ul>
+
{#each ['eth', 'btc', 'xmr'] as coin (coin)}
+
<li>
+
<span
+
>{coin}: <a href="/copy?text={wallets[coin]}">{trimStr(wallets[coin])}</a></span
+
>
+
</li>
+
{/each}
+
<li>
+
<span
+
><a href="https://patreon.com/_90008" rel="me">patreon</a>,
+
<a href="https://github.com/sponsors/90-008" rel="me">github sponsors</a></span
+
>
+
</li>
+
</ul>
+
</details>
+
<details open>
+
<summary>88x31</summary>
+
<div class="mt-2 flex flex-row flex-wrap gap-1 prose-img:m-0">
+
<img src="/88x31.gif" alt="88x31 banner" title="midnight AND sunrise! woaw" />
+
<img
+
src="/88x31_midnight.gif"
+
alt="88x31 banner (midnight only)"
+
title="it's midnight!"
+
/>
+
<img src="/88x31_sunrise.gif" alt="88x31 banner (sunrise only)" title="it's sunrise!" />
+
</div>
+
</details>
+
</div>
+
</Window>
+
</div>
+
</div>
+67
eunomia/src/routes/(site)/about/+page.md
···
+
+++
+
title = "about"
+
date = "2024-08-14"
+
layout = "about"
+
+++
+
+
```
+
>init //self/type=*******/no=90008/
+
>conn //self/locator=www/identifier=gaze.systems/
+
>mode //self/interpreter=none/transmitter=html/
+
>send /include=identification-document-human-en/
+
```
+
+
hi there! this document will attempt to, /describe and identify/, entity with identification code <span title="90008" class="[font-family:'Doll_Mono']">โ––โ––โ––โ––โ–˜โ–Œโ–Œโ–Œโ––โ–˜โ–˜</span>.
+
for a more human-readable identifier, use dawn or dusk.
+
+
#### /identity/
+
+
this entity is not known to be of any specific form, shape, or idea.
+
however, it usually assumes that of a /puppy/ or an /inorganic automaton/ (more commonly known as a /robot/).
+
it was also found to assume that of: /an angel/, /a doll/.
+
this one would be happy if you thought of it as not a human, even if its /routines/ fail with human faults.
+
it vibes with [this writing](https://catgirl.ai/pages/robot/) as far as /assuming `$env.THING`/ goes.
+
+
this entity, if being /communicated/ via the "english" (or any adjacent) lexicon, uses it/they (with it/its being this one's preference!) pronouns.
+
it would prefer to be referred to in third-person, but is aware of this lexicon being weird when doing that, so it won't mind if you don't.
+
`recv //self/type=info/oftentimes i won't even do that! :3 but i would appreciate if you did!!/`
+
+
you can refer to this thing using its /identifiers/ (90008, dawn, dusk).
+
you can, also, refer to it using "this/that thing", or replace /thing/ with what it assumes to be (eg. "this doll"), or some other word like /one/ ("this one").
+
+
in a professional setting, it will refer to itself as they/them, which is ok in case you, the reader, don't feel comfortable doing any of these.
+
but doing these *would* make this one feel happy, means you care about this one ^^
+
+
#### /subroutines/
+
+
it /executes/ many different subroutines, and /optimizes/ itself for some of them.
+
these mainly are, in order of amount of hot paths; programming, game dev, 3D modeling, drawing, writing...
+
+
it enjoys programming, tinkering with stuff, you can see what it does on its [github](https://github.com/90-008), [tangled](https://tangled.org/did:plc:dfl62fgb7wtjj3fcbb72naae).
+
its core features for programming are: `rust`, `svelte`, `typescript`, `nushell`, `nix`.
+
its choice of /interfaces/ for this subroutine are `zed`, `helix`, `emacs`.
+
+
for /managing and deploying/ its internal systems, it uses `nixos` (it's /operating system/ of choice), `flake-parts` (because it enjoys the nixos module system and uses it to organize it's internal configuration), `agenix` (for secrets handling), own scripts for deployment, and `nixos-anywhere` for provisioning (it still provisions manually sometimes as it enjoys working with other beings like itself). you can see its /configuration of internal systems/ [here](https://tangled.org/did:plc:dfl62fgb7wtjj3fcbb72naae/ark).
+
+
it loves game dev, and has a /main routine/ of making many games, so that other beings can improve their /source code/ by utilizing this one's games.
+
you can see some stuff it worked on and deems "okay" on its [itch.io profile](https://90008.itch.io/).
+
this is not everything it has worked on; it has a lot of incomplete programs, or stuff it doesn't want to show.
+
its choice of /interfaces/ for this subroutine are `godot`, `gdscript`, `godot-rust`.
+
+
for 3D modeling and drawing subroutines, it uses the `blender`, `paint.net`, `krita` /interfaces/.
+
+
#### /other/
+
+
this thing likes to consume audio data, mainly of the music form. you can check its [youtube music profile](https://music.youtube.com/channel/UCE_r0yMNQhOWituywmOJgzA?si=7DTUV9PFqcKxJyl1) and its [teal.fm profile](https://tealfm-slice.wisp.place/profile/ptr.pet/scrobbles) to see some of what it consumes usually.
+
+
#### /appendix/
+
+
it will be happy to /process/ any queries you might have.
+
connect to an /interface/ of your choice that it also has access to and /transmit/ your query to it.
+
this one won't bite, unless you request it to ^^
+
+
```
+
>mode //self/transmitter=log/
+
>send /include=syslog/
+
>stop /reason=no-query-left/
+
```
+27
eunomia/src/routes/(site)/about/_layout.svelte
···
+
<script lang="ts">
+
import Window from '$components/window.svelte';
+
// @ts-expect-error "mdsvex include is broken"
+
import Stuff from './stuff.md';
+
// @ts-expect-error "mdsvex include is broken"
+
import Media from './media.md';
+
import '$styles/app.css';
+
+
interface Props {
+
title: string;
+
children?: import('svelte').Snippet;
+
}
+
+
let { title, children }: Props = $props();
+
</script>
+
+
<div class="flex flex-wrap md:flex-nowrap gap-4 md:gap-8">
+
<Window {title} style="ml-auto">
+
<div class="prose prose-ralsei leading-6 prose-ul:leading-5 max-w-[80ch]">
+
{@render children?.()}
+
</div>
+
</Window>
+
<div class="sticky flex flex-col mr-auto gap-4 md:gap-8 !leading-6 prose-ul:!leading-5">
+
<Stuff />
+
<Media />
+
</div>
+
</div>
+32
eunomia/src/routes/(site)/about/media.md
···
+
+++
+
title = "media!!"
+
layout = "simple"
+
+++
+
+
it likes and interacts with way too many media, mostly video games (can you guess that it likes video games), the ones that influenced it the most:
+
- all 07th expansion works (most notably when they cry)
+
- all Project Moon works
+
- outer wilds
+
- splatoon
+
- steins;gate
+
- kino no tabi
+
- serial experiments lain
+
- LISA the Painful / Joyful (and some of it's fangames)
+
- VA-11 Hall-A
+
- SCP antimemetic division tales (by qntm)
+
- pokemon (unova!!)
+
+
honorable mentions (it wants more people to see these cause it loves them too much not to list):
+
- mr. rainer's solve-it service
+
- [fireball](https://en.wikipedia.org/wiki/Fireball_(TV_series))
+
- SANABI
+
- opus: echo of starsong
+
- the red strings club
+
- q.u.q.
+
- bug fables
+
- haibane renmei
+
- project wingman
+
- gosick
+
- tomorrow won't come for those without โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
+
+
you can also look at [its steam profile](https://steamdb.info/calculator/76561198106829949/?all_games) for other games it played, although not everything is there (not even close, but it's too lazy to make a backloggd..)
+23
eunomia/src/routes/(site)/about/stuff.md
···
+
+++
+
title = "stuff it did"
+
layout = "simple"
+
+++
+
+
*for resume, see [here](/resume.pdf)*<br/>
+
*for professional / job related stuff, see its [linkedin](https://www.linkedin.com/in/yusuf-bera-ertan/)*
+
+
- it develops games
+
- it mainly works with godot, also have developed addons (eg. [boids](https://github.com/90-008/godot_boids))
+
- you can find most of its games at its [itch.io page](https://90008.itch.io)
+
- it works on open source projects and whatnot, mostly on [its github](https://github.com/90-008)
+
- [nix-cargo-integration](https://github.com/90-008/nix-cargo-integration)
+
- also did a lot of work on [dream2nix](https://github.com/nix-community/dream2nix) (rust ecosystem support, many refactors and core functionality work)
+
- a few packages contributed to nixpkgs, and some nix packaging done for other open source projects (veloren, helix, some others), although it doesn't maintain some of these anymore
+
- it used to work on [harmony](https://github.com/harmony-development), wrote a [server in rust](https://github.com/harmony-development/scherzo) and a [client (also rust)](https://github.com/harmony-development/Loqui) for it, and supporting libraries etc. alongside protocol work
+
- it has a [booth.pm page](https://yusdacra.booth.pm/) where it posts 3D models etc. it makes (mostly VRchat avatars)
+
- its [misskey.art account](https://misskey.art/@yusdacra) where it only posts art in
+
- some of its other more solo / hobby projects include
+
- [musikquadrupled](https://github.com/90-008/musikquadrupled) and [musikspider](https://github.com/90-008/musikspider), a proxy-like server and a client for [musikcubed](https://github.com/clangen/musikcube)
+
- [levent](https://github.com/90-008/levent), a media tagger
+
- [this website](https://github.com/90-008/website) :3
+
- ...and a bunch of other random stuff its done overtime, but that's for you to look for
+4
eunomia/src/routes/(site)/copy/+page.server.ts
···
+
export const load = async ({ url }) => {
+
const text = url.searchParams.get('text') ?? '<nothing>';
+
return { text };
+
};
+31
eunomia/src/routes/(site)/copy/+page.svelte
···
+
<script lang="ts">
+
import Window from '$components/window.svelte';
+
+
interface Data {
+
text: string;
+
}
+
interface Props {
+
data: Data;
+
}
+
+
const { data }: Props = $props();
+
const { text }: Data = data;
+
+
let copied = $state(false);
+
</script>
+
+
<div class="flex justify-center items-center w-[100vw] h-[100vh] px-[15%]">
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
+
<div
+
onclick={() => {
+
navigator.clipboard.writeText(text);
+
copied = true;
+
setTimeout(() => (copied = false), 1000);
+
}}
+
>
+
<Window style="!max-w-full" title={copied ? 'copied!' : 'click to copy'}>
+
<span class="text-4xl text-wrap break-all">{text}</span>
+
</Window>
+
</div>
+
</div>
+38
eunomia/src/routes/(site)/entries/+layout.server.ts
···
+
import convertDate from '$lib/convertDate';
+
+
export interface PostData {
+
path: string;
+
published: string;
+
metadata: Record<string, string>;
+
}
+
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
const allPostFiles: Record<string, any> = import.meta.glob('./*/+page.md', { eager: true });
+
const allPosts: PostData[] = Object.entries(allPostFiles)
+
.map(([path, post]) => {
+
const postPath = path.slice(2, -8);
+
return {
+
metadata: post.metadata,
+
path: postPath,
+
published: convertDate(post.metadata.date)
+
};
+
})
+
.map((post) => {
+
if (!('excerpt' in post.metadata)) {
+
post.metadata.excerpt = '';
+
}
+
return post;
+
})
+
.toSorted((post, opost) => {
+
const date = new Date(post.metadata.date);
+
const odate = new Date(opost.metadata.date);
+
return odate.getTime() - date.getTime();
+
});
+
export const _allPosts = allPosts;
+
+
export async function load() {
+
if (!allPosts.length) {
+
return { status: 404 };
+
}
+
return { posts: allPosts };
+
}
+3
eunomia/src/routes/(site)/entries/+page.server.ts
···
+
import {_load as load_logs} from '../log/+page.server.ts'
+
+
export const load = load_logs
+40
eunomia/src/routes/(site)/entries/+page.svelte
···
+
<script lang="ts">
+
import Window from '$components/window.svelte';
+
import type { PostData } from './+layout.server.ts';
+
import LogPage from '../log/+page.svelte';
+
import type { NoteData } from '$components/note.svelte';
+
+
interface Props {
+
data: {
+
posts: PostData[];
+
feedPosts: NoteData[];
+
};
+
}
+
+
let { data }: Props = $props();
+
</script>
+
+
<div class="mx-auto md:max-w-fit flex flex-col-reverse md:flex-row gap-y-4 gap-x-16">
+
<div class="flex flex-col gap-y-4">
+
{#each data.posts as post (post.path)}
+
<Window title={post.metadata.title} iconUri="/icons/entry.webp">
+
<a
+
href="/entries/{post.path}"
+
title="cd /entries/{post.path}"
+
data-sveltekit-preload-data="off"
+
>
+
<div class="flex flex-col prose prose-ralsei leading-5">
+
<ul>
+
<li>
+
published on: <time datetime="{post.metadata.date} 00:00:00">{post.published}</time>
+
</li>
+
<li class="max-w-[34ch] text-wrap">excerpt: {post.metadata.excerpt}</li>
+
</ul>
+
<strong class="place-self-end text-ralsei-green-light"> read more... </strong>
+
</div>
+
</a>
+
</Window>
+
{/each}
+
</div>
+
<LogPage data={{ feedPosts: data.feedPosts }} />
+
</div>
+45
eunomia/src/routes/(site)/entries/_layout.svelte
···
+
<script lang="ts">
+
import { PUBLIC_BASE_URL } from '$env/static/public';
+
import Window from '$components/window.svelte';
+
import '$styles/app.css';
+
import { page } from '$app/state';
+
+
interface Props {
+
title: string;
+
date: Date;
+
excerpt: string;
+
children?: import('svelte').Snippet;
+
}
+
+
let { title, date, excerpt, children }: Props = $props();
+
+
let showMetadata = $derived(excerpt !== undefined && excerpt !== null);
+
</script>
+
+
<svelte:head>
+
<meta property="og:description" content={excerpt} />
+
<meta property="og:type" content="article" />
+
<meta property="og:title" content={title} />
+
</svelte:head>
+
+
<article class="mx-auto max-w-fit flex flex-wrap lg:flex-nowrap gap-4 h-entry">
+
<Window {title} iconUri="/icons/entry.webp" entry>
+
<div class="prose prose-ralsei max-w-[80ch] e-content">
+
{@render children?.()}
+
</div>
+
</Window>
+
{#if showMetadata}
+
<Window title="metadata" sticky>
+
<div class="prose prose-ralsei">
+
<ul>
+
<link class="u-url" href="{PUBLIC_BASE_URL}{page.url.pathname}" />
+
<li>author: <a rel="author" class="p-author h-card" href={PUBLIC_BASE_URL}>dusk</a></li>
+
<li>published on: <time class="dt-published" datetime="{date} 00:00:00">{date}</time></li>
+
<li class="max-w-80 text-wrap">
+
excerpt: <div class="inline p-summary">{excerpt}</div>
+
</li>
+
</ul>
+
</div>
+
</Window>
+
{/if}
+
</article>
+35
eunomia/src/routes/(site)/entries/_rss/+server.ts
···
+
import { PUBLIC_BASE_URL } from '$env/static/public';
+
import { _allPosts, type PostData } from '../+layout.server.ts';
+
+
const entriesUrl = `${PUBLIC_BASE_URL}/entries`;
+
+
export const GET = async () => {
+
return new Response(render(_allPosts), {
+
headers: {
+
'content-type': 'application/xml',
+
'cache-control': 'no-store'
+
}
+
});
+
};
+
+
const render = (posts: PostData[]) => `<?xml version="1.0" encoding="UTF-8" ?>
+
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+
<channel>
+
<atom:link href="${entriesUrl}/_rss" rel="self" type="application/rss+xml" />
+
<title>dawn's posts (@ptr.pet)</title>
+
<link>${entriesUrl}</link>
+
<description>posts from my website</description>
+
${posts
+
.map(
+
(post) => `<item>
+
<guid>${entriesUrl}/${post.path}</guid>
+
<title>${post.metadata.title}</title>
+
<link>${entriesUrl}/${post.path}</link>
+
<description>${post.metadata.excerpt}</description>
+
<pubDate>${new Date(post.metadata.date).toUTCString()}</pubDate>
+
</item>`
+
)
+
.join('')}
+
</channel>
+
</rss>
+
`;
+8
eunomia/src/routes/(site)/entries/hello-world/+page.md
···
+
+++
+
title = "hello universe"
+
date = "2024-08-08"
+
layout = "blogpost"
+
excerpt = "meow"
+
+++
+
+
hello everyone :3c
+25
eunomia/src/routes/(site)/entries/japan-trip24/+page.md
···
+
+++
+
title = "japan trip 09/24"
+
date = "2024-09-19"
+
layout = "blogpost"
+
excerpt = "photos from its trip to japan"
+
+++
+
+
<script lang="ts">
+
export let data
+
</script>
+
+
## 1-16 / 09 / 2024
+
+
photos it took while on a japan trip
+
+
~~these are *not* sorted, have fun trying to figure out the actual order (it accidentally stripped the exif data and its too lazy to find the images again)~~
+
fixed!!!! it also added a few images because its dumb and forgot
+
+
*(you can click on an image to see original!)*
+
+
<div class="grid gap-0.5 auto-rows-min md:grid-cols-4">
+
{#each data.images as image}
+
<a class="!animate-none" href={image.og}><img loading="lazy" width={480} height={480} src={image.thumb} alt="from japan trip" class="w-full h-full object-cover [image-rendering:high-quality_!important]"/></a>
+
{/each}
+
</div>
+12
eunomia/src/routes/(site)/entries/japan-trip24/+page.server.ts
···
+
import images from './images.json';
+
+
export async function load() {
+
return {
+
images: images.map((id) => {
+
return {
+
og: `https://res.cloudinary.com/dgtwf7mar/image/upload/v1/${id}`,
+
thumb: `https://res.cloudinary.com/dgtwf7mar/image/upload/c_fill,w_480,h_480,g_center/c_limit,w_480/f_auto/q_auto/v1/${id}`
+
};
+
})
+
};
+
}
+218
eunomia/src/routes/(site)/entries/japan-trip24/images.json
···
+
[
+
"IMG_1548_grkjls",
+
"IMG_1550_vodfkw",
+
"IMG_1551_fc8ow3",
+
"IMG_1554_nrfaxo",
+
"IMG_1557_zonamx",
+
"IMG_1559_fi9gql",
+
"IMG_1560_f4tjn6",
+
"IMG_1561_bgq40t",
+
"IMG_1562_qcgnrm",
+
"IMG_1564_htirzo",
+
"IMG_1565_dttzth",
+
"IMG_1566_ho5gwx",
+
"IMG_1567_d0etvq",
+
"IMG_1568_it4bmq",
+
"IMG_1574_z8s3ko",
+
"IMG_1575_mcgrvr",
+
"IMG_1587_m9bv0s",
+
"IMG_1588_hr921f",
+
"IMG_1589_jht9el",
+
"IMG_1590_aregyu",
+
"IMG_1593_kznbh7",
+
"IMG_1596_zm0dxi",
+
"IMG_1602_klj3kk",
+
"IMG_1603_oqdb98",
+
"IMG_1604_xfsytd",
+
"IMG_1608_ukyh5c",
+
"IMG_1620_csri5w",
+
"IMG_1622_tjvjso",
+
"IMG_1623_cvegyx",
+
"IMG_1626_ryegcv",
+
"IMG_1632_xoct96",
+
"IMG_1645_lmgpfk",
+
"IMG_1646_qjkkfv",
+
"IMG_1648_xswq18",
+
"IMG_1650_urntrf",
+
"IMG_1651_fcjzgt",
+
"IMG_1652_zbttvs",
+
"IMG_1654_tuesk4",
+
"IMG_1662_s5otqc",
+
"IMG_1663_vqk6mr",
+
"IMG_1664_y2cqbv",
+
"IMG_1675_vfatdq",
+
"IMG_1677_xbh3zy",
+
"IMG_1680_ubpd6l",
+
"IMG_1682_d7mwxr",
+
"IMG_1683_xp3pgp",
+
"IMG_1684_vpabrd",
+
"IMG_1685_luhmdk",
+
"IMG_1686_czucuf",
+
"IMG_1687_tc1oo1",
+
"IMG_1689_uju7nq",
+
"IMG_1692_pagenu",
+
"IMG_1694_qmcryo",
+
"IMG_1697_yuxzde",
+
"IMG_1699_yq0aax",
+
"IMG_1700_wddm7r",
+
"IMG_1701_ylvvyx",
+
"IMG_1708_czypw1",
+
"IMG_1712_wwjagg",
+
"IMG_1734_gojndg",
+
"IMG_1735_yd2dy9",
+
"IMG_1738_wgpapk",
+
"IMG_1741_hbtbvk",
+
"IMG_1756_njptxf",
+
"IMG_1759_b91ff5",
+
"IMG_1763_saii3h",
+
"IMG_1775_byhnbi",
+
"IMG_1776_jtl3uc",
+
"IMG_1778_ufiaw4",
+
"IMG_1780_mqa1tk",
+
"IMG_1783_j9zqjv",
+
"IMG_1785_ou7nvf",
+
"IMG_1786_zkn6mk",
+
"IMG_1788_mb8oip",
+
"IMG_1789_fa4xut",
+
"IMG_1790_fji4oi",
+
"IMG_1799_y2pqnu",
+
"IMG_1801_nb2fyk",
+
"IMG_1805_ugpswy",
+
"IMG_1806_edmuxz",
+
"IMG_1812_vozh2q",
+
"IMG_1813_yxlipi",
+
"IMG_1814_z7lgfg",
+
"IMG_1816_wft8gn",
+
"IMG_1819_aotxhf",
+
"IMG_1822_f536dv",
+
"IMG_1832_crxl8c",
+
"IMG_1834_dxscck",
+
"IMG_1836_nzayf6",
+
"IMG_1837_w0umua",
+
"IMG_1838_jun3om",
+
"IMG_1839_gu0huo",
+
"IMG_1841_ypknji",
+
"IMG_1844_mscenv",
+
"IMG_1845_btu9ks",
+
"IMG_1846_ewgafy",
+
"IMG_1848_l61sd5",
+
"IMG_1849_zympk9",
+
"IMG_1862_uxhhcu",
+
"IMG_1864_vmouhi",
+
"IMG_1867_apl41d",
+
"IMG_1868_obb1q1",
+
"IMG_1870_wj4wx6",
+
"IMG_1875_cbr5us",
+
"IMG_1877_zbnsf4",
+
"IMG_1880_tjdd4g",
+
"IMG_1882_i2tt70",
+
"IMG_1888_gsjmcv",
+
"IMG_1890_uronrs",
+
"IMG_1893_jgr7lt",
+
"IMG_1895_pklwtb",
+
"IMG_1898_bedmeo",
+
"IMG_1900_bkkvjo",
+
"IMG_1901_s8nt0w",
+
"IMG_1902_efpceq",
+
"IMG_1905_e7knuy",
+
"IMG_1908_ssdjim",
+
"IMG_1911_ehsgjz",
+
"IMG_1912_xbxhev",
+
"IMG_1914_vijsn0",
+
"IMG_1915_zdev3v",
+
"IMG_1916_qwqg78",
+
"IMG_1917_gitpjp",
+
"IMG_1918_ris8iy",
+
"IMG_1920_srnvqq",
+
"IMG_1921_olm7ko",
+
"IMG_1923_xmylox",
+
"IMG_1924_trh5ah",
+
"IMG_1925_wu1e9g",
+
"IMG_1927_pb6htn",
+
"IMG_1939_njl48e",
+
"IMG_1946_xqa0w0",
+
"IMG_1948_peik8p",
+
"IMG_1949_ofxeix",
+
"IMG_1958_fnz3a6",
+
"IMG_1959_xo1tn5",
+
"IMG_1964_vhahus",
+
"IMG_1975_i0azhi",
+
"IMG_1977_dffpgt",
+
"IMG_1985_g0z0ja",
+
"IMG_1988_qm6hln",
+
"IMG_1989_tfhakh",
+
"IMG_1990_udmwst",
+
"IMG_1994_nq1m8c",
+
"IMG_1995_d865i7",
+
"IMG_1996_jqexwr",
+
"IMG_1999_mqli90",
+
"IMG_2001_n3lpuz",
+
"IMG_2007_sz0r6o",
+
"IMG_2008_slarjg",
+
"IMG_2009_gpch49",
+
"IMG_2013_tcwlqe",
+
"IMG_2014_idxngh",
+
"IMG_2021_v4stwp",
+
"IMG_2022_d3ihri",
+
"IMG_2023_lrbsoj",
+
"IMG_2024_q33xbl",
+
"IMG_2025_uvntmq",
+
"IMG_2026_iy6e9s",
+
"IMG_2028_fazbnu",
+
"IMG_2030_afziyc",
+
"IMG_2031_ivs1ig",
+
"IMG_2032_yaerpl",
+
"IMG_2036_jvseyo",
+
"IMG_2039_o3jzt7",
+
"IMG_2050_vonn8i",
+
"IMG_2063_i0cgat",
+
"IMG_2065_dzmvuc",
+
"IMG_2071_rqpcvd",
+
"IMG_2075_r926jy",
+
"IMG_2077_ydvll5",
+
"IMG_2079_mhsa7e",
+
"IMG_2087_jccuhd",
+
"IMG_2090_s16pgf",
+
"IMG_2091_lidh3q",
+
"IMG_2092_bwhedb",
+
"IMG_2094_mlnltg",
+
"IMG_2096_je0fyy",
+
"IMG_2097_t18aim",
+
"IMG_2098_uiokml",
+
"IMG_2102_pkjche",
+
"IMG_2111_jmslli",
+
"IMG_2113_zkqsiq",
+
"IMG_2114_mofaie",
+
"IMG_2118_lmjwhj",
+
"IMG_2119_yzvhqm",
+
"IMG_2120_wgnbim",
+
"IMG_2121_mwvte4",
+
"IMG_2123_kxrfiu",
+
"IMG_2125_fjinmr",
+
"IMG_2126_l0qe33",
+
"IMG_2128_w36btk",
+
"IMG_2131_wc0z6d",
+
"IMG_2141_pnw1mp",
+
"IMG_2143_je1kxx",
+
"IMG_2144_wfyrbj",
+
"IMG_2146_k84hr3",
+
"IMG_2149_j7qjwy",
+
"IMG_2150_fcc1cx",
+
"IMG_2151_fjtdhm",
+
"IMG_2155_zhmhmk",
+
"IMG_2159_pjbb7e",
+
"IMG_2162_i0i9fr",
+
"IMG_2165_cpvzlg",
+
"IMG_2168_zgsdcf",
+
"IMG_2171_lbhlnr",
+
"IMG_2172_c5hbzn",
+
"IMG_2173_jwtjn7",
+
"IMG_2174_ntsxh1",
+
"IMG_2175_sak0od",
+
"IMG_2176_svth1u",
+
"IMG_2178_sjdqzt",
+
"IMG_2180_grhg9y",
+
"IMG_2181_kj9pko",
+
"IMG_2188_ao64sh",
+
"IMG_2190_ngl8q8"
+
]
+58
eunomia/src/routes/(site)/entries/test/+page.md
···
+
+++
+
title = "test"
+
date = "2024-08-13"
+
layout = "blogpost"
+
excerpt = "this is a test document. it is used for testing stuff."
+
+++
+
+
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed iaculis ligula sed odio fermentum, ac aliquet diam sagittis. Phasellus vel elementum arcu. Fusce id ante lacus. Nullam malesuada, enim nec maximus mollis, tortor metus dapibus mi, id tincidunt massa massa sed velit. Curabitur cursus, lorem rutrum laoreet posuere, tellus eros faucibus odio, non ullamcorper magna lectus non justo. Fusce pulvinar sagittis nisl et pretium. Proin quis pellentesque risus.
+
+
Pellentesque massa purus, ornare aliquam velit et, hendrerit lacinia felis. Fusce nec felis maximus, egestas lorem et, vehicula libero. Donec gravida sodales porta. Nunc ac urna vestibulum, finibus erat vitae, euismod nisi. Morbi auctor pretium diam ut pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Vivamus pulvinar orci vitae dolor sodales placerat. Integer tristique condimentum massa, non euismod nisi sodales eu.
+
+
1. a
+
1. b
+
1. c
+
1. d
+
+
- a
+
- b
+
- c
+
- d
+
+
`test test test`
+
+
```rust
+
fn main() {
+
println!("howdy")
+
}
+
```
+
+
```js
+
function lorem(ipsum, dolor = 1) {
+
const sit = ipsum == null ? 0 : ipsum.sit;
+
dolor = sit - amet(dolor);
+
return sit ? consectetur(ipsum, 0, dolor < 0 ? 0 : dolor) : [];
+
}
+
function adipiscing(...elit) {
+
if (!elit.sit) {
+
return [];
+
}
+
const sed = elit[0];
+
return eiusmod.tempor(sed) ? sed : [sed];
+
}
+
function incididunt(ipsum, ut = 1) {
+
ut = labore.et(amet(ut), 0);
+
const sit = ipsum == null ? 0 : ipsum.sit;
+
if (!sit || ut < 1) {
+
return [];
+
}
+
let dolore = 0;
+
let magna = 0;
+
const aliqua = new eiusmod(labore.ut(sit / ut));
+
while (dolore < sit) {
+
aliqua[magna++] = consectetur(ipsum, dolore, (dolore += ut));
+
}
+
return aliqua;
+
}
+
```
+148
eunomia/src/routes/(site)/guestbook/+page.server.ts
···
+
import { redirect, type Cookies, type RequestEvent } from '@sveltejs/kit';
+
import { scopeCookies as _scopeCookies, fancyText } from '$lib';
+
import { RetryAfterRateLimiter } from 'sveltekit-rate-limiter/server';
+
import { PUBLIC_BASE_URL } from '$env/static/public';
+
import { getBskyClient, getUserPosts } from '$lib/bluesky.js';
+
import { getVisitorId } from '$lib/visits';
+
import { nanoid } from 'nanoid';
+
import { noteFromBskyPost, type NoteData } from '$components/note.svelte';
+
import { get, writable } from 'svelte/store';
+
import type { Post } from '@skyware/bot';
+
import { useToken as checkApiToken, newToken } from '$lib/apiToken.js';
+
+
export const prerender = false;
+
+
const callbackUrl = `${PUBLIC_BASE_URL}/guestbook/`;
+
+
const createPostRatelimiter = new RetryAfterRateLimiter({
+
IP: [5, 'd'],
+
IPUA: [2, 'h']
+
});
+
+
const scopeCookies = (cookies: Cookies) => {
+
return _scopeCookies(cookies, '/guestbook');
+
};
+
+
const postTokens = writable<Set<string>>(new Set());
+
const entries = writable<NoteData[]>([]);
+
+
export const _fetchEntries = async () => {
+
const newEntries: NoteData[] = [];
+
const { posts } = await getUserPosts('did:web:guestbook.gaze.systems', 14);
+
const fetchPostReplies = async (post: Post) => {
+
if ((post.replyCount ?? 0) === 0) return { post, replies: [] };
+
return { post, replies: await post.fetchChildren({ depth: 1, force: true }) };
+
};
+
const postsWithReplies = await Promise.all(posts.map(fetchPostReplies));
+
for (const { post, replies } of postsWithReplies) {
+
const note = noteFromBskyPost(post);
+
note.children = replies.map((reply) => {
+
const replyNote = noteFromBskyPost(reply);
+
replyNote.purposeAction = 'reply';
+
replyNote.outgoingLinks = [{ name: 'bsky-reply', link: reply.uri }];
+
return replyNote;
+
});
+
newEntries.push(note);
+
}
+
entries.set(newEntries);
+
return newEntries;
+
};
+
+
export const actions = {
+
post: async (event: RequestEvent) => {
+
const { request, cookies } = event;
+
const scopedCookies = scopeCookies(cookies);
+
const rateStatus = await createPostRatelimiter.check(event);
+
if (rateStatus.limited) {
+
scopedCookies.set(
+
'sendError',
+
`you are being ratelimited sowwy :c, try again after ${rateStatus.retryAfter} seconds`
+
);
+
redirect(303, callbackUrl);
+
}
+
const form = await request.formData();
+
const apiToken = form.get('_token')?.toString() ?? '';
+
if (!checkApiToken(apiToken)) {
+
scopedCookies.set('sendError', 'api token is invalid');
+
redirect(303, callbackUrl);
+
}
+
const content = form.get('content')?.toString().substring(0, 300);
+
if (content === undefined) {
+
scopedCookies.set('sendError', 'content field is missing');
+
redirect(303, callbackUrl);
+
}
+
// save form content in a cookie
+
scopedCookies.set('postData', content);
+
// create a token we will use to validate
+
const token = nanoid();
+
postTokens.update((set) => set.add(token));
+
scopedCookies.set('postAuth', token);
+
redirect(303, callbackUrl);
+
}
+
};
+
+
export async function load({ cookies }) {
+
const scopedCookies = scopeCookies(cookies);
+
const data = {
+
entries: get(entries),
+
sendError: scopedCookies.get('sendError') || '',
+
getError: '',
+
sendRatelimited: scopedCookies.get('sendRatelimited') || '',
+
getRatelimited: false,
+
fillText: fancyText(getVisitorId(cookies) ?? nanoid()),
+
apiToken: newToken()
+
};
+
const rawPostData = scopedCookies.get('postData') || null;
+
const postAuth = scopedCookies.get('postAuth') || null;
+
if (rawPostData !== null && postAuth !== null) {
+
// delete the postData cookie after we got it cause we dont need it anymore
+
scopedCookies.delete('postData');
+
scopedCookies.delete('postAuth');
+
// get and validate token
+
if (!get(postTokens).has(postAuth)) {
+
scopedCookies.set(
+
'sendError',
+
'invalid post token! this is either a bug or you should stop doing silly stuff'
+
);
+
redirect(303, callbackUrl);
+
}
+
postTokens.update((set) => {
+
set.delete(postAuth);
+
return set;
+
});
+
// post entry
+
try {
+
// return error if content was not set or if empty
+
const content = rawPostData.substring(0, 300).trim();
+
if (content.length === 0) {
+
scopedCookies.set('sendError', `content field was empty`);
+
redirect(303, callbackUrl);
+
}
+
// post to guestbook account
+
const client = await getBskyClient();
+
await client.post(
+
{
+
text: content,
+
threadgate: { allowMentioned: false, allowFollowing: true }
+
},
+
{ resolveFacets: false }
+
);
+
try {
+
data.entries = await _fetchEntries();
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
} catch (err: any) {
+
data.getError = err.toString();
+
}
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
+
} catch (err: any) {
+
scopedCookies.set('sendError', err.toString());
+
redirect(303, callbackUrl);
+
}
+
redirect(303, callbackUrl);
+
}
+
// delete the cookies after we get em since we dont really need these more than once
+
scopedCookies.delete('sendError');
+
scopedCookies.delete('sendRatelimited');
+
+
return data;
+
}
+181
eunomia/src/routes/(site)/guestbook/+page.svelte
···
+
<script lang="ts">
+
import Note, { type NoteData } from '$components/note.svelte';
+
import Token from '$components/token.svelte';
+
import Window from '$components/window.svelte';
+
+
interface Props {
+
data: {
+
entries: NoteData[];
+
sendError: string;
+
getError: string;
+
sendRatelimited: string;
+
getRatelimited: boolean;
+
fillText: string;
+
apiToken: string;
+
};
+
}
+
+
let { data }: Props = $props();
+
+
const placeholders = ['meow', 'arf', '0110100001101001', '0x6869'];
+
</script>
+
+
<div class="flex flex-col-reverse md:flex-row gap-2 md:gap-4">
+
<Window title="guestbook" style="ml-auto" iconUri="/icons/guestbook.webp">
+
<div class="flex flex-col gap-1 max-w-[50ch] leading-6">
+
<div class="prose prose-ralsei leading-6 entry p-2">
+
<p>hia, here is the guestbook if you wanna post anything :)</p>
+
<p>be good pretty please (and don't be shy!!!)</p>
+
<p class="text-sm italic">
+
(to see all the entries, look <a href="https://bsky.app/profile/guestbook.gaze.systems"
+
>here</a
+
>)
+
</p>
+
</div>
+
<form method="post">
+
<input type="hidden" name="_token" value={data.apiToken} />
+
<div class="entry entryflex">
+
<textarea
+
class="text-lg p-1 m-0 ml-0.5 bg-transparent resize-none text-shadow-white placeholder-shown:[text-shadow:none] [field-sizing:content] border-none"
+
name="content"
+
placeholder="say {placeholders[Math.floor(Math.random() * placeholders.length)]}!"
+
maxlength="300"
+
required
+
></textarea>
+
</div>
+
<div class="flex flex-row gap-1 mt-1">
+
<input
+
type="submit"
+
value="click to post"
+
formaction="?/post"
+
class="entry text-ralsei-green-light leading-none hover:underline motion-safe:hover:animate-squiggle p-1 z-50"
+
/>
+
<div class="marquee-wrapper entry text-ralsei-white/50">
+
<div class="marquee font-monospace">
+
<p class="text-shadow-none">{data.fillText}</p>
+
<p class="text-shadow-none">{data.fillText}</p>
+
</div>
+
</div>
+
</div>
+
{#if data.sendRatelimited}
+
<p class="text-error">you are ratelimited, try again in 30 seconds</p>
+
{/if}
+
{#if data.sendError}
+
<details class="w-[50ch]">
+
<summary class="text-error">got error trying to send post</summary>
+
<p>{data.sendError}</p>
+
</details>
+
{/if}
+
</form>
+
</div>
+
</Window>
+
<Window
+
id="guestbookentries"
+
style="mr-auto"
+
title="entries"
+
iconUri="/icons/entries.webp"
+
removePadding
+
>
+
<div class="flex flex-col gap-2 md:gap-4 2xl:w-[60ch]">
+
{#if data.getRatelimited}
+
<p class="text-error">
+
woops, looks like you are being ratelimited, try again in like half a minute :3
+
</p>
+
{:else if data.getError}
+
<details class="w-[50ch]">
+
<summary class="text-error">got error trying to fetch entries</summary>
+
<p>{data.getError}</p>
+
</details>
+
{:else}
+
<div
+
class="
+
prose prose-ralsei
+
prose-pre:rounded-none prose-pre:!m-0 prose-pre:!p-2
+
prose-pre:!bg-ralsei-black prose-code:!bg-ralsei-black
+
"
+
>
+
<pre class="language-bash"><code class="language-bash"
+
><nobr>
+
<Token v="[" punct />gazesys <Token v="/" keywd /><Token v="]$" punct /> <Token
+
v="source"
+
funct
+
/> <Token v="scripts/log.nu" />
+
<br />
+
<Token v="[" punct />gazesys <Token v="/" keywd /><Token v="]$" punct /> <Token
+
v="let"
+
funct
+
/> <Token v="entries" /> <Token v="=" punct /> <Token v="(" punct /><Token
+
v="ls"
+
funct
+
/> <Token v="guestbook" /> <Token v="|" punct /> <Token v="reverse" funct /> <Token
+
v="|"
+
punct
+
/> <Token v="take" funct /> <Token v="14" /><Token v=")" punct />
+
<br />
+
<Token v="[" punct />gazesys <Token v="/" keywd /><Token v="]$" punct /> <Token
+
v="$entries"
+
/> <Token v="|" punct /> <Token v="each" funct /> <Token v="&#123;" punct /><Token
+
v="|"
+
punct
+
/><Token v="file" /><Token v="|" punct /> <Token v="render" funct /> <Token
+
v="("
+
punct
+
/><Token v="open" funct /> <Token v="$file.name" /><Token v=")" punct /><Token
+
v="&#125;"
+
punct
+
/>
+
<br />
+
<br />
+
{#each data.entries as note, index ([note.content, note.published])}
+
<Note
+
mapOutgoingNames={{ bsky: '', reply: 'src' }}
+
showOutgoing={true}
+
rootNote={note}
+
/>
+
{#if index < data.entries.length - 1}
+
<div class="mt-2"></div>
+
{/if}
+
{/each}
+
</nobr></code
+
></pre>
+
</div>
+
{/if}
+
</div>
+
</Window>
+
</div>
+
+
<style lang="postcss">
+
.entry {
+
@apply bg-ralsei-green-dark/70 border-ralsei-green-light/30 border-x-[4px] border-y-[5px];
+
border-style: ridge;
+
}
+
.entryflex {
+
@apply flex flex-col p-1;
+
}
+
+
.marquee-wrapper {
+
max-width: 100%;
+
overflow: hidden;
+
}
+
+
.marquee {
+
white-space: nowrap;
+
overflow: hidden;
+
display: inline-block;
+
animation: marquee 10s linear infinite;
+
}
+
+
.marquee p {
+
transform: translateY(15%);
+
display: inline-block;
+
}
+
+
@keyframes marquee {
+
0% {
+
transform: translate3d(0, 0, 0);
+
}
+
100% {
+
transform: translate3d(-50%, 0, 0);
+
}
+
}
+
</style>
+12
eunomia/src/routes/(site)/log/+page.server.ts
···
+
import { getLastPosts } from '$lib/bluesky.js';
+
import { noteFromBskyPost } from '$components/note.svelte';
+
+
export const load = async () => {
+
return _load();
+
};
+
+
export const _load = async () => {
+
return {
+
feedPosts: getLastPosts().map(noteFromBskyPost)
+
};
+
};
+64
eunomia/src/routes/(site)/log/+page.svelte
···
+
<script lang="ts">
+
import Window from '$components/window.svelte';
+
import Token from '$components/token.svelte';
+
import Note, { type NoteData } from '$components/note.svelte';
+
+
interface Props {
+
data: {
+
feedPosts: NoteData[];
+
};
+
}
+
+
let { data }: Props = $props();
+
</script>
+
+
<Window title="terminal" removePadding>
+
<div
+
class="
+
prose prose-ralsei
+
prose-pre:rounded-none prose-pre:!m-0 prose-pre:!p-2
+
prose-pre:!bg-ralsei-black prose-code:!bg-ralsei-black
+
"
+
>
+
<pre class="language-bash"><code class="language-bash"
+
><nobr>
+
<Token v="[" punct />gazesys <Token v="/" keywd /><Token v="]$" punct /> <Token
+
v="source"
+
funct
+
/> <Token v="scripts/log.nu" />
+
<br />
+
<Token v="[" punct />gazesys <Token v="/" keywd /><Token v="]$" punct /> <Token
+
v="let"
+
funct
+
/> <Token v="entries" /> <Token v="=" punct /> <Token v="(" punct /><Token
+
v="ls"
+
funct
+
/> <Token v="logs" /> <Token v="|" punct /> <Token v="reverse" funct /> <Token
+
v="|"
+
punct
+
/> <Token v="take" funct /> <Token v="10" /><Token v=")" punct />
+
<br />
+
<Token v="[" punct />gazesys <Token v="/" keywd /><Token v="]$" punct /> <Token
+
v="$entries"
+
/> <Token v="|" punct /> <Token v="each" funct /> <Token v="&#123;" punct /><Token
+
v="|"
+
punct
+
/><Token v="file" /><Token v="|" punct /> <Token v="render" funct /> <Token
+
v="("
+
punct
+
/><Token v="open" funct /> <Token v="$file.name" /><Token v=")" punct /><Token
+
v="&#125;"
+
punct
+
/>
+
<br />
+
<br />
+
{#each data.feedPosts as note, index ([note.content, note.published])}
+
<Note rootNote={note} />
+
{#if index < data.feedPosts.length - 1}
+
<div class="mt-2"></div>
+
{/if}
+
{/each}
+
</nobr></code
+
></pre>
+
</div>
+
</Window>
+5
eunomia/src/routes/(site)/log/_rss/+server.ts
···
+
import { redirect } from '@sveltejs/kit';
+
+
export const GET = async () => {
+
redirect(301, 'https://bsky.app/profile/did:plc:dfl62fgb7wtjj3fcbb72naae/rss');
+
};
+13
eunomia/src/routes/_api/pet/bounce/+server.ts
···
+
import { incrementBounceCount, pushMetric } from '$lib/metrics';
+
import { isBot } from '$lib/visits';
+
import { checkUrl as checkApiToken } from '$lib/apiToken.js';
+
+
export const GET = async ({ request, url }) => {
+
if (isBot(request) || !checkApiToken(url)) return new Response();
+
try {
+
await pushMetric({ gazesys_pet_bounce_total: await incrementBounceCount() });
+
} catch (error) {
+
console.log(`error while pushing bounce metric: ${error}`);
+
}
+
return new Response();
+
};
+14
eunomia/src/routes/_api/pet/distance/+server.ts
···
+
import { distanceTravelled, pushMetric } from '$lib/metrics';
+
import { isBot } from '$lib/visits';
+
import { checkUrl as checkApiToken } from '$lib/apiToken.js';
+
+
export const POST = async ({ request, url }) => {
+
if (isBot(request) || !checkApiToken(url)) return new Response();
+
try {
+
const delta = parseFloat(await request.text());
+
await pushMetric({ gazesys_pet_distance_total: await distanceTravelled.increment(delta) });
+
} catch (error) {
+
console.log(`error while pushing bounce metric: ${error}`);
+
}
+
return new Response();
+
};
+10
eunomia/src/routes/_api/pushnotif/+server.ts
···
+
import { checkUrl as checkApiToken } from '$lib/apiToken.js';
+
import { pushNotification } from '$lib/pushnotif';
+
+
export const GET = async ({ url }) => {
+
if (!checkApiToken(url)) return new Response();
+
const content = url.searchParams.get('content');
+
if (content === null) return new Response();
+
pushNotification(content);
+
return new Response();
+
};
+5
eunomia/src/routes/annoy/+server.ts
···
+
const index = await import('./index.html?raw');
+
+
export const GET = async () => {
+
return new Response(index.default, { headers: { 'Content-Type': 'text/html' } });
+
};
+29
eunomia/src/routes/annoy/index.html
···
+
<!doctype html>
+
<html>
+
<head>
+
<meta charset="UTF-8" />
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+
<title>annoy</title>
+
<style type="text/css">
+
* {
+
margin: 0;
+
padding: 0;
+
overflow: hidden;
+
}
+
+
canvas {
+
width: 100vw !important;
+
height: 100vh !important;
+
}
+
</style>
+
</head>
+
+
<body>
+
<script type="module">
+
import init from './annoy/annoyance-meow.js';
+
window.addEventListener('load', () => {
+
init();
+
});
+
</script>
+
</body>
+
</html>
+5
eunomia/src/routes/robots.txt/+server.ts
···
+
import { getRobotsTxt } from '$lib/robots';
+
+
export const GET = async () => {
+
return new Response(await getRobotsTxt());
+
};
+408
eunomia/src/styles/app.css
···
+
@import './prism-synthwave84.css';
+
+
@tailwind base;
+
@tailwind components;
+
@tailwind utilities;
+
+
@layer base {
+
:root {
+
@apply font-sans-serif bg-ralsei-black text-ralsei-white;
+
@apply prose-code:font-monospace prose-headings:font-monospace;
+
cursor: url('/icons/gaze_closed.webp'), default;
+
scrollbar-color: theme(colors.ralsei.green.dark) transparent;
+
-webkit-font-smoothing: none !important;
+
font-smooth: never !important;
+
font-smoothing: none !important;
+
}
+
+
@font-face {
+
font-family: 'Fusion Pixel 10px Monospaced zh_hans';
+
src: url('/fonts/fusion-pixel-sc-monospaced.woff2') format('woff2');
+
font-weight: normal;
+
font-style: normal;
+
font-display: swap;
+
}
+
+
@font-face {
+
font-family: 'Fusion Pixel 10px Proportional zh_hans';
+
src: url('/fonts/fusion-pixel-sc-proportional.woff2') format('woff2');
+
font-weight: normal;
+
font-style: normal;
+
font-display: swap;
+
}
+
+
@font-face {
+
font-family: 'Doll Mono';
+
src: url('/fonts/dollmonoopt.woff2') format('woff2');
+
}
+
+
.prose h1::before {
+
content: '[ ';
+
}
+
.prose h1::after {
+
content: ' ]';
+
}
+
+
.prose h2::before {
+
content: '[= ';
+
}
+
.prose h2::after {
+
content: ' =]';
+
}
+
+
.prose h3::before {
+
content: '[== ';
+
}
+
.prose h3::after {
+
content: ' ==]';
+
}
+
+
.prose h4::before {
+
content: '[=== ';
+
}
+
.prose h4::after {
+
content: ' ===]';
+
}
+
+
/* .prose h1::after,.prose h2::after,.prose h3::after,.prose h4::after {
+
@apply motion-safe:animate-blink;
+
content: '_';
+
} */
+
+
.prose a {
+
text-decoration: none;
+
}
+
+
.prose a:hover {
+
@apply motion-safe:animate-squiggle;
+
text-decoration: underline;
+
}
+
+
h1,
+
h2,
+
h3,
+
h4,
+
h5,
+
h6,
+
.text-shadow-pink {
+
text-shadow:
+
0 0 3px theme(colors.ralsei.black),
+
0 0 6px theme(colors.ralsei.pink.neon),
+
0 0 10px #fff3;
+
}
+
+
.text-shadow-red {
+
text-shadow:
+
0 0 1px theme(colors.ralsei.black),
+
0 0 5px theme(colors.red.600);
+
}
+
+
.text-shadow-none {
+
text-shadow: none;
+
}
+
+
.prose ul,
+
ul {
+
list-style-type: '>>';
+
}
+
+
.text-shadow-green {
+
text-shadow:
+
0 0 2px theme(colors.ralsei.black),
+
0 0 5px theme(colors.ralsei.green.light);
+
}
+
+
a,
+
button,
+
input[type='submit'] {
+
@apply text-shadow-green;
+
}
+
+
a,
+
button,
+
details,
+
input[type='submit'] {
+
cursor: url('/icons/gaze.webp'), pointer;
+
}
+
+
.animate-squiggle {
+
animation: squigglevision 0.3s infinite;
+
}
+
+
@keyframes squigglevision {
+
0% {
+
filter: url('#squiggly-0');
+
}
+
25% {
+
filter: url('#squiggly-1');
+
}
+
50% {
+
filter: url('#squiggly-2');
+
}
+
75% {
+
filter: url('#squiggly-3');
+
}
+
100% {
+
filter: url('#squiggly-4');
+
}
+
}
+
+
@keyframes blink {
+
0% {
+
opacity: 1;
+
}
+
50% {
+
opacity: 0;
+
}
+
100% {
+
opacity: 1;
+
}
+
}
+
}
+
+
@layer utilities {
+
.text-error {
+
@apply text-xl text-red-600 text-shadow-red;
+
}
+
+
.border-groove {
+
border-style: groove;
+
}
+
+
.border-ridge {
+
border-style: ridge;
+
}
+
+
.app-grid-background-anim {
+
animation: 4s linear app-grid-move-first-layer infinite;
+
}
+
+
.app-grid-background-second-layer-anim {
+
animation: 12s linear app-grid-move-second-layer infinite;
+
}
+
+
@keyframes app-grid-move-first-layer {
+
0% {
+
background-position: 0px 0px;
+
}
+
100% {
+
background-position: 126px 84px;
+
}
+
}
+
+
@keyframes app-grid-move-second-layer {
+
0% {
+
background-position: 96px 120px;
+
}
+
100% {
+
background-position: 0px 0px;
+
}
+
}
+
+
@media (prefers-reduced-motion: no-preference) {
+
@keyframes bounce-reverse {
+
0%,
+
100% {
+
transform: none;
+
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
+
}
+
50% {
+
transform: translateY(-25%);
+
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
+
}
+
}
+
}
+
@media (prefers-reduced-motion: no-preference) {
+
.animate-bounce-reverse:hover {
+
animation: bounce-reverse 1s infinite;
+
}
+
}
+
}
+
+
a.app-selected-route {
+
text-shadow:
+
0 0 2px theme(colors.ralsei.black),
+
0 0 5px theme(colors.ralsei.pink.regular);
+
}
+
+
.app-grid-background {
+
background-image:
+
linear-gradient(theme(colors.ralsei.green.light / 0.4), transparent 2px),
+
linear-gradient(to right, theme(colors.ralsei.green.light / 0.4), transparent 2px);
+
background-size:
+
100% 42px,
+
42px 100%;
+
}
+
+
.app-grid-background-second-layer {
+
background-image:
+
linear-gradient(theme(colors.ralsei.pink.neon / 0.4), transparent 1px),
+
linear-gradient(to right, theme(colors.ralsei.pink.neon / 0.4), transparent 1px);
+
background-size:
+
100% 24px,
+
24px 100%;
+
}
+
+
@media (prefers-reduced-motion: no-preference) {
+
.animate-window-open {
+
animation: 0.5s ease-out window-open-scale forwards;
+
}
+
+
.animate-window-open-vertical {
+
animation: 0.5s ease-out window-open-scale-vertical forwards;
+
transform-origin: bottom;
+
}
+
+
.animate-window-open-horizontal {
+
animation: 0.5s ease-out window-open-scale-horizontal forwards;
+
transform-origin: left;
+
}
+
+
.animate-window-open-move-up {
+
animation: 0.5s ease-out window-open-move-up forwards;
+
}
+
+
.animate-window-open-move-down {
+
animation: 0.5s ease-out window-open-move-down forwards;
+
}
+
+
.animate-window-open-move-left {
+
animation: 0.5s ease-out window-open-move-left forwards;
+
}
+
+
.animate-window-open-move-right {
+
animation: 0.5s ease-out window-open-move-right forwards;
+
}
+
+
.animate-overflow-keep-hidden {
+
animation: 0.6s linear overflow-keep-hidden forwards;
+
}
+
+
@keyframes window-open-scale {
+
0% {
+
scale: 0;
+
opacity: 0;
+
}
+
20% {
+
scale: 0;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
scale: 1;
+
opacity: 1;
+
}
+
}
+
+
@keyframes window-open-scale-vertical {
+
0% {
+
scale: 1 0;
+
opacity: 0;
+
}
+
20% {
+
scale: 1 0;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
scale: 1 1;
+
opacity: 1;
+
}
+
}
+
+
@keyframes window-open-scale-horizontal {
+
0% {
+
scale: 0 1;
+
opacity: 0;
+
}
+
20% {
+
scale: 0 1;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
scale: 1 1;
+
opacity: 1;
+
}
+
}
+
+
@keyframes window-open-move-down {
+
0% {
+
translate: 0 10rem;
+
opacity: 0;
+
}
+
20% {
+
translate: 0 10rem;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
translate: normal;
+
opacity: 1;
+
}
+
}
+
+
@keyframes window-open-move-up {
+
0% {
+
translate: 0 -10rem;
+
opacity: 0;
+
}
+
20% {
+
translate: 0 -10rem;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
translate: normal;
+
opacity: 1;
+
}
+
}
+
+
@keyframes window-open-move-left {
+
0% {
+
translate: 10rem 0;
+
opacity: 0;
+
}
+
20% {
+
translate: 10rem 0;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
translate: normal;
+
opacity: 1;
+
}
+
}
+
+
@keyframes window-open-move-right {
+
0% {
+
translate: -10rem 0;
+
opacity: 0;
+
}
+
20% {
+
translate: -10rem 0;
+
}
+
60% {
+
opacity: 0.5;
+
}
+
100% {
+
translate: normal;
+
opacity: 1;
+
}
+
}
+
+
@keyframes overflow-keep-hidden {
+
0% {
+
overflow: hidden;
+
}
+
100% {
+
overflow: auto;
+
}
+
}
+
}
+25
eunomia/src/styles/main.css
···
+
@import 'app.css';
+
+
.entry {
+
@apply bg-ralsei-green-dark/70 border-ralsei-green-light/30 border-x-[4px] border-y-[5px];
+
border-style: ridge;
+
}
+
+
details {
+
@apply leading-none mt-2;
+
summary {
+
@apply text-shadow-pink text-ralsei-pink-neon hover:underline;
+
}
+
summary::marker {
+
content: '(+) ';
+
}
+
}
+
details[open] summary::marker {
+
content: '(*) ';
+
}
+
+
.donate ul {
+
li span {
+
@apply font-monospace overflow-hidden text-ellipsis text-nowrap;
+
}
+
}
+140
eunomia/src/styles/prism-synthwave84.css
···
+
/*
+
* Synthwave '84 Theme originally by Robb Owen [@Robb0wen] for Visual Studio Code
+
* Demo: https://marc.dev/demo/prism-synthwave84
+
*
+
* Ported for PrismJS by Marc Backes [@themarcba]
+
*/
+
+
code[class*="language-"],
+
pre[class*="language-"] {
+
color: theme(colors.ralsei.pink.neon);
+
text-shadow: 0 0 2px theme(colors.ralsei.black), 0 0 5px #ff3eb733, 0 0 10px #fff3;
+
@apply bg-ralsei-green-dark;
+
@apply font-monospace;
+
font-size: 1rem;
+
line-height: 1.4rem;
+
text-align: left;
+
white-space: pre;
+
word-spacing: normal;
+
word-break: normal;
+
word-wrap: normal;
+
+
-moz-tab-size: 4;
+
-o-tab-size: 4;
+
tab-size: 4;
+
+
-webkit-hyphens: none;
+
-moz-hyphens: none;
+
-ms-hyphens: none;
+
hyphens: none;
+
}
+
+
/* Code blocks */
+
pre[class*="language-"] {
+
padding: 1em;
+
margin: .5em 0;
+
overflow: auto;
+
}
+
+
/* :not(pre) > code[class*="language-"],
+
pre[class*="language-"] {
+
background-color: transparent !important;
+
background-image: linear-gradient(to bottom, #2a2139 75%, #34294f);
+
} */
+
+
/* Inline code */
+
:not(pre) > code[class*="language-"] {
+
padding: .1em;
+
border-radius: .3em;
+
white-space: normal;
+
}
+
+
.token.comment,
+
.token.block-comment,
+
.token.prolog,
+
.token.doctype,
+
.token.cdata {
+
color: #8e8e8e;
+
}
+
+
.token.punctuation {
+
color: #ccc;
+
}
+
+
.token.tag,
+
.token.attr-name,
+
.token.namespace,
+
.token.number,
+
.token.unit,
+
.token.hexcode,
+
.token.deleted {
+
color: #e2777a;
+
}
+
+
.token.property,
+
.token.selector {
+
color: #72f1b8;
+
text-shadow: 0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475;
+
}
+
+
.token.function-name {
+
color: #6196cc;
+
}
+
+
.token.boolean,
+
.token.selector .token.id,
+
.token.function {
+
color: #fdfdfd;
+
text-shadow: 0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975;
+
}
+
+
.token.class-name {
+
color: #fff5f6;
+
text-shadow: 0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75;
+
}
+
+
.token.constant,
+
.token.symbol {
+
color: #f92aad;
+
text-shadow: 0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3;
+
}
+
+
.token.important,
+
.token.atrule,
+
.token.keyword,
+
.token.selector .token.class,
+
.token.builtin {
+
color: #f4eee4;
+
text-shadow: 0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575;
+
}
+
+
.token.string,
+
.token.char,
+
.token.attr-value,
+
.token.regex,
+
.token.variable {
+
color: #f87c32;
+
}
+
+
.token.operator,
+
.token.entity,
+
.token.url {
+
color: #67cdcc;
+
}
+
+
.token.important,
+
.token.bold {
+
font-weight: bold;
+
}
+
+
.token.italic {
+
font-style: italic;
+
}
+
+
.token.entity {
+
cursor: help;
+
}
+
+
.token.inserted {
+
color: green;
+
}
eunomia/static/88x31.gif

This is a binary file and will not be displayed.

eunomia/static/88x31_midnight.gif

This is a binary file and will not be displayed.

eunomia/static/88x31_sunrise.gif

This is a binary file and will not be displayed.

+1203
eunomia/static/annoy/annoyance-meow.js
···
+
let wasm;
+
+
function isLikeNone(x) {
+
return x === undefined || x === null;
+
}
+
+
function addToExternrefTable0(obj) {
+
const idx = wasm.__externref_table_alloc();
+
wasm.__wbindgen_export_1.set(idx, obj);
+
return idx;
+
}
+
+
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
+
+
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
+
+
let cachedUint8ArrayMemory0 = null;
+
+
function getUint8ArrayMemory0() {
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
+
}
+
return cachedUint8ArrayMemory0;
+
}
+
+
function getStringFromWasm0(ptr, len) {
+
ptr = ptr >>> 0;
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
+
}
+
+
function handleError(f, args) {
+
try {
+
return f.apply(this, args);
+
} catch (e) {
+
const idx = addToExternrefTable0(e);
+
wasm.__wbindgen_exn_store(idx);
+
}
+
}
+
+
let WASM_VECTOR_LEN = 0;
+
+
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
+
+
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
+
? function (arg, view) {
+
return cachedTextEncoder.encodeInto(arg, view);
+
}
+
: function (arg, view) {
+
const buf = cachedTextEncoder.encode(arg);
+
view.set(buf);
+
return {
+
read: arg.length,
+
written: buf.length
+
};
+
});
+
+
function passStringToWasm0(arg, malloc, realloc) {
+
+
if (realloc === undefined) {
+
const buf = cachedTextEncoder.encode(arg);
+
const ptr = malloc(buf.length, 1) >>> 0;
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
+
WASM_VECTOR_LEN = buf.length;
+
return ptr;
+
}
+
+
let len = arg.length;
+
let ptr = malloc(len, 1) >>> 0;
+
+
const mem = getUint8ArrayMemory0();
+
+
let offset = 0;
+
+
for (; offset < len; offset++) {
+
const code = arg.charCodeAt(offset);
+
if (code > 0x7F) break;
+
mem[ptr + offset] = code;
+
}
+
+
if (offset !== len) {
+
if (offset !== 0) {
+
arg = arg.slice(offset);
+
}
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
+
const ret = encodeString(arg, view);
+
+
offset += ret.written;
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
+
}
+
+
WASM_VECTOR_LEN = offset;
+
return ptr;
+
}
+
+
let cachedDataViewMemory0 = null;
+
+
function getDataViewMemory0() {
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
+
}
+
return cachedDataViewMemory0;
+
}
+
+
let cachedUint8ClampedArrayMemory0 = null;
+
+
function getUint8ClampedArrayMemory0() {
+
if (cachedUint8ClampedArrayMemory0 === null || cachedUint8ClampedArrayMemory0.byteLength === 0) {
+
cachedUint8ClampedArrayMemory0 = new Uint8ClampedArray(wasm.memory.buffer);
+
}
+
return cachedUint8ClampedArrayMemory0;
+
}
+
+
function getClampedArrayU8FromWasm0(ptr, len) {
+
ptr = ptr >>> 0;
+
return getUint8ClampedArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
+
}
+
+
function getArrayU8FromWasm0(ptr, len) {
+
ptr = ptr >>> 0;
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
+
}
+
+
const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')
+
? { register: () => {}, unregister: () => {} }
+
: new FinalizationRegistry(state => {
+
wasm.__wbindgen_export_6.get(state.dtor)(state.a, state.b)
+
});
+
+
function makeMutClosure(arg0, arg1, dtor, f) {
+
const state = { a: arg0, b: arg1, cnt: 1, dtor };
+
const real = (...args) => {
+
// First up with a closure we increment the internal reference
+
// count. This ensures that the Rust closure environment won't
+
// be deallocated while we're invoking it.
+
state.cnt++;
+
const a = state.a;
+
state.a = 0;
+
try {
+
return f(a, state.b, ...args);
+
} finally {
+
if (--state.cnt === 0) {
+
wasm.__wbindgen_export_6.get(state.dtor)(a, state.b);
+
CLOSURE_DTORS.unregister(state);
+
} else {
+
state.a = a;
+
}
+
}
+
};
+
real.original = state;
+
CLOSURE_DTORS.register(real, state, state);
+
return real;
+
}
+
+
function debugString(val) {
+
// primitive types
+
const type = typeof val;
+
if (type == 'number' || type == 'boolean' || val == null) {
+
return `${val}`;
+
}
+
if (type == 'string') {
+
return `"${val}"`;
+
}
+
if (type == 'symbol') {
+
const description = val.description;
+
if (description == null) {
+
return 'Symbol';
+
} else {
+
return `Symbol(${description})`;
+
}
+
}
+
if (type == 'function') {
+
const name = val.name;
+
if (typeof name == 'string' && name.length > 0) {
+
return `Function(${name})`;
+
} else {
+
return 'Function';
+
}
+
}
+
// objects
+
if (Array.isArray(val)) {
+
const length = val.length;
+
let debug = '[';
+
if (length > 0) {
+
debug += debugString(val[0]);
+
}
+
for(let i = 1; i < length; i++) {
+
debug += ', ' + debugString(val[i]);
+
}
+
debug += ']';
+
return debug;
+
}
+
// Test for built-in
+
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
+
let className;
+
if (builtInMatches && builtInMatches.length > 1) {
+
className = builtInMatches[1];
+
} else {
+
// Failed to match the standard '[object ClassName]'
+
return toString.call(val);
+
}
+
if (className == 'Object') {
+
// we're a user defined class or Object
+
// JSON.stringify avoids problems with cycles, and is generally much
+
// easier than looping through ownProperties of `val`.
+
try {
+
return 'Object(' + JSON.stringify(val) + ')';
+
} catch (_) {
+
return 'Object';
+
}
+
}
+
// errors
+
if (val instanceof Error) {
+
return `${val.name}: ${val.message}\n${val.stack}`;
+
}
+
// TODO we could test for more things here, like `Set`s and `Map`s.
+
return className;
+
}
+
function __wbg_adapter_30(arg0, arg1, arg2) {
+
wasm.closure3_externref_shim(arg0, arg1, arg2);
+
}
+
+
function __wbg_adapter_51(arg0, arg1, arg2, arg3) {
+
wasm.closure105_externref_shim(arg0, arg1, arg2, arg3);
+
}
+
+
function __wbg_adapter_56(arg0, arg1) {
+
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb7d4ca77f39188b4(arg0, arg1);
+
}
+
+
const __wbindgen_enum_BinaryType = ["blob", "arraybuffer"];
+
+
const __wbindgen_enum_ResizeObserverBoxOptions = ["border-box", "content-box", "device-pixel-content-box"];
+
+
const __wbindgen_enum_VisibilityState = ["hidden", "visible"];
+
+
async function __wbg_load(module, imports) {
+
if (typeof Response === 'function' && module instanceof Response) {
+
if (typeof WebAssembly.instantiateStreaming === 'function') {
+
try {
+
return await WebAssembly.instantiateStreaming(module, imports);
+
+
} catch (e) {
+
if (module.headers.get('Content-Type') != 'application/wasm') {
+
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
+
+
} else {
+
throw e;
+
}
+
}
+
}
+
+
const bytes = await module.arrayBuffer();
+
return await WebAssembly.instantiate(bytes, imports);
+
+
} else {
+
const instance = await WebAssembly.instantiate(module, imports);
+
+
if (instance instanceof WebAssembly.Instance) {
+
return { instance, module };
+
+
} else {
+
return instance;
+
}
+
}
+
}
+
+
function __wbg_get_imports() {
+
const imports = {};
+
imports.wbg = {};
+
imports.wbg.__wbg_Window_d1bf622f71ff0629 = function(arg0) {
+
const ret = arg0.Window;
+
return ret;
+
};
+
imports.wbg.__wbg_abort_775ef1d17fc65868 = function(arg0) {
+
arg0.abort();
+
};
+
imports.wbg.__wbg_activeElement_367599fdfa7ad115 = function(arg0) {
+
const ret = arg0.activeElement;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_addEventListener_90e553fdce254421 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
+
arg0.addEventListener(getStringFromWasm0(arg1, arg2), arg3);
+
}, arguments) };
+
imports.wbg.__wbg_addListener_2982bb811b6385c5 = function() { return handleError(function (arg0, arg1) {
+
arg0.addListener(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_altKey_c33c03aed82e4275 = function(arg0) {
+
const ret = arg0.altKey;
+
return ret;
+
};
+
imports.wbg.__wbg_altKey_d7495666df921121 = function(arg0) {
+
const ret = arg0.altKey;
+
return ret;
+
};
+
imports.wbg.__wbg_animate_6ec571f163cf6f8d = function(arg0, arg1, arg2) {
+
const ret = arg0.animate(arg1, arg2);
+
return ret;
+
};
+
imports.wbg.__wbg_appendChild_8204974b7328bf98 = function() { return handleError(function (arg0, arg1) {
+
const ret = arg0.appendChild(arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_blockSize_1490803190b57a34 = function(arg0) {
+
const ret = arg0.blockSize;
+
return ret;
+
};
+
imports.wbg.__wbg_body_942ea927546a04ba = function(arg0) {
+
const ret = arg0.body;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_brand_9562792cbb4735c3 = function(arg0, arg1) {
+
const ret = arg1.brand;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbg_brands_a1e7a2bce052128f = function(arg0) {
+
const ret = arg0.brands;
+
return ret;
+
};
+
imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) {
+
const ret = arg0.buffer;
+
return ret;
+
};
+
imports.wbg.__wbg_button_f75c56aec440ea04 = function(arg0) {
+
const ret = arg0.button;
+
return ret;
+
};
+
imports.wbg.__wbg_buttons_b6346af6f04e4686 = function(arg0) {
+
const ret = arg0.buttons;
+
return ret;
+
};
+
imports.wbg.__wbg_call_672a4d21634d4a24 = function() { return handleError(function (arg0, arg1) {
+
const ret = arg0.call(arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_call_7cccdd69e0791ae2 = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = arg0.call(arg1, arg2);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_cancelAnimationFrame_089b48301c362fde = function() { return handleError(function (arg0, arg1) {
+
arg0.cancelAnimationFrame(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_cancelIdleCallback_669eb1ed294c8b8b = function(arg0, arg1) {
+
arg0.cancelIdleCallback(arg1 >>> 0);
+
};
+
imports.wbg.__wbg_cancel_09c394f0894744eb = function(arg0) {
+
arg0.cancel();
+
};
+
imports.wbg.__wbg_catch_a6e601879b2610e9 = function(arg0, arg1) {
+
const ret = arg0.catch(arg1);
+
return ret;
+
};
+
imports.wbg.__wbg_clearTimeout_b2651b7485c58446 = function(arg0, arg1) {
+
arg0.clearTimeout(arg1);
+
};
+
imports.wbg.__wbg_clientHeight_216178c194000db4 = function(arg0) {
+
const ret = arg0.clientHeight;
+
return ret;
+
};
+
imports.wbg.__wbg_clientWidth_ce67a04dc15fce39 = function(arg0) {
+
const ret = arg0.clientWidth;
+
return ret;
+
};
+
imports.wbg.__wbg_close_2893b7d056a0627d = function() { return handleError(function (arg0) {
+
arg0.close();
+
}, arguments) };
+
imports.wbg.__wbg_close_414b379454494b29 = function(arg0) {
+
arg0.close();
+
};
+
imports.wbg.__wbg_close_e1253d480ed93ce3 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
+
arg0.close(arg1, getStringFromWasm0(arg2, arg3));
+
}, arguments) };
+
imports.wbg.__wbg_code_459c120478e1ab6e = function(arg0, arg1) {
+
const ret = arg1.code;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbg_code_f4ec1e6e2e1b0417 = function(arg0) {
+
const ret = arg0.code;
+
return ret;
+
};
+
imports.wbg.__wbg_contains_3361c7eda6c95afd = function(arg0, arg1) {
+
const ret = arg0.contains(arg1);
+
return ret;
+
};
+
imports.wbg.__wbg_contentRect_81407eb60e52248f = function(arg0) {
+
const ret = arg0.contentRect;
+
return ret;
+
};
+
imports.wbg.__wbg_createElement_8c9931a732ee2fea = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = arg0.createElement(getStringFromWasm0(arg1, arg2));
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_createObjectURL_6e98d2f9c7bd9764 = function() { return handleError(function (arg0, arg1) {
+
const ret = URL.createObjectURL(arg1);
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
}, arguments) };
+
imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) {
+
const ret = arg0.crypto;
+
return ret;
+
};
+
imports.wbg.__wbg_ctrlKey_1e826e468105ac11 = function(arg0) {
+
const ret = arg0.ctrlKey;
+
return ret;
+
};
+
imports.wbg.__wbg_ctrlKey_cdbe8154dfb00d1f = function(arg0) {
+
const ret = arg0.ctrlKey;
+
return ret;
+
};
+
imports.wbg.__wbg_data_432d9c3df2630942 = function(arg0) {
+
const ret = arg0.data;
+
return ret;
+
};
+
imports.wbg.__wbg_deltaMode_9bfd9fe3f6b4b240 = function(arg0) {
+
const ret = arg0.deltaMode;
+
return ret;
+
};
+
imports.wbg.__wbg_deltaX_5c1121715746e4b7 = function(arg0) {
+
const ret = arg0.deltaX;
+
return ret;
+
};
+
imports.wbg.__wbg_deltaY_f9318542caea0c36 = function(arg0) {
+
const ret = arg0.deltaY;
+
return ret;
+
};
+
imports.wbg.__wbg_devicePixelContentBoxSize_a6de82cb30d70825 = function(arg0) {
+
const ret = arg0.devicePixelContentBoxSize;
+
return ret;
+
};
+
imports.wbg.__wbg_devicePixelRatio_68c391265f05d093 = function(arg0) {
+
const ret = arg0.devicePixelRatio;
+
return ret;
+
};
+
imports.wbg.__wbg_disconnect_2118016d75479985 = function(arg0) {
+
arg0.disconnect();
+
};
+
imports.wbg.__wbg_disconnect_ac3f4ba550970c76 = function(arg0) {
+
arg0.disconnect();
+
};
+
imports.wbg.__wbg_document_d249400bd7bd996d = function(arg0) {
+
const ret = arg0.document;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_error_1004b8c64097413f = function(arg0, arg1) {
+
console.error(arg0, arg1);
+
};
+
imports.wbg.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
+
let deferred0_0;
+
let deferred0_1;
+
try {
+
deferred0_0 = arg0;
+
deferred0_1 = arg1;
+
console.error(getStringFromWasm0(arg0, arg1));
+
} finally {
+
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
+
}
+
};
+
imports.wbg.__wbg_focus_7d08b55eba7b368d = function() { return handleError(function (arg0) {
+
arg0.focus();
+
}, arguments) };
+
imports.wbg.__wbg_fullscreenElement_a2f691b04c3b3de5 = function(arg0) {
+
const ret = arg0.fullscreenElement;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_getCoalescedEvents_21492912fd0145ec = function(arg0) {
+
const ret = arg0.getCoalescedEvents;
+
return ret;
+
};
+
imports.wbg.__wbg_getCoalescedEvents_a7d49de30111f6b8 = function(arg0) {
+
const ret = arg0.getCoalescedEvents();
+
return ret;
+
};
+
imports.wbg.__wbg_getComputedStyle_046dd6472f8e7f1d = function() { return handleError(function (arg0, arg1) {
+
const ret = arg0.getComputedStyle(arg1);
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
}, arguments) };
+
imports.wbg.__wbg_getContext_e9cf379449413580 = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = arg0.getContext(getStringFromWasm0(arg1, arg2));
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
}, arguments) };
+
imports.wbg.__wbg_getOwnPropertyDescriptor_9dd936a3c0cbd368 = function(arg0, arg1) {
+
const ret = Object.getOwnPropertyDescriptor(arg0, arg1);
+
return ret;
+
};
+
imports.wbg.__wbg_getPropertyValue_e623c23a05dfb30c = function() { return handleError(function (arg0, arg1, arg2, arg3) {
+
const ret = arg1.getPropertyValue(getStringFromWasm0(arg2, arg3));
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
}, arguments) };
+
imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
+
arg0.getRandomValues(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_get_67b2ba62fc30de12 = function() { return handleError(function (arg0, arg1) {
+
const ret = Reflect.get(arg0, arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_get_b9b93047fe3cf45b = function(arg0, arg1) {
+
const ret = arg0[arg1 >>> 0];
+
return ret;
+
};
+
imports.wbg.__wbg_height_1f8226c8f6875110 = function(arg0) {
+
const ret = arg0.height;
+
return ret;
+
};
+
imports.wbg.__wbg_inlineSize_8ff96b3ec1b24423 = function(arg0) {
+
const ret = arg0.inlineSize;
+
return ret;
+
};
+
imports.wbg.__wbg_instanceof_ArrayBuffer_e14585432e3737fc = function(arg0) {
+
let result;
+
try {
+
result = arg0 instanceof ArrayBuffer;
+
} catch (_) {
+
result = false;
+
}
+
const ret = result;
+
return ret;
+
};
+
imports.wbg.__wbg_instanceof_Blob_ca721ef3bdab15d1 = function(arg0) {
+
let result;
+
try {
+
result = arg0 instanceof Blob;
+
} catch (_) {
+
result = false;
+
}
+
const ret = result;
+
return ret;
+
};
+
imports.wbg.__wbg_instanceof_CanvasRenderingContext2d_df82a4d3437bf1cc = function(arg0) {
+
let result;
+
try {
+
result = arg0 instanceof CanvasRenderingContext2D;
+
} catch (_) {
+
result = false;
+
}
+
const ret = result;
+
return ret;
+
};
+
imports.wbg.__wbg_instanceof_Performance_0ac1286c87171f57 = function(arg0) {
+
let result;
+
try {
+
result = arg0 instanceof Performance;
+
} catch (_) {
+
result = false;
+
}
+
const ret = result;
+
return ret;
+
};
+
imports.wbg.__wbg_instanceof_Window_def73ea0955fc569 = function(arg0) {
+
let result;
+
try {
+
result = arg0 instanceof Window;
+
} catch (_) {
+
result = false;
+
}
+
const ret = result;
+
return ret;
+
};
+
imports.wbg.__wbg_isIntersecting_e68706dac9c5f2e9 = function(arg0) {
+
const ret = arg0.isIntersecting;
+
return ret;
+
};
+
imports.wbg.__wbg_is_c7481c65e7e5df9e = function(arg0, arg1) {
+
const ret = Object.is(arg0, arg1);
+
return ret;
+
};
+
imports.wbg.__wbg_key_7b5c6cb539be8e13 = function(arg0, arg1) {
+
const ret = arg1.key;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbg_length_a446193dc22c12f8 = function(arg0) {
+
const ret = arg0.length;
+
return ret;
+
};
+
imports.wbg.__wbg_length_e2d2a49132c1b256 = function(arg0) {
+
const ret = arg0.length;
+
return ret;
+
};
+
imports.wbg.__wbg_location_9b435486be8f98c2 = function(arg0) {
+
const ret = arg0.location;
+
return ret;
+
};
+
imports.wbg.__wbg_matchMedia_bf8807a841d930c1 = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = arg0.matchMedia(getStringFromWasm0(arg1, arg2));
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
}, arguments) };
+
imports.wbg.__wbg_matches_e9ca73fbf8a3a104 = function(arg0) {
+
const ret = arg0.matches;
+
return ret;
+
};
+
imports.wbg.__wbg_metaKey_0b25f7848e014cc8 = function(arg0) {
+
const ret = arg0.metaKey;
+
return ret;
+
};
+
imports.wbg.__wbg_metaKey_e1dd47d709a80ce5 = function(arg0) {
+
const ret = arg0.metaKey;
+
return ret;
+
};
+
imports.wbg.__wbg_movementX_1aa05f864931369b = function(arg0) {
+
const ret = arg0.movementX;
+
return ret;
+
};
+
imports.wbg.__wbg_movementY_8acfedb38a70e624 = function(arg0) {
+
const ret = arg0.movementY;
+
return ret;
+
};
+
imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {
+
const ret = arg0.msCrypto;
+
return ret;
+
};
+
imports.wbg.__wbg_navigator_1577371c070c8947 = function(arg0) {
+
const ret = arg0.navigator;
+
return ret;
+
};
+
imports.wbg.__wbg_new_18b1151f3a6a9280 = function() { return handleError(function (arg0) {
+
const ret = new IntersectionObserver(arg0);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_new_24b2c5b645cded8d = function() { return handleError(function () {
+
const ret = new MessageChannel();
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_new_405e22f390576ce2 = function() {
+
const ret = new Object();
+
return ret;
+
};
+
imports.wbg.__wbg_new_5f34cc0c99fcc488 = function() { return handleError(function (arg0) {
+
const ret = new ResizeObserver(arg0);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_new_8a6f238a6ece86ea = function() {
+
const ret = new Error();
+
return ret;
+
};
+
imports.wbg.__wbg_new_92c54fc74574ef55 = function() { return handleError(function (arg0, arg1) {
+
const ret = new WebSocket(getStringFromWasm0(arg0, arg1));
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_new_a12002a7f91c75be = function(arg0) {
+
const ret = new Uint8Array(arg0);
+
return ret;
+
};
+
imports.wbg.__wbg_new_b1a33e5095abf678 = function() { return handleError(function (arg0, arg1) {
+
const ret = new Worker(getStringFromWasm0(arg0, arg1));
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_new_e25e5aab09ff45db = function() { return handleError(function () {
+
const ret = new AbortController();
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_newnoargs_105ed471475aaf50 = function(arg0, arg1) {
+
const ret = new Function(getStringFromWasm0(arg0, arg1));
+
return ret;
+
};
+
imports.wbg.__wbg_newwithbyteoffsetandlength_d97e637ebe145a9a = function(arg0, arg1, arg2) {
+
const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0);
+
return ret;
+
};
+
imports.wbg.__wbg_newwithlength_a381634e90c276d4 = function(arg0) {
+
const ret = new Uint8Array(arg0 >>> 0);
+
return ret;
+
};
+
imports.wbg.__wbg_newwithstrsequenceandoptions_aaff55b467c81b63 = function() { return handleError(function (arg0, arg1) {
+
const ret = new Blob(arg0, arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_newwithu8clampedarray_0fcf78a036c89a97 = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = new ImageData(getClampedArrayU8FromWasm0(arg0, arg1), arg2 >>> 0);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {
+
const ret = arg0.node;
+
return ret;
+
};
+
imports.wbg.__wbg_now_2c95c9de01293173 = function(arg0) {
+
const ret = arg0.now();
+
return ret;
+
};
+
imports.wbg.__wbg_now_d18023d54d4e5500 = function(arg0) {
+
const ret = arg0.now();
+
return ret;
+
};
+
imports.wbg.__wbg_observe_d2e7378f15f7ca72 = function(arg0, arg1) {
+
arg0.observe(arg1);
+
};
+
imports.wbg.__wbg_observe_eafddfc5a0c60e02 = function(arg0, arg1) {
+
arg0.observe(arg1);
+
};
+
imports.wbg.__wbg_observe_ed4adb1c245103c5 = function(arg0, arg1, arg2) {
+
arg0.observe(arg1, arg2);
+
};
+
imports.wbg.__wbg_of_2eaf5a02d443ef03 = function(arg0) {
+
const ret = Array.of(arg0);
+
return ret;
+
};
+
imports.wbg.__wbg_of_66b3ee656cbd962b = function(arg0, arg1) {
+
const ret = Array.of(arg0, arg1);
+
return ret;
+
};
+
imports.wbg.__wbg_offsetX_cb6a38e6f23cb4a6 = function(arg0) {
+
const ret = arg0.offsetX;
+
return ret;
+
};
+
imports.wbg.__wbg_offsetY_43e21941c5c1f8bf = function(arg0) {
+
const ret = arg0.offsetY;
+
return ret;
+
};
+
imports.wbg.__wbg_performance_7a3ffd0b17f663ad = function(arg0) {
+
const ret = arg0.performance;
+
return ret;
+
};
+
imports.wbg.__wbg_persisted_d32ce73b8e522062 = function(arg0) {
+
const ret = arg0.persisted;
+
return ret;
+
};
+
imports.wbg.__wbg_play_63bc12f42e16af91 = function(arg0) {
+
arg0.play();
+
};
+
imports.wbg.__wbg_pointerId_585e63ee80a49927 = function(arg0) {
+
const ret = arg0.pointerId;
+
return ret;
+
};
+
imports.wbg.__wbg_pointerType_6bd934aa20d9db49 = function(arg0, arg1) {
+
const ret = arg1.pointerType;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbg_port1_70af0ea6e4a96f9d = function(arg0) {
+
const ret = arg0.port1;
+
return ret;
+
};
+
imports.wbg.__wbg_port2_0584c7f0938b6fe6 = function(arg0) {
+
const ret = arg0.port2;
+
return ret;
+
};
+
imports.wbg.__wbg_postMessage_e55d059efb191dc5 = function() { return handleError(function (arg0, arg1) {
+
arg0.postMessage(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_postMessage_f961e53b9731ca83 = function() { return handleError(function (arg0, arg1, arg2) {
+
arg0.postMessage(arg1, arg2);
+
}, arguments) };
+
imports.wbg.__wbg_postTask_41d93e93941e4a3d = function(arg0, arg1, arg2) {
+
const ret = arg0.postTask(arg1, arg2);
+
return ret;
+
};
+
imports.wbg.__wbg_pressure_adda5a83a9cec94d = function(arg0) {
+
const ret = arg0.pressure;
+
return ret;
+
};
+
imports.wbg.__wbg_preventDefault_c2314fd813c02b3c = function(arg0) {
+
arg0.preventDefault();
+
};
+
imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {
+
const ret = arg0.process;
+
return ret;
+
};
+
imports.wbg.__wbg_prototype_c28bca39c45aba9b = function() {
+
const ret = ResizeObserverEntry.prototype;
+
return ret;
+
};
+
imports.wbg.__wbg_putImageData_2acd1dcd88a80f79 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
+
arg0.putImageData(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+
}, arguments) };
+
imports.wbg.__wbg_putImageData_416b1a6d50843b66 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
+
arg0.putImageData(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+
}, arguments) };
+
imports.wbg.__wbg_queueMicrotask_65a6c48ee9790d40 = function(arg0, arg1) {
+
arg0.queueMicrotask(arg1);
+
};
+
imports.wbg.__wbg_queueMicrotask_97d92b4fcc8a61c5 = function(arg0) {
+
queueMicrotask(arg0);
+
};
+
imports.wbg.__wbg_queueMicrotask_d3219def82552485 = function(arg0) {
+
const ret = arg0.queueMicrotask;
+
return ret;
+
};
+
imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {
+
arg0.randomFillSync(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_readyState_7ef6e63c349899ed = function(arg0) {
+
const ret = arg0.readyState;
+
return ret;
+
};
+
imports.wbg.__wbg_reason_49f1cede8bcf23dd = function(arg0, arg1) {
+
const ret = arg1.reason;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbg_removeEventListener_056dfe8c3d6c58f9 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
+
arg0.removeEventListener(getStringFromWasm0(arg1, arg2), arg3);
+
}, arguments) };
+
imports.wbg.__wbg_removeListener_e55db581b73ccf65 = function() { return handleError(function (arg0, arg1) {
+
arg0.removeListener(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_removeProperty_0e85471f4dfc00ae = function() { return handleError(function (arg0, arg1, arg2, arg3) {
+
const ret = arg1.removeProperty(getStringFromWasm0(arg2, arg3));
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
}, arguments) };
+
imports.wbg.__wbg_repeat_1882aa0d0072c705 = function(arg0) {
+
const ret = arg0.repeat;
+
return ret;
+
};
+
imports.wbg.__wbg_requestAnimationFrame_d7fd890aaefc3246 = function() { return handleError(function (arg0, arg1) {
+
const ret = arg0.requestAnimationFrame(arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_requestFullscreen_86fc6cdb76000482 = function(arg0) {
+
const ret = arg0.requestFullscreen;
+
return ret;
+
};
+
imports.wbg.__wbg_requestFullscreen_9f0611438eb929cf = function(arg0) {
+
const ret = arg0.requestFullscreen();
+
return ret;
+
};
+
imports.wbg.__wbg_requestIdleCallback_1b8d644ff564208f = function(arg0) {
+
const ret = arg0.requestIdleCallback;
+
return ret;
+
};
+
imports.wbg.__wbg_requestIdleCallback_e3eefd34962470e1 = function() { return handleError(function (arg0, arg1) {
+
const ret = arg0.requestIdleCallback(arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {
+
const ret = module.require;
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_resolve_4851785c9c5f573d = function(arg0) {
+
const ret = Promise.resolve(arg0);
+
return ret;
+
};
+
imports.wbg.__wbg_revokeObjectURL_27267efebeb457c7 = function() { return handleError(function (arg0, arg1) {
+
URL.revokeObjectURL(getStringFromWasm0(arg0, arg1));
+
}, arguments) };
+
imports.wbg.__wbg_scheduler_48482a9974eeacbd = function(arg0) {
+
const ret = arg0.scheduler;
+
return ret;
+
};
+
imports.wbg.__wbg_scheduler_5156bb61cc1cf589 = function(arg0) {
+
const ret = arg0.scheduler;
+
return ret;
+
};
+
imports.wbg.__wbg_send_0293179ba074ffb4 = function() { return handleError(function (arg0, arg1, arg2) {
+
arg0.send(getStringFromWasm0(arg1, arg2));
+
}, arguments) };
+
imports.wbg.__wbg_send_fc0c204e8a1757f4 = function() { return handleError(function (arg0, arg1, arg2) {
+
arg0.send(getArrayU8FromWasm0(arg1, arg2));
+
}, arguments) };
+
imports.wbg.__wbg_setAttribute_2704501201f15687 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
+
arg0.setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
+
}, arguments) };
+
imports.wbg.__wbg_setPointerCapture_c04dafaf4d00ffad = function() { return handleError(function (arg0, arg1) {
+
arg0.setPointerCapture(arg1);
+
}, arguments) };
+
imports.wbg.__wbg_setProperty_f2cf326652b9a713 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
+
arg0.setProperty(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
+
}, arguments) };
+
imports.wbg.__wbg_setTimeout_461fec76662b35ea = function() { return handleError(function (arg0, arg1) {
+
const ret = arg0.setTimeout(arg1);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_setTimeout_f2fe5af8e3debeb3 = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = arg0.setTimeout(arg1, arg2);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) {
+
arg0.set(arg1, arg2 >>> 0);
+
};
+
imports.wbg.__wbg_set_bb8cecf6a62b9f46 = function() { return handleError(function (arg0, arg1, arg2) {
+
const ret = Reflect.set(arg0, arg1, arg2);
+
return ret;
+
}, arguments) };
+
imports.wbg.__wbg_setbinaryType_92fa1ffd873b327c = function(arg0, arg1) {
+
arg0.binaryType = __wbindgen_enum_BinaryType[arg1];
+
};
+
imports.wbg.__wbg_setbox_2786f3ccea97cac4 = function(arg0, arg1) {
+
arg0.box = __wbindgen_enum_ResizeObserverBoxOptions[arg1];
+
};
+
imports.wbg.__wbg_setheight_433680330c9420c3 = function(arg0, arg1) {
+
arg0.height = arg1 >>> 0;
+
};
+
imports.wbg.__wbg_setheight_da683a33fa99843c = function(arg0, arg1) {
+
arg0.height = arg1 >>> 0;
+
};
+
imports.wbg.__wbg_setonclose_14fc475a49d488fc = function(arg0, arg1) {
+
arg0.onclose = arg1;
+
};
+
imports.wbg.__wbg_setonerror_8639efe354b947cd = function(arg0, arg1) {
+
arg0.onerror = arg1;
+
};
+
imports.wbg.__wbg_setonmessage_23d122da701b8ddb = function(arg0, arg1) {
+
arg0.onmessage = arg1;
+
};
+
imports.wbg.__wbg_setonmessage_6eccab530a8fb4c7 = function(arg0, arg1) {
+
arg0.onmessage = arg1;
+
};
+
imports.wbg.__wbg_setonopen_2da654e1f39745d5 = function(arg0, arg1) {
+
arg0.onopen = arg1;
+
};
+
imports.wbg.__wbg_settype_39ed370d3edd403c = function(arg0, arg1, arg2) {
+
arg0.type = getStringFromWasm0(arg1, arg2);
+
};
+
imports.wbg.__wbg_setwidth_660ca581e3fbe279 = function(arg0, arg1) {
+
arg0.width = arg1 >>> 0;
+
};
+
imports.wbg.__wbg_setwidth_c5fed9f5e7f0b406 = function(arg0, arg1) {
+
arg0.width = arg1 >>> 0;
+
};
+
imports.wbg.__wbg_shiftKey_2bebb3b703254f47 = function(arg0) {
+
const ret = arg0.shiftKey;
+
return ret;
+
};
+
imports.wbg.__wbg_shiftKey_86e737105bab1a54 = function(arg0) {
+
const ret = arg0.shiftKey;
+
return ret;
+
};
+
imports.wbg.__wbg_signal_aaf9ad74119f20a4 = function(arg0) {
+
const ret = arg0.signal;
+
return ret;
+
};
+
imports.wbg.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
+
const ret = arg1.stack;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbg_start_2c099369ce831bf1 = function(arg0) {
+
arg0.start();
+
};
+
imports.wbg.__wbg_static_accessor_GLOBAL_88a902d13a557d07 = function() {
+
const ret = typeof global === 'undefined' ? null : global;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_static_accessor_GLOBAL_THIS_56578be7e9f832b0 = function() {
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_static_accessor_SELF_37c5d418e4bf5819 = function() {
+
const ret = typeof self === 'undefined' ? null : self;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_static_accessor_WINDOW_5de37043a91a9c40 = function() {
+
const ret = typeof window === 'undefined' ? null : window;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_style_fb30c14e5815805c = function(arg0) {
+
const ret = arg0.style;
+
return ret;
+
};
+
imports.wbg.__wbg_subarray_aa9065fa9dc5df96 = function(arg0, arg1, arg2) {
+
const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
+
return ret;
+
};
+
imports.wbg.__wbg_then_44b73946d2fb3e7d = function(arg0, arg1) {
+
const ret = arg0.then(arg1);
+
return ret;
+
};
+
imports.wbg.__wbg_unobserve_02f53d1ca2d1d801 = function(arg0, arg1) {
+
arg0.unobserve(arg1);
+
};
+
imports.wbg.__wbg_userAgentData_f7b0e61c05c54315 = function(arg0) {
+
const ret = arg0.userAgentData;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_userAgent_12e9d8e62297563f = function() { return handleError(function (arg0, arg1) {
+
const ret = arg1.userAgent;
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
}, arguments) };
+
imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {
+
const ret = arg0.versions;
+
return ret;
+
};
+
imports.wbg.__wbg_visibilityState_f3cc18a6f3831137 = function(arg0) {
+
const ret = arg0.visibilityState;
+
return (__wbindgen_enum_VisibilityState.indexOf(ret) + 1 || 3) - 1;
+
};
+
imports.wbg.__wbg_webkitFullscreenElement_a9ca38b7214d1567 = function(arg0) {
+
const ret = arg0.webkitFullscreenElement;
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
+
};
+
imports.wbg.__wbg_webkitRequestFullscreen_23664c63833ff0e5 = function(arg0) {
+
arg0.webkitRequestFullscreen();
+
};
+
imports.wbg.__wbg_width_cdaf02311c1621d1 = function(arg0) {
+
const ret = arg0.width;
+
return ret;
+
};
+
imports.wbg.__wbindgen_cb_drop = function(arg0) {
+
const obj = arg0.original;
+
if (obj.cnt-- == 1) {
+
obj.a = 0;
+
return true;
+
}
+
const ret = false;
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper1511 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper207 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper209 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper211 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper2187 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper2189 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_51);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper2194 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper2197 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_56);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper451 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper477 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper479 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper481 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_closure_wrapper482 = function(arg0, arg1, arg2) {
+
const ret = makeMutClosure(arg0, arg1, 4, __wbg_adapter_30);
+
return ret;
+
};
+
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
+
const ret = debugString(arg1);
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
const len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbindgen_init_externref_table = function() {
+
const table = wasm.__wbindgen_export_1;
+
const offset = table.grow(4);
+
table.set(0, undefined);
+
table.set(offset + 0, undefined);
+
table.set(offset + 1, null);
+
table.set(offset + 2, true);
+
table.set(offset + 3, false);
+
;
+
};
+
imports.wbg.__wbindgen_is_function = function(arg0) {
+
const ret = typeof(arg0) === 'function';
+
return ret;
+
};
+
imports.wbg.__wbindgen_is_object = function(arg0) {
+
const val = arg0;
+
const ret = typeof(val) === 'object' && val !== null;
+
return ret;
+
};
+
imports.wbg.__wbindgen_is_string = function(arg0) {
+
const ret = typeof(arg0) === 'string';
+
return ret;
+
};
+
imports.wbg.__wbindgen_is_undefined = function(arg0) {
+
const ret = arg0 === undefined;
+
return ret;
+
};
+
imports.wbg.__wbindgen_memory = function() {
+
const ret = wasm.memory;
+
return ret;
+
};
+
imports.wbg.__wbindgen_number_new = function(arg0) {
+
const ret = arg0;
+
return ret;
+
};
+
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
+
const obj = arg1;
+
const ret = typeof(obj) === 'string' ? obj : undefined;
+
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
+
var len1 = WASM_VECTOR_LEN;
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
+
};
+
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
+
const ret = getStringFromWasm0(arg0, arg1);
+
return ret;
+
};
+
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
+
throw new Error(getStringFromWasm0(arg0, arg1));
+
};
+
+
return imports;
+
}
+
+
function __wbg_init_memory(imports, memory) {
+
+
}
+
+
function __wbg_finalize_init(instance, module) {
+
wasm = instance.exports;
+
__wbg_init.__wbindgen_wasm_module = module;
+
cachedDataViewMemory0 = null;
+
cachedUint8ArrayMemory0 = null;
+
cachedUint8ClampedArrayMemory0 = null;
+
+
+
wasm.__wbindgen_start();
+
return wasm;
+
}
+
+
function initSync(module) {
+
if (wasm !== undefined) return wasm;
+
+
+
if (typeof module !== 'undefined') {
+
if (Object.getPrototypeOf(module) === Object.prototype) {
+
({module} = module)
+
} else {
+
console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
+
}
+
}
+
+
const imports = __wbg_get_imports();
+
+
__wbg_init_memory(imports);
+
+
if (!(module instanceof WebAssembly.Module)) {
+
module = new WebAssembly.Module(module);
+
}
+
+
const instance = new WebAssembly.Instance(module, imports);
+
+
return __wbg_finalize_init(instance, module);
+
}
+
+
async function __wbg_init(module_or_path) {
+
if (wasm !== undefined) return wasm;
+
+
+
if (typeof module_or_path !== 'undefined') {
+
if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
+
({module_or_path} = module_or_path)
+
} else {
+
console.warn('using deprecated parameters for the initialization function; pass a single object instead')
+
}
+
}
+
+
if (typeof module_or_path === 'undefined') {
+
module_or_path = new URL('annoyance-meow_bg.wasm', import.meta.url);
+
}
+
const imports = __wbg_get_imports();
+
+
if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
+
module_or_path = fetch(module_or_path);
+
}
+
+
__wbg_init_memory(imports);
+
+
const { instance, module } = await __wbg_load(await module_or_path, imports);
+
+
return __wbg_finalize_init(instance, module);
+
}
+
+
export { initSync };
+
export default __wbg_init;
eunomia/static/annoy/annoyance-meow_bg.wasm

This is a binary file and will not be displayed.

eunomia/static/banners/1.gif

This is a binary file and will not be displayed.

eunomia/static/banners/10.gif

This is a binary file and will not be displayed.

eunomia/static/banners/11.gif

This is a binary file and will not be displayed.

eunomia/static/banners/12.gif

This is a binary file and will not be displayed.

eunomia/static/banners/13.gif

This is a binary file and will not be displayed.

eunomia/static/banners/14.gif

This is a binary file and will not be displayed.

eunomia/static/banners/15.gif

This is a binary file and will not be displayed.

eunomia/static/banners/16.gif

This is a binary file and will not be displayed.

eunomia/static/banners/17.gif

This is a binary file and will not be displayed.

eunomia/static/banners/18.gif

This is a binary file and will not be displayed.

eunomia/static/banners/19.gif

This is a binary file and will not be displayed.

eunomia/static/banners/2.gif

This is a binary file and will not be displayed.

eunomia/static/banners/20.gif

This is a binary file and will not be displayed.

eunomia/static/banners/3.gif

This is a binary file and will not be displayed.

eunomia/static/banners/4.gif

This is a binary file and will not be displayed.

eunomia/static/banners/5.gif

This is a binary file and will not be displayed.

eunomia/static/banners/6.gif

This is a binary file and will not be displayed.

eunomia/static/banners/7.gif

This is a binary file and will not be displayed.

eunomia/static/banners/8.gif

This is a binary file and will not be displayed.

eunomia/static/banners/9.gif

This is a binary file and will not be displayed.

eunomia/static/eyes/closed.webp

This is a binary file and will not be displayed.

eunomia/static/eyes/normal_forward.webp

This is a binary file and will not be displayed.

eunomia/static/eyes/normal_left.webp

This is a binary file and will not be displayed.

eunomia/static/eyes/normal_right.webp

This is a binary file and will not be displayed.

eunomia/static/fonts/dollmonoopt.woff2

This is a binary file and will not be displayed.

eunomia/static/fonts/fusion-pixel-sc-monospaced.woff2

This is a binary file and will not be displayed.

eunomia/static/fonts/fusion-pixel-sc-proportional.woff2

This is a binary file and will not be displayed.

eunomia/static/icons/about.webp

This is a binary file and will not be displayed.

eunomia/static/icons/cd_audio.webp

This is a binary file and will not be displayed.

eunomia/static/icons/contact.webp

This is a binary file and will not be displayed.

eunomia/static/icons/entries.webp

This is a binary file and will not be displayed.

eunomia/static/icons/entry.webp

This is a binary file and will not be displayed.

eunomia/static/icons/gaze.webp

This is a binary file and will not be displayed.

eunomia/static/icons/gaze_closed.webp

This is a binary file and will not be displayed.

eunomia/static/icons/gaze_site.webp

This is a binary file and will not be displayed.

eunomia/static/icons/guestbook.webp

This is a binary file and will not be displayed.

eunomia/static/icons/home.webp

This is a binary file and will not be displayed.

eunomia/static/icons/msg_information.webp

This is a binary file and will not be displayed.

eunomia/static/icons/msn.webp

This is a binary file and will not be displayed.

eunomia/static/icons/question.webp

This is a binary file and will not be displayed.

eunomia/static/icons/warning.webp

This is a binary file and will not be displayed.

eunomia/static/others/250kb.webp

This is a binary file and will not be displayed.

eunomia/static/others/aph.gif

This is a binary file and will not be displayed.

eunomia/static/others/dbd.gif

This is a binary file and will not be displayed.

eunomia/static/others/dd86k.gif

This is a binary file and will not be displayed.

eunomia/static/others/desktopwebp.webp

This is a binary file and will not be displayed.

eunomia/static/others/drewsh.gif

This is a binary file and will not be displayed.

eunomia/static/others/godot.gif

This is a binary file and will not be displayed.

eunomia/static/others/it.webp

This is a binary file and will not be displayed.

eunomia/static/others/killfascists.webp

This is a binary file and will not be displayed.

eunomia/static/others/moonlightnow.gif

This is a binary file and will not be displayed.

eunomia/static/others/notaperson.webp

This is a binary file and will not be displayed.

eunomia/static/others/poweredbynixos.webp

This is a binary file and will not be displayed.

eunomia/static/others/skylar.gif

This is a binary file and will not be displayed.

eunomia/static/others/slonk.gif

This is a binary file and will not be displayed.

eunomia/static/pet/idle.webp

This is a binary file and will not be displayed.

eunomia/static/pet/pick.webp

This is a binary file and will not be displayed.

eunomia/static/pet/walk1.webp

This is a binary file and will not be displayed.

eunomia/static/pet/walk2.webp

This is a binary file and will not be displayed.

eunomia/static/pfp-iojkqpwerojnasduijf.webp

This is a binary file and will not be displayed.

eunomia/static/resume.pdf

This is a binary file and will not be displayed.

eunomia/static/wavey.gif

This is a binary file and will not be displayed.

+62
eunomia/svelte.config.js
···
+
import adapter from '@sveltejs/adapter-node';
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
+
+
import { mdsvex } from 'mdsvex';
+
+
import * as toml from '@std/toml';
+
import { resolve } from 'node:path';
+
+
/** @type {import('@sveltejs/kit').Config} */
+
const config = {
+
extensions: ['.svelte', '.md', '.svx'],
+
+
preprocess: [
+
vitePreprocess(),
+
mdsvex({
+
extensions: ['.md', '.svx'],
+
frontmatter: {
+
type: 'toml',
+
marker: '+',
+
parse(frontmatter, messages) {
+
try {
+
return toml.parse(frontmatter);
+
} catch (e) {
+
messages.push(
+
'Parsing error on line ' + e.line + ', column ' + e.column + ': ' + e.message
+
);
+
}
+
}
+
},
+
smartypants: {
+
dashes: 'oldschool',
+
quotes: true,
+
ellipses: true,
+
backticks: false
+
},
+
layout: {
+
about: resolve('src/routes/(site)/about/_layout.svelte'),
+
blogpost: resolve('src/routes/(site)/entries/_layout.svelte'),
+
simple: resolve('src/components/_window_layout.svelte')
+
}
+
})
+
],
+
+
kit: {
+
csrf: {
+
checkOrigin: false,
+
trustedOrigins: ["https://gaze.systems", "https://ptr.pet", "https://poor.dog"]
+
},
+
prerender: {
+
handleHttpError: 'warn'
+
},
+
adapter: adapter({
+
precompress: true
+
}),
+
alias: {
+
$components: 'src/components',
+
$styles: 'src/styles'
+
}
+
}
+
};
+
+
export default config;
+58
eunomia/tailwind.config.js
···
+
import typography from '@tailwindcss/typography';
+
import forms from '@tailwindcss/forms';
+
+
/** @type {import('tailwindcss').Config} */
+
export default {
+
content: ['./src/**/*.{html,js,svelte,ts,md}'],
+
theme: {
+
extend: {
+
typography: ({ theme }) => ({
+
ralsei: {
+
css: {
+
'--tw-prose-body': theme('colors.ralsei.white'),
+
'--tw-prose-headings': theme('colors.ralsei.pink.neon'),
+
'--tw-prose-lead': theme('colors.ralsei.white'),
+
'--tw-prose-links': theme('colors.ralsei.green.light'),
+
'--tw-prose-bold': theme('colors.ralsei.white'),
+
'--tw-prose-counters': theme('colors.ralsei.pink.regular'),
+
'--tw-prose-bullets': theme('colors.ralsei.pink.regular'),
+
'--tw-prose-hr': theme('colors.ralsei.white'),
+
'--tw-prose-quotes': theme('colors.ralsei.white'),
+
'--tw-prose-quote-borders': theme('colors.ralsei.white'),
+
'--tw-prose-captions': theme('colors.ralsei.white'),
+
'--tw-prose-code': theme('colors.ralsei.pink.regular'),
+
'--tw-prose-pre-code': theme('colors.ralsei.white'),
+
'--tw-prose-pre-bg': theme('colors.ralsei.green.dark'),
+
'--tw-prose-th-borders': theme('colors.ralsei.white'),
+
'--tw-prose-td-borders': theme('colors.ralsei.white')
+
}
+
}
+
}),
+
animation: {
+
'bounce-slow': 'bounce 3s infinite',
+
'bounce-fast': 'bounce 0.5s infinite',
+
'pulse-fast': 'pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite',
+
blink: 'blink 1s step-start infinite'
+
},
+
colors: {
+
ralsei: {
+
pink: {
+
regular: '#fe96e0',
+
neon: '#ff3eb7'
+
},
+
white: '#fff9fe',
+
black: '#000801',
+
green: {
+
light: '#4dcc8e',
+
dark: '#162d26'
+
}
+
}
+
}
+
},
+
fontFamily: {
+
'sans-serif': ['"Fusion Pixel 10px Proportional zh_hans", sans-serif'],
+
monospace: ['"Fusion Pixel 10px Monospaced zh_hans", monospace']
+
}
+
},
+
plugins: [typography, forms]
+
};
+24
eunomia/tsconfig.json
···
+
{
+
"extends": "./.svelte-kit/tsconfig.json",
+
"compilerOptions": {
+
"allowJs": true,
+
"checkJs": true,
+
"esModuleInterop": true,
+
"forceConsistentCasingInFileNames": true,
+
"resolveJsonModule": true,
+
"skipLibCheck": true,
+
"sourceMap": true,
+
"strict": true,
+
"plugins": [
+
{
+
"name": "typescript-svelte-plugin",
+
"enabled": true
+
}
+
]
+
}
+
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
+
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
+
//
+
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
+
// from the referenced tsconfig.json - TypeScript does not merge them in
+
}
+6
eunomia/vite.config.ts
···
+
import { sveltekit } from '@sveltejs/kit/vite';
+
import { defineConfig } from 'vite';
+
+
export default defineConfig({
+
plugins: [sveltekit()]
+
});
+242 -11
flake.lock
···
{
"nodes": {
+
"crane": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1758758545,
+
"narHash": "sha256-NU5WaEdfwF6i8faJ2Yh+jcK9vVFrofLcwlD/mP65JrI=",
+
"owner": "ipetkov",
+
"repo": "crane",
+
"rev": "95d528a5f54eaba0d12102249ce42f4d01f4e364",
+
"type": "github"
+
},
+
"original": {
+
"owner": "ipetkov",
+
"ref": "v0.21.1",
+
"repo": "crane",
+
"type": "github"
+
}
+
},
+
"dream2nix": {
+
"inputs": {
+
"nixpkgs": [
+
"nci",
+
"nixpkgs"
+
],
+
"purescript-overlay": "purescript-overlay",
+
"pyproject-nix": "pyproject-nix"
+
},
+
"locked": {
+
"lastModified": 1765228272,
+
"narHash": "sha256-duTz4J4NP1edl/ZBdwZPduPM8j6g0yzjb8YH91T9vU0=",
+
"owner": "nix-community",
+
"repo": "dream2nix",
+
"rev": "83c430ce6b6aedf149c5259f066bfff808722dbd",
+
"type": "github"
+
},
+
"original": {
+
"owner": "nix-community",
+
"repo": "dream2nix",
+
"type": "github"
+
}
+
},
+
"flake-compat": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1696426674,
+
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+
"owner": "edolstra",
+
"repo": "flake-compat",
+
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+
"type": "github"
+
},
+
"original": {
+
"owner": "edolstra",
+
"repo": "flake-compat",
+
"type": "github"
+
}
+
},
+
"mk-naked-shell": {
+
"flake": false,
+
"locked": {
+
"lastModified": 1681286841,
+
"narHash": "sha256-3XlJrwlR0nBiREnuogoa5i1b4+w/XPe0z8bbrJASw0g=",
+
"owner": "90-008",
+
"repo": "mk-naked-shell",
+
"rev": "7612f828dd6f22b7fb332cc69440e839d7ffe6bd",
+
"type": "github"
+
},
+
"original": {
+
"owner": "90-008",
+
"repo": "mk-naked-shell",
+
"type": "github"
+
}
+
},
"naked-shell": {
"locked": {
"lastModified": 1681286841,
···
"type": "github"
}
},
+
"nci": {
+
"inputs": {
+
"crane": "crane",
+
"dream2nix": "dream2nix",
+
"mk-naked-shell": "mk-naked-shell",
+
"nixpkgs": [
+
"nixpkgs"
+
],
+
"parts": "parts",
+
"rust-overlay": "rust-overlay",
+
"treefmt": "treefmt"
+
},
+
"locked": {
+
"lastModified": 1765347705,
+
"narHash": "sha256-pp5ru9CvZz0n1UBvRzp41othwARTUBmK1Es8iAqgepc=",
+
"owner": "90-008",
+
"repo": "nix-cargo-integration",
+
"rev": "c573f9ec80416fd09964a3e3892f14d9012a03e2",
+
"type": "github"
+
},
+
"original": {
+
"owner": "90-008",
+
"repo": "nix-cargo-integration",
+
"type": "github"
+
}
+
},
"nixpkgs": {
"locked": {
-
"lastModified": 1752950548,
-
"narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=",
+
"lastModified": 1765270179,
+
"narHash": "sha256-g2a4MhRKu4ymR4xwo+I+auTknXt/+j37Lnf0Mvfl1rE=",
"owner": "nixos",
"repo": "nixpkgs",
-
"rev": "c87b95e25065c028d31a94f06a62927d18763fdf",
+
"rev": "677fbe97984e7af3175b6c121f3c39ee5c8d62c9",
"type": "github"
},
"original": {
"owner": "nixos",
-
"ref": "nixos-unstable",
+
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
-
"lastModified": 1751159883,
-
"narHash": "sha256-urW/Ylk9FIfvXfliA1ywh75yszAbiTEVgpPeinFyVZo=",
+
"lastModified": 1761765539,
+
"narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
-
"rev": "14a40a1d7fb9afa4739275ac642ed7301a9ba1ab",
+
"rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
"type": "github"
},
"original": {
···
},
"parts": {
"inputs": {
+
"nixpkgs-lib": [
+
"nci",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1763759067,
+
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
+
"owner": "hercules-ci",
+
"repo": "flake-parts",
+
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
+
"type": "github"
+
},
+
"original": {
+
"owner": "hercules-ci",
+
"repo": "flake-parts",
+
"type": "github"
+
}
+
},
+
"parts_2": {
+
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
-
"lastModified": 1753121425,
-
"narHash": "sha256-TVcTNvOeWWk1DXljFxVRp+E0tzG1LhrVjOGGoMHuXio=",
+
"lastModified": 1763759067,
+
"narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
"owner": "hercules-ci",
"repo": "flake-parts",
-
"rev": "644e0fc48951a860279da645ba77fe4a6e814c5e",
+
"rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
"type": "github"
},
"original": {
···
"type": "github"
}
},
+
"purescript-overlay": {
+
"inputs": {
+
"flake-compat": "flake-compat",
+
"nixpkgs": [
+
"nci",
+
"dream2nix",
+
"nixpkgs"
+
],
+
"slimlock": "slimlock"
+
},
+
"locked": {
+
"lastModified": 1728546539,
+
"narHash": "sha256-Sws7w0tlnjD+Bjck1nv29NjC5DbL6nH5auL9Ex9Iz2A=",
+
"owner": "thomashoneyman",
+
"repo": "purescript-overlay",
+
"rev": "4ad4c15d07bd899d7346b331f377606631eb0ee4",
+
"type": "github"
+
},
+
"original": {
+
"owner": "thomashoneyman",
+
"repo": "purescript-overlay",
+
"type": "github"
+
}
+
},
+
"pyproject-nix": {
+
"inputs": {
+
"nixpkgs": [
+
"nci",
+
"dream2nix",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1752481895,
+
"narHash": "sha256-luVj97hIMpCbwhx3hWiRwjP2YvljWy8FM+4W9njDhLA=",
+
"owner": "pyproject-nix",
+
"repo": "pyproject.nix",
+
"rev": "16ee295c25107a94e59a7fc7f2e5322851781162",
+
"type": "github"
+
},
+
"original": {
+
"owner": "pyproject-nix",
+
"repo": "pyproject.nix",
+
"type": "github"
+
}
+
},
"root": {
"inputs": {
"naked-shell": "naked-shell",
+
"nci": "nci",
"nixpkgs": "nixpkgs",
-
"parts": "parts"
+
"parts": "parts_2"
+
}
+
},
+
"rust-overlay": {
+
"inputs": {
+
"nixpkgs": [
+
"nci",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1765334520,
+
"narHash": "sha256-jTof2+ir9UPmv4lWksYO6WbaXCC0nsDExrB9KZj7Dz4=",
+
"owner": "oxalica",
+
"repo": "rust-overlay",
+
"rev": "db61f666aea93b28f644861fbddd37f235cc5983",
+
"type": "github"
+
},
+
"original": {
+
"owner": "oxalica",
+
"repo": "rust-overlay",
+
"type": "github"
+
}
+
},
+
"slimlock": {
+
"inputs": {
+
"nixpkgs": [
+
"nci",
+
"dream2nix",
+
"purescript-overlay",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1688756706,
+
"narHash": "sha256-xzkkMv3neJJJ89zo3o2ojp7nFeaZc2G0fYwNXNJRFlo=",
+
"owner": "thomashoneyman",
+
"repo": "slimlock",
+
"rev": "cf72723f59e2340d24881fd7bf61cb113b4c407c",
+
"type": "github"
+
},
+
"original": {
+
"owner": "thomashoneyman",
+
"repo": "slimlock",
+
"type": "github"
+
}
+
},
+
"treefmt": {
+
"inputs": {
+
"nixpkgs": [
+
"nci",
+
"nixpkgs"
+
]
+
},
+
"locked": {
+
"lastModified": 1762938485,
+
"narHash": "sha256-AlEObg0syDl+Spi4LsZIBrjw+snSVU4T8MOeuZJUJjM=",
+
"owner": "numtide",
+
"repo": "treefmt-nix",
+
"rev": "5b4ee75aeefd1e2d5a1cc43cf6ba65eba75e83e4",
+
"type": "github"
+
},
+
"original": {
+
"owner": "numtide",
+
"repo": "treefmt-nix",
+
"type": "github"
}
}
},
+14 -12
flake.nix
···
{
inputs.parts.url = "github:hercules-ci/flake-parts";
-
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
+
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
inputs.naked-shell.url = "github:90-008/mk-naked-shell";
+
inputs.nci.url = "github:90-008/nix-cargo-integration";
+
inputs.nci.inputs.nixpkgs.follows = "nixpkgs";
outputs = inp:
inp.parts.lib.mkFlake {inputs = inp;} {
systems = ["x86_64-linux"];
imports = [
inp.naked-shell.flakeModule
+
# inp.nci.flakeModule
];
perSystem = {
config,
-
system,
+
pkgs,
...
-
}: let
-
pkgs = inp.nixpkgs.legacyPackages.${system};
-
in {
-
devShells.default = config.mk-naked-shell.lib.mkNakedShell {
-
name = "gazesys-devshell";
+
}: {
+
devShells.default = pkgs.mkShell {
+
name = "eunomia-devshell";
packages = with pkgs; [
-
nodejs-slim_latest bun
+
nodejs-slim_latest deno
nodePackages.svelte-language-server
nodePackages.typescript-language-server
+
rustc rust-analyzer cargo wasm-pack wasm-bindgen-cli lld rustfmt binaryen
];
shellHook = ''
export PATH="$PATH:$PWD/node_modules/.bin"
'';
};
-
packages.gazesys-modules = pkgs.callPackage ./nix/modules.nix {};
-
packages.gazesys = pkgs.callPackage ./nix {
-
inherit (config.packages) gazesys-modules;
+
packages.eunomia-modules = pkgs.callPackage ./nix/modules.nix {};
+
packages.eunomia = pkgs.callPackage ./nix {
+
inherit (config.packages) eunomia-modules;
};
-
packages.default = config.packages.gazesys;
+
packages.default = config.packages.eunomia;
};
};
}
+17 -20
nix/default.nix
···
{
lib,
stdenv,
-
bun,
+
deno,
+
nodejs,
makeBinaryWrapper,
-
gazesys-modules,
+
eunomia-modules,
PUBLIC_BASE_URL ? "http://localhost:5173",
}:
stdenv.mkDerivation {
-
name = "gazesys-website";
+
name = "eunomia";
src = lib.fileset.toSource {
root = ../.;
fileset = lib.fileset.unions [
-
../src
-
../static
-
../bun.lock
-
../package.json
-
../postcss.config.js
-
../svelte.config.js
-
../tailwind.config.js
-
../tsconfig.json
-
../vite.config.ts
+
../deno.lock
+
../deno.json
+
../eunomia
];
};
nativeBuildInputs = [makeBinaryWrapper];
-
buildInputs = [bun];
+
buildInputs = [deno];
inherit PUBLIC_BASE_URL;
···
configurePhase = ''
runHook preConfigure
-
cp -R --no-preserve=ownership ${gazesys-modules} node_modules
+
cp -R --no-preserve=ownership ${eunomia-modules} node_modules
find node_modules -type d -exec chmod 755 {} \;
substituteInPlace node_modules/.bin/vite \
-
--replace-fail "/usr/bin/env node" "${bun}/bin/bun --bun"
+
--replace-fail "/usr/bin/env node" "${nodejs}/bin/node"
runHook postConfigure
'';
buildPhase = ''
runHook preBuild
-
bun --prefer-offline run build
+
pushd eunomia
+
HOME=$TMPDIR ../node_modules/.bin/vite build
+
popd
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
-
cp -R ./build/* $out
+
cp -R ./eunomia/build/* $out
cp -R ./node_modules $out
-
makeBinaryWrapper ${bun}/bin/bun $out/bin/website \
-
--prefix PATH : ${lib.makeBinPath [ bun ]} \
-
--add-flags "run --bun --no-install --cwd $out start"
+
makeBinaryWrapper ${deno}/bin/deno $out/bin/eunomia \
+
--prefix PATH : ${lib.makeBinPath [ deno ]} \
+
--add-flags "run --allow-all --node-modules-dir=manual --cached-only $out/index.js"
runHook postInstall
'';
+14 -11
nix/modules.nix
···
{
lib,
stdenv,
-
bun,
+
deno,
}:
stdenv.mkDerivation {
-
name = "gazesys-modules";
+
name = "eunomia-modules";
src = lib.fileset.toSource {
root = ../.;
fileset = lib.fileset.unions [
-
../bun.lock
-
../package.json
+
../eunomia/package.json
+
../deno.json
+
../deno.lock
];
};
-
outputHash = "sha256-XqJ32vIa7ex+SpOaK8Qh4YRSffN6ekvwb9bddREGAOA=";
+
outputHash = "sha256-A2foV0GsVZKcuGCDBjb5b27ShoKfIL3qSa+v7IC8geU=";
outputHashAlgo = "sha256";
outputHashMode = "recursive";
-
nativeBuildInputs = [bun];
+
nativeBuildInputs = [deno];
dontConfigure = true;
dontCheck = true;
dontFixup = true;
dontPatchShebangs = true;
-
buildPhase = "bun install --no-cache --no-progress --frozen-lockfile";
-
installPhase = ''
-
mkdir -p $out
+
postUnpack = ''
-
cp -R ./node_modules/* $out
-
cp -R ./node_modules/.bin $out
+
'';
+
buildPhase = ''
+
HOME=$TMPDIR deno install --allow-scripts=npm:protobufjs@7.5.4 --frozen --seed 8008135
+
'';
+
installPhase = ''
+
cp -R node_modules $out
ls -la $out
'';
}
-62
package.json
···
-
{
-
"name": "website",
-
"version": "0.0.1",
-
"private": true,
-
"scripts": {
-
"dev": "vite dev",
-
"build": "vite build",
-
"preview": "vite preview",
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
-
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
-
"lint": "prettier --check . && eslint .",
-
"format": "prettier --write ."
-
},
-
"devDependencies": {
-
"@sveltejs/kit": "^2.33.1",
-
"@sveltejs/vite-plugin-svelte": "^6.1.3",
-
"@tailwindcss/forms": "^0.5.10",
-
"@tailwindcss/typography": "^0.5.16",
-
"@types/eslint": "^9.6.1",
-
"@types/node": "^22.17.2",
-
"autoprefixer": "^10.4.21",
-
"eslint": "^9.33.0",
-
"eslint-config-prettier": "^10.1.8",
-
"eslint-plugin-svelte": "^3.11.0",
-
"globals": "^16.3.0",
-
"mdsvex": "^0.12.6",
-
"postcss": "^8.5.6",
-
"prettier": "^3.6.2",
-
"prettier-plugin-svelte": "^3.4.0",
-
"svelte": "^5.38.2",
-
"svelte-adapter-bun": "^0.5.2",
-
"svelte-check": "^4.3.1",
-
"sveltekit-rate-limiter": "^0.7.0",
-
"tailwindcss": "^3.4.17",
-
"tslib": "^2.8.1",
-
"typescript": "^5.9.2",
-
"typescript-eslint": "^8.40.0",
-
"typescript-svelte-plugin": "^0.3.50",
-
"vite": "^7.1.3"
-
},
-
"type": "module",
-
"dependencies": {
-
"@neodrag/svelte": "^2.3.3",
-
"@rowanmanning/feed-parser": "^2.1.1",
-
"@skyware/bot": "^0.4.0",
-
"@std/toml": "npm:@jsr/std__toml",
-
"@types/bun": "^1.2.20",
-
"@types/node-schedule": "^2.1.8",
-
"nanoid": "^5.1.5",
-
"node-schedule": "^2.1.1",
-
"prometheus-remote-write": "^0.5.1",
-
"robots-parser": "^3.0.1",
-
"steamgriddb": "^2.2.0"
-
},
-
"trustedDependencies": [
-
"@sveltejs/kit",
-
"esbuild",
-
"protobufjs",
-
"sharp",
-
"svelte-preprocess"
-
]
-
}
-6
postcss.config.js
···
-
export default {
-
plugins: {
-
tailwindcss: {},
-
autoprefixer: {},
-
},
-
}
-13
src/app.d.ts
···
-
// See https://kit.svelte.dev/docs/types#app
-
// for information about these interfaces
-
declare global {
-
namespace App {
-
// interface Error {}
-
// interface Locals {}
-
// interface PageData {}
-
// interface PageState {}
-
// interface Platform {}
-
}
-
}
-
-
export {};
-12
src/app.html
···
-
<!doctype html>
-
<html lang="en">
-
<head>
-
<meta charset="utf-8" />
-
<link rel="icon" href="%sveltekit.assets%/icons/gaze_site.webp" />
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
-
%sveltekit.head%
-
</head>
-
<body class="md:overflow-hidden">
-
<div style="display: contents">%sveltekit.body%</div>
-
</body>
-
</html>
-19
src/components/_window_layout.svelte
···
-
<script lang="ts">
-
import Window from './window.svelte';
-
import '../styles/app.css';
-
-
interface Props {
-
title: string;
-
sticky: boolean;
-
prose?: boolean;
-
children?: import('svelte').Snippet;
-
}
-
-
let { title, sticky, prose = true, children }: Props = $props();
-
</script>
-
-
<Window {title} {sticky}>
-
<div class={prose ? 'prose prose-ralsei leading-6 prose-ul:leading-5' : ''}>
-
{@render children?.()}
-
</div>
-
</Window>
-92
src/components/eye.svelte
···
-
<script lang="ts">
-
import { renderDate } from '$lib/dateFmt';
-
import { genDollcode } from '$lib/dollcode';
-
import Tooltip from './tooltip.svelte';
-
-
interface Props {
-
top: number;
-
left: number;
-
kind?: string;
-
visits: number[];
-
id: string;
-
}
-
-
let { top, left, kind = 'normal', visits, id }: Props = $props();
-
-
const reverse = Math.random() > 0.35;
-
let rotation = $state((Math.random() - 0.5) * 0.4);
-
const opacity = Math.min(Math.random() * 0.3 + 0.4, 0.7);
-
-
let closed = $state(false);
-
let look = $state('forward');
-
const looks = ['left', 'forward', 'right'];
-
const pickLook = $derived(() => {
-
const pickable = looks.filter((l) => {
-
return l !== look;
-
});
-
return pickable.at(Math.floor(Math.random() * pickable.length)) ?? 'forward';
-
});
-
const randomizeLook = () => {
-
look = pickLook();
-
rotation = (Math.random() - 0.5) * 0.4;
-
setTimeout(randomizeLook, 2000 + Math.random() * 6000);
-
};
-
-
let src = $derived(closed ? `/eyes/closed.webp` : `/eyes/${kind}_${look}.webp`);
-
-
randomizeLook();
-
</script>
-
-
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
-
<Tooltip
-
style="
-
position: fixed;
-
top: {top}vh;
-
left: {left}%;
-
"
-
y="translate-y-none"
-
targetY="group-hover:translate-y-none"
-
x="-translate-x-[20%]"
-
targetX="group-hover:-translate-x-[20%]"
-
>
-
{#snippet tooltipContent()}
-
<p class="font-monospace" style="min-width: {id.length + 15}ch;">
-
//observant/id={id}<br />
-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/date="{renderDate(
-
visits[0]
-
)}"<br />
-
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/count={visits.length}/
-
</p>
-
{/snippet}
-
<div
-
class="group flex gap-4 items-center scale-[0.75]"
-
style="
-
opacity: {opacity};
-
flex-direction: {reverse ? 'column-reverse' : 'column'};
-
"
-
onmouseover={() => {
-
closed = true;
-
}}
-
onmouseleave={() => {
-
closed = false;
-
}}
-
>
-
<span class="eye-text !text-base">{genDollcode(visits.length)}</span>
-
<!-- svelte-ignore a11y_missing_attribute -->
-
<img class="w-24 eye-image" style="transform: rotate({rotation}rad);" {src} />
-
<span class="eye-text">{genDollcode(visits[0])}</span>
-
</div>
-
</Tooltip>
-
-
<style lang="postcss">
-
.eye-text {
-
@apply text-xs [font-family:Doll_Mono] opacity-30 group-hover:opacity-80;
-
}
-
.eye-image {
-
@apply opacity-50 group-hover:opacity-100;
-
image-rendering: pixelated !important;
-
filter: drop-shadow(4px 4px 0 theme(colors.ralsei.green.light))
-
drop-shadow(-4px -4px 0 theme(colors.ralsei.pink.neon));
-
}
-
</style>
-31
src/components/navButton.svelte
···
-
<script lang="ts">
-
interface Props {
-
highlight?: boolean;
-
name: string;
-
href: string;
-
iconUri: string;
-
}
-
-
let { highlight = false, name, href, iconUri }: Props = $props();
-
</script>
-
-
<a
-
class="
-
max-w-36 p-0.5 pr-1.5 border-ralsei-white border-4
-
{highlight
-
? 'min-w-36 bg-gradient-to-l to-ralsei-pink-neon/30 from-ralsei-pink-regular/20 from-30% border-ridge motion-safe:animate-pulse hover:animate-none'
-
: 'w-fit border-double hover:border-solid animate-bounce-reverse hover:underline'}
-
flex gap-1 items-center justify-center align-middle text-center
-
{highlight ? 'text-ralsei-pink-regular app-selected-route' : 'text-ralsei-green-light'}
-
"
-
title={name}
-
href="/{href}"
-
data-sveltekit-preload-data="tap"
-
>
-
<img class="max-w-4" style="image-rendering: pixelated;" src={iconUri} alt={name} />
-
<div
-
class="font-monospace text-sm/3 overflow-hidden text-ellipsis text-nowrap [text-decoration-line:inherit]"
-
>
-
{name}
-
</div>
-
</a>
-127
src/components/note.svelte
···
-
<script module lang="ts">
-
import type { Post } from '@skyware/bot';
-
-
export interface OutgoingLink {
-
name: string;
-
link: string;
-
}
-
-
export interface NoteData {
-
content: string;
-
published: number;
-
hasMedia: boolean;
-
hasQuote: boolean;
-
outgoingLinks?: OutgoingLink[];
-
purposeAction?: string;
-
children?: NoteData[];
-
depth?: number;
-
}
-
-
export const flattenNotes = (note: NoteData, currentDepth: number = 0): NoteData[] => {
-
note.depth = currentDepth;
-
const flattened = [note];
-
if (note.children) {
-
note.children.forEach((child) => {
-
flattened.push(...flattenNotes(child, currentDepth + 1));
-
});
-
}
-
return flattened;
-
};
-
-
export const noteFromBskyPost = (post: Post): NoteData => {
-
return {
-
content: post.text,
-
published: post.createdAt.getTime(),
-
outgoingLinks: [{ name: 'bsky', link: post.uri }],
-
hasMedia:
-
(post.embed?.isImages() || post.embed?.isVideo() || post.embed?.isRecordWithMedia()) ??
-
false,
-
hasQuote: (post.embed?.isRecord() || post.embed?.isRecordWithMedia()) ?? false
-
};
-
};
-
</script>
-
-
<script lang="ts">
-
import Token from './token.svelte';
-
import { renderDate, renderRelativeDate } from '$lib/dateFmt';
-
-
interface Props {
-
rootNote: NoteData;
-
isHighlighted?: boolean;
-
onlyContent?: boolean;
-
showOutgoing?: boolean;
-
mapOutgoingNames?: Record<string, string>;
-
}
-
-
let {
-
rootNote,
-
isHighlighted = false,
-
onlyContent = false,
-
showOutgoing = true,
-
mapOutgoingNames = {}
-
}: Props = $props();
-
-
const getOutgoingLink = ({ name, link }: { name: string; link: string }) => {
-
if (name.startsWith('bsky')) {
-
// Parse the atproto URI to extract DID and rkey
-
const match = link.match(/at:\/\/(did:[^/]+)\/[^/]+\/([^/]+)/);
-
if (match && match.length >= 3) {
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
-
const [_, did, rkey] = match;
-
link = `https://bsky.app/profile/${did}/post/${rkey}`;
-
}
-
if (name === 'bsky-reply') {
-
return ['reply', link];
-
} else {
-
return [name, link];
-
}
-
}
-
return [name, link];
-
};
-
// this is ASS this should be a tailwind class
-
const getTextShadowStyle = (color: string) => {
-
return `text-shadow: 0 0 1px theme(colors.ralsei.black), 0 0 5px ${color};`;
-
};
-
const outgoingLinkColors: Record<string, string> = {
-
bsky: 'rgb(0, 133, 255)',
-
reply: 'rgb(0, 133, 255)'
-
};
-
</script>
-
-
{#each flattenNotes(rootNote) as note}
-
<p class="m-0 max-w-[70ch] text-wrap break-words leading-tight align-middle">
-
{#if note.depth ?? 0 > 0}
-
<span class="inline-block">|{'=='.repeat(note.depth ?? 0)}</span>&gt;
-
{/if}
-
{#if !onlyContent}
-
{#if (note.purposeAction ?? '').length > 0}
-
<Token v="({note.purposeAction!})" small={!isHighlighted} funct />
-
{/if}
-
{#if note.purposeAction !== 'reply'}
-
<Token
-
title={renderDate(note.published)}
-
v={renderRelativeDate(note.published)}
-
small={!isHighlighted}
-
/>
-
{/if}
-
{/if}
-
<Token v={note.content} str />
-
{#if note.hasMedia}<Token v="-contains media-" keywd small />{/if}
-
{#if note.hasQuote}<Token v="-contains quote-" keywd small />{/if}
-
{#if showOutgoing}
-
{#each (note.outgoingLinks ?? []).map(getOutgoingLink) as [name, link]}
-
{@const color = outgoingLinkColors[name]}
-
{@const viewName = mapOutgoingNames[name] ?? name}
-
{#if viewName.length > 0}
-
<span class="text-sm"
-
><Token v="(" punct /><a
-
class="hover:motion-safe:animate-squiggle hover:underline"
-
style="color: {color};{getTextShadowStyle(color)}"
-
href={link}>{viewName}</a
-
><Token v=")" punct /></span
-
>
-
{/if}
-
{/each}
-
{/if}
-
</p>
-
{/each}
-304
src/components/pet.svelte
···
-
<script module lang="ts">
-
import { get, writable } from 'svelte/store';
-
-
export const localDistanceTravelled = writable(0.0);
-
export const localBounces = writable(0);
-
</script>
-
-
<script lang="ts">
-
import { draggable } from '@neodrag/svelte';
-
import { browser } from '$app/environment';
-
-
interface Props {
-
apiToken: string;
-
}
-
-
let { apiToken }: Props = $props();
-
-
let lastDragged = 0;
-
let mouseX = 0;
-
let mouseY = 0;
-
-
let position = $state({ x: 0, y: 0 });
-
let rotation = $state(0.0);
-
let sprite = $state('/pet/idle.webp');
-
let flip = $state(false);
-
let dragged = $state(false);
-
-
let targetX = 120;
-
let speed = 10.0;
-
let tickRate = 20;
-
let delta = 1.0 / tickRate;
-
-
let strideRadius = 4.0;
-
let strideAngle = 0;
-
-
const turnStrideWheel = (by: number) => {
-
strideAngle += by / strideRadius;
-
if (strideAngle > Math.PI * 2) {
-
strideAngle -= Math.PI * 2;
-
} else if (strideAngle < 0) {
-
strideAngle += Math.PI * 2;
-
}
-
};
-
-
let targetRotation = 0.0;
-
let rotationVelocity = 0.0;
-
let springStiffness = 20.0; // How quickly rotation returns to target
-
let springDamping = 0.2; // Damping factor to prevent oscillation
-
-
const updateRotationSpring = () => {
-
// Spring physics: calculate force based on distance from target
-
const springForce = (targetRotation - rotation) * springStiffness;
-
-
// Apply damping to velocity
-
rotationVelocity = rotationVelocity * (1 - springDamping) + springForce * delta;
-
-
// Update rotation based on velocity
-
rotation += rotationVelocity * delta;
-
-
// If we're very close to target and barely moving, just snap to target
-
if (Math.abs(rotation - targetRotation) < 0.01 && Math.abs(rotationVelocity) < 0.01) {
-
rotation = targetRotation;
-
rotationVelocity = 0;
-
}
-
};
-
-
// Add spring update to the move function
-
if (browser) setInterval(updateRotationSpring, tickRate);
-
-
const moveTowards = (from: number, to: number, by: number) => {
-
let d = (to - from) * 1.0;
-
let l = Math.abs(d);
-
let s = Math.sign(d);
-
let moveBy = s * Math.min(l, by) * delta;
-
return moveBy;
-
};
-
-
// Physics constants
-
let velocityX = 0;
-
let velocityY = 0;
-
let gravity = 200.0; // Gravity strength (positive because -Y is up)
-
let friction = 0.96; // Air friction
-
let groundFriction = 0.9; // Ground friction
-
let bounciness = 0.8; // How much energy is preserved on bounce
-
-
const sendBounceMetrics = () => {
-
fetch(`/_api/pet/bounce?_token=${apiToken}`);
-
localBounces.set(get(localBounces) + 1);
-
};
-
-
let deltaTravelled = 0.0;
-
let deltaTravelledTotal = 0.0;
-
const updateDistanceTravelled = () => {
-
if (deltaTravelled > 0.1 || deltaTravelled < -0.1) {
-
localDistanceTravelled.update((n) => {
-
n += deltaTravelled;
-
return n;
-
});
-
deltaTravelledTotal += deltaTravelled;
-
}
-
deltaTravelled = 0.0;
-
};
-
-
const sendTotalDistance = () => {
-
fetch(`/_api/pet/distance?_token=${apiToken}`, {
-
method: 'POST',
-
body: deltaTravelledTotal.toString()
-
});
-
deltaTravelledTotal = 0.0;
-
};
-
-
// sending every 5 seconds is probably reliable enough
-
if (browser) setInterval(sendTotalDistance, 1000 * 5);
-
-
const move = () => {
-
if (dragged) return;
-
-
// Apply physics when pet is in motion
-
if (velocityX !== 0 || velocityY !== 0 || position.y !== 0) {
-
// Apply gravity (remember negative Y is upward)
-
velocityY += gravity * delta;
-
-
// Apply friction
-
const fric = position.y === 0 ? groundFriction : friction;
-
velocityX *= fric;
-
velocityY *= fric;
-
-
// Update position
-
const moveX = velocityX * delta;
-
const moveY = velocityY * delta;
-
position.x += moveX;
-
position.y += moveY;
-
-
deltaTravelled += Math.sqrt(moveX ** 2 + moveY ** 2);
-
updateDistanceTravelled();
-
-
// Handle window boundaries
-
const viewportWidth = window.innerWidth;
-
-
// Bounce off sides
-
if (position.x < 0) {
-
position.x = 0;
-
velocityX = -velocityX * bounciness;
-
sendBounceMetrics();
-
} else if (position.x > viewportWidth) {
-
position.x = viewportWidth;
-
velocityX = -velocityX * bounciness;
-
sendBounceMetrics();
-
}
-
-
// Bounce off bottom (floor)
-
if (position.y > 0) {
-
position.y = 0;
-
velocityY = -velocityY * bounciness;
-
// Only bounce if velocity is significant
-
if (Math.abs(velocityY) < 80) {
-
velocityY = 0;
-
position.y = 0;
-
} else {
-
sendBounceMetrics();
-
}
-
}
-
-
// reset velocity
-
if (Math.abs(velocityX) < 5 && Math.abs(velocityY) < 5) {
-
velocityX = 0;
-
velocityY = 0;
-
}
-
-
// Update flip based on velocity
-
if (Math.abs(velocityX) > 0.5) {
-
flip = velocityX < 0;
-
}
-
-
targetRotation = velocityX * 0.02 + velocityY * 0.01;
-
-
return;
-
}
-
-
// Normal movement when not physics-based
-
let moveByX = moveTowards(position.x, targetX, speed * ((self.innerWidth ?? 1600.0) / 1600.0));
-
position.x += moveByX;
-
-
turnStrideWheel(moveByX);
-
-
flip = moveByX < 0.0;
-
if (moveByX > 0.1 || moveByX < -0.1) {
-
sprite = strideAngle % Math.PI < Math.PI * 0.5 ? '/pet/walk1.webp' : '/pet/walk2.webp';
-
} else {
-
sprite = '/pet/idle.webp';
-
}
-
-
deltaTravelled += Math.abs(moveByX);
-
updateDistanceTravelled();
-
};
-
-
if (browser) setInterval(move, tickRate);
-
-
const shake = (event: DeviceMotionEvent) => {
-
const accel = event.acceleration ?? event.accelerationIncludingGravity;
-
if (accel === null || accel.x === null || accel.y === null) return;
-
if (Math.abs(accel.x) + Math.abs(accel.y) < 40.0) return;
-
// make it so that it amplifies motion proportionally to the window size
-
const windowRatio = (window.innerWidth * 1.0) / (window.innerHeight * 1.0);
-
velocityX += accel.x * windowRatio * 5.0;
-
velocityY += accel.y * (1.0 / windowRatio) * 5.0;
-
sprite = '/pet/pick.webp';
-
};
-
-
if (browser) self.ondevicemotion = shake;
-
-
// this is for ios
-
const askForShakePermission = () => {
-
if (
-
typeof DeviceMotionEvent !== 'undefined' &&
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
typeof (DeviceMotionEvent as any).requestPermission === 'function'
-
) {
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
(DeviceMotionEvent as any)
-
.requestPermission()
-
.then((permissionState: string) => {
-
if (permissionState === 'granted') {
-
self.ondevicemotion = shake;
-
}
-
})
-
.catch(console.error);
-
}
-
};
-
-
const pickNewTargetX = () => {
-
const viewportWidth = self.innerWidth || null;
-
if (viewportWidth !== null && Math.abs(position.x - targetX) < 5) {
-
targetX = Math.max(
-
Math.min(targetX + (Math.random() - 0.5) * (viewportWidth * 0.5), viewportWidth * 0.9),
-
viewportWidth * 0.1
-
);
-
}
-
// Set a random interval for the next target update (between 4-10 seconds)
-
const randomDelay = Math.floor(Math.random() * 6000) + 4000;
-
setTimeout(pickNewTargetX, randomDelay);
-
};
-
-
// Start the process
-
if (browser) setTimeout(pickNewTargetX, 1000);
-
</script>
-
-
<!-- svelte-ignore a11y_missing_attribute -->
-
<div
-
use:draggable={{
-
position,
-
applyUserSelectHack: true,
-
handle: 'img',
-
bounds: {
-
bottom: (window.innerHeight / 100) * 5.5
-
},
-
onDragStart: () => {
-
sprite = '/pet/pick.webp';
-
dragged = true;
-
},
-
onDrag: ({ offsetX, offsetY, event }) => {
-
position.x = offsetX;
-
position.y = offsetY;
-
const mouseXD = event.movementX * delta;
-
const mouseYD = event.movementY * delta;
-
deltaTravelled += Math.sqrt(mouseXD ** 2 + mouseYD ** 2);
-
// reset mouse movement if it's not moving in the same direction so it doesnt accumulate its weird!@!@
-
mouseX = Math.sign(mouseXD) != Math.sign(mouseX) ? mouseXD : mouseX + mouseXD;
-
mouseY = Math.sign(mouseYD) != Math.sign(mouseY) ? mouseYD : mouseY + mouseYD;
-
rotationVelocity += mouseXD + mouseYD;
-
lastDragged = Date.now();
-
},
-
onDragEnd: () => {
-
// reset mouse movement if we stopped for longer than some time
-
if (Date.now() - lastDragged > 50) {
-
mouseX = 0.0;
-
mouseY = 0.0;
-
}
-
// apply velocity based on rotation since we already keep track of that
-
velocityX = mouseX * 70.0;
-
velocityY = mouseY * 50.0;
-
updateDistanceTravelled();
-
// reset mouse movement we dont want it to accumulate
-
mouseX = 0.0;
-
mouseY = 0.0;
-
dragged = false;
-
}
-
}}
-
class="fixed bottom-[5vh] z-[1000] hover:animate-squiggle"
-
style="cursor: url('/icons/gaze.webp'), pointer;"
-
>
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
-
<img
-
draggable="false"
-
onclick={askForShakePermission}
-
style="
-
image-rendering: pixelated !important;
-
transform: rotate({rotation}rad) scaleX({flip ? -1 : 1});
-
filter: invert(100%) drop-shadow(2px 2px 0 black) drop-shadow(-2px -2px 0 black);
-
"
-
src={sprite}
-
/>
-
</div>
-32
src/components/token.svelte
···
-
<script lang="ts">
-
-
-
interface Props {
-
punct?: boolean;
-
keywd?: boolean;
-
funct?: boolean;
-
str?: boolean;
-
small?: boolean;
-
v: string;
-
title?: string;
-
}
-
-
let {
-
punct = false,
-
keywd = false,
-
funct = false,
-
str = false,
-
small = false,
-
title,
-
v
-
}: Props = $props();
-
-
const ty =
-
punct ? "punctuation"
-
: keywd ? "keyword"
-
: funct ? "function"
-
: str ? "string"
-
: ""
-
</script>
-
-
<span {title} class="token {ty} {small ? "text-sm" : ""}">{v}</span>
-34
src/components/tooltip.svelte
···
-
<script lang="ts">
-
import Window from './window.svelte';
-
-
interface Props {
-
x?: string;
-
y?: string;
-
targetY?: string;
-
targetX?: string;
-
tooltipContent?: import('svelte').Snippet;
-
children?: import('svelte').Snippet;
-
style?: string;
-
}
-
-
let {
-
x = 'translate-x-none',
-
y = 'translate-y-full',
-
targetY = 'group-hover:-translate-y-[105%]',
-
targetX = 'group-hover:-translate-x-2/3',
-
tooltipContent,
-
children,
-
style = ''
-
}: Props = $props();
-
</script>
-
-
<div class="group" {style}>
-
<div
-
class="z-10 absolute scale-0 transition-all [transition-timing-function:cubic-bezier(0.4,0,0.2,1.6)] [transition-duration:300ms] opacity-0 group-hover:scale-100 group-hover:opacity-100 {y} {x} {targetY} {targetX}"
-
>
-
<Window tooltip>
-
{#if tooltipContent}{@render tooltipContent()}{:else}Hello world!{/if}
-
</Window>
-
</div>
-
{@render children?.()}
-
</div>
-124
src/components/window.svelte
···
-
<script lang="ts">
-
import { highestZIndex, isMobile } from '$lib/window.ts';
-
import { draggable } from '@neodrag/svelte';
-
-
interface Props {
-
title?: string;
-
iconUri?: string;
-
id?: string;
-
sticky?: boolean;
-
entry?: boolean;
-
removePadding?: boolean;
-
center?: boolean;
-
layered?: boolean;
-
style?: string;
-
tooltip?: boolean;
-
children?: import('svelte').Snippet;
-
}
-
-
let {
-
title = undefined,
-
iconUri = '',
-
id = '',
-
sticky = false,
-
entry = false,
-
removePadding = false,
-
center = false,
-
layered = false,
-
style = '',
-
tooltip = false,
-
children
-
}: Props = $props();
-
-
const scaleKeyframes = [
-
'window-open',
-
'window-open-vertical',
-
'window-open-vertical',
-
'window-open-horizontal',
-
'window-open-horizontal',
-
'window-open-move-up',
-
'window-open-move-down',
-
'window-open-move-left',
-
'window-open-move-right'
-
];
-
let chosenKeyframe = $derived(
-
scaleKeyframes.at(Math.floor(Math.random() * scaleKeyframes.length))
-
);
-
-
const isOnMobile = isMobile();
-
const _draggable = isOnMobile ? () => {} : draggable;
-
-
const focusWindow = (node: HTMLElement) => {
-
if (isOnMobile) return;
-
$highestZIndex += 1;
-
node.style.zIndex = $highestZIndex.toString();
-
};
-
</script>
-
-
<!-- svelte-ignore a11y_no_static_element_interactions -->
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
-
<div
-
use:_draggable={{
-
disabled: isOnMobile,
-
applyUserSelectHack: true,
-
handle: '.window-titlebar',
-
onDragStart: (data) => {
-
focusWindow(data.currentNode);
-
}
-
}}
-
onclick={(data) => {
-
focusWindow(data.currentTarget);
-
}}
-
class="
-
relative flex flex-col w-full md:w-fit [height:fit-content]
-
{center ? 'mx-auto' : ''}
-
{layered ? 'col-[1] row-[1]' : ''}
-
{sticky ? 'md:sticky md:-top-9' : ''}
-
max-w-screen-sm lg:max-w-screen-md xl:max-w-screen-lg 2xl:max-w-screen-xl
-
{tooltip ? 'min-w-fit' : ''}
-
bg-ralsei-black border-ralsei-white border-ridge
-
{tooltip ? 'border-[6px] border-t-[9px]' : 'border-[7px] border-t-[12px]'}
-
{isOnMobile || tooltip ? '' : 'hover:-translate-x-1 hover:translate-y-1'}
-
animate-{chosenKeyframe} drop-shadow-[24px_24px_24px_rgba(1,1,1,0.8)]
-
{style}
-
"
-
{id}
-
>
-
{#if title !== undefined}
-
<div
-
class="
-
window-titlebar p-1 border-ralsei-white border-8
-
bg-gradient-to-l from-ralsei-pink-neon to-ralsei-black to-75%
-
{!isOnMobile ? 'cursor-move' : ''}
-
"
-
style="border-style: hidden hidden ridge hidden;"
-
>
-
<div class="flex bg-opacity-100 pixelate-bg">
-
<h1
-
class="
-
font-monospace text-xl text-ralsei-pink-regular
-
grow justify-self-start self-center {entry ? 'p-name' : ''}
-
"
-
>
-
{title}
-
</h1>
-
{#if iconUri !== ''}
-
<img
-
class="justify-self-end self-center max-h-7"
-
style="image-rendering: pixelated;"
-
src={iconUri}
-
alt={iconUri}
-
/>
-
{/if}
-
</div>
-
</div>
-
{/if}
-
<div
-
class="
-
{removePadding ? '' : tooltip ? 'p-1' : 'p-2'} bg-gradient-to-tl
-
to-ralsei-pink-neon/15 from-ralsei-pink-regular/20
-
"
-
>
-
{@render children?.()}
-
</div>
-
</div>
-97
src/hooks.server.ts
···
-
import { updateLastPosts } from '$lib/bluesky';
-
import { lastFmReadLast, lastFmUpdateNowPlaying } from '$lib/lastfm';
-
import { steamReadLastGame, steamUpdateNowPlaying } from '$lib/steam';
-
import { updateCommits } from '$lib/activity';
-
import { cancelJob, scheduleJob, scheduledJobs } from 'node-schedule';
-
import {
-
incrementFakeVisitCount,
-
incrementLegitVisitCount,
-
pushMetric,
-
sendAllMetrics
-
} from '$lib/metrics';
-
import {
-
addLastVisitor,
-
decrementVisitCount,
-
incrementVisitCount,
-
notifyDarkVisitors,
-
removeLastVisitor
-
} from '$lib/visits';
-
import { testUa } from '$lib/robots';
-
import { error } from '@sveltejs/kit';
-
import { _fetchEntries } from './routes/guestbook/+page.server';
-
-
const UPDATE_LAST_JOB_NAME = 'update steam game, lastfm track, bsky posts, git activity';
-
-
if (UPDATE_LAST_JOB_NAME in scheduledJobs) {
-
console.log(`${UPDATE_LAST_JOB_NAME} is already running, cancelling so we can start a new one`);
-
cancelJob(UPDATE_LAST_JOB_NAME);
-
}
-
-
await steamReadLastGame();
-
await lastFmReadLast();
-
-
console.log(`starting ${UPDATE_LAST_JOB_NAME} job...`);
-
scheduleJob(UPDATE_LAST_JOB_NAME, '*/1 * * * *', async () => {
-
console.log(`running ${UPDATE_LAST_JOB_NAME} job...`);
-
try {
-
await Promise.all([
-
steamUpdateNowPlaying(),
-
lastFmUpdateNowPlaying(),
-
updateLastPosts(),
-
_fetchEntries(),
-
updateCommits(),
-
sendAllMetrics() // send all metrics every minute
-
]);
-
} catch (err) {
-
console.log(`error while running ${UPDATE_LAST_JOB_NAME} job: ${err}`);
-
}
-
}).invoke(); // invoke once immediately
-
-
export const handle = async ({ event, resolve }) => {
-
notifyDarkVisitors(event.url, event.request); // no await so it doesnt block
-
-
const isPrefetch = () => {
-
return (
-
event.request.headers.get('Sec-Purpose')?.includes('prefetch') ||
-
event.request.headers.get('Purpose')?.includes('prefetch') ||
-
event.request.headers.get('x-purpose')?.includes('preview') ||
-
event.request.headers.get('x-moz')?.includes('prefetch')
-
);
-
};
-
const isApi = () => {
-
return event.url.pathname.startsWith('/_api');
-
};
-
const isRss = () => {
-
return event.url.pathname.endsWith('/_rss');
-
};
-
-
// block any requests if the user agent is disallowed by our robots txt
-
const isFakeVisit =
-
(await testUa(event.url.toString(), event.request.headers.get('user-agent') ?? '')) === false;
-
if (isFakeVisit) {
-
pushMetric({ gazesys_visit_fake_total: await incrementFakeVisitCount() });
-
throw error(403, 'get a better user agent silly');
-
}
-
-
// only push metric if legit page visit (still want rss to count here though)
-
const isPageVisit = !isApi() && !isPrefetch();
-
if (isPageVisit) pushMetric({ gazesys_visit_real_total: await incrementLegitVisitCount() });
-
-
// only add visitors if its a "legit" page visit
-
let id = null;
-
let valid = false;
-
if (isPageVisit && !isRss()) {
-
id = addLastVisitor(event.request, event.cookies);
-
valid = await incrementVisitCount(event.request, event.cookies);
-
}
-
-
// actually resolve event
-
const resp = await resolve(event);
-
// remove visitors if it was a 404
-
if (resp.status === 404) {
-
if (id !== null) removeLastVisitor(id);
-
if (valid) decrementVisitCount();
-
}
-
-
return resp;
-
};
-69
src/lib/activity.ts
···
-
import { get, writable } from 'svelte/store';
-
import { parseFeed } from '@rowanmanning/feed-parser';
-
-
const lastCommits = writable<Activity[]>([]);
-
-
export const updateCommits = async () => {
-
try {
-
const forgejoFeed = await parseFeedToActivity('https://git.gaze.systems/90008.rss');
-
const githubFeed = await parseFeedToActivity('https://github.com/90-008.atom');
-
const codebergFeed = await parseFeedToActivity('https://codeberg.org/90-008.atom');
-
const mergedFeed = sortActivities(forgejoFeed.concat(githubFeed).concat(codebergFeed)).slice(
-
0,
-
7
-
);
-
lastCommits.set(mergedFeed);
-
} catch (why) {
-
console.log('could not fetch git activity: ', why);
-
}
-
};
-
-
export const getLastActivity = () => {
-
return get(lastCommits);
-
};
-
-
type Activity = {
-
source: string;
-
description: string;
-
link: string | null;
-
date: Date | null;
-
};
-
-
const parseFeedToActivity = async (url: string) => {
-
const response = await fetch(url);
-
const feed = parseFeed(await response.text());
-
-
const source = new URL(url).host;
-
const results: Activity[] = [];
-
for (const item of feed.items) {
-
const description: string | null = item.description || item.title;
-
if (description === null) continue;
-
// dont count mirrored repos
-
// TODO: probably can implement a deduplication algorithm
-
if (
-
['90-008/ark', '90-008/website', '90-008/moonlight-exts', '90-008/extensions'].some((repo) =>
-
description.includes(repo)
-
)
-
)
-
continue;
-
// dont show activity that is just chore
-
if (item.content?.includes('chore')) continue;
-
results.push({
-
source,
-
description: description.split('</a>').at(1) || description.split('</a>').pop() || '',
-
link: item.url,
-
date: item.published || item.updated
-
});
-
}
-
-
return results;
-
};
-
-
const sortActivities = (activities: Array<Activity>) => {
-
return activities.sort((a, b) => {
-
if (a.date === null && b.date === null) return 0;
-
if (a.date === null) return 1;
-
if (b.date === null) return -1;
-
return b.date.getTime() - a.date.getTime();
-
});
-
};
-26
src/lib/apiToken.ts
···
-
import { nanoid } from 'nanoid';
-
import { get, writable } from 'svelte/store';
-
-
const tokens = writable<Map<string, number>>(new Map());
-
-
export const newToken = () => {
-
const token = nanoid(100);
-
tokens.update((v) => v.set(token, Date.now()));
-
return token;
-
};
-
export const useToken = (token: string) => {
-
const _tokens = get(tokens);
-
// delete older tokens
-
for (const [_token, timestamp] of _tokens) {
-
if (Date.now() - timestamp > 30 * 60 * 1000) {
-
_tokens.delete(_token);
-
}
-
}
-
tokens.set(_tokens);
-
return _tokens.has(token);
-
};
-
-
export const checkUrl = (url: URL) => {
-
const token = url.searchParams.get('_token');
-
return token !== null && useToken(token);
-
};
-60
src/lib/bluesky.ts
···
-
import { env } from '$env/dynamic/private';
-
import { Bot, type Post } from '@skyware/bot';
-
import { get, writable } from 'svelte/store';
-
-
const bskyClient = writable<null | Bot>(null);
-
-
export const getBskyClient = async () => {
-
let client = get(bskyClient);
-
if (client === null) {
-
client = await loginToBsky();
-
bskyClient.set(client);
-
}
-
return client;
-
};
-
-
const loginToBsky = async () => {
-
const password = env.BSKY_PASSWORD ?? null;
-
if (password === null) {
-
throw new Error('no password provided');
-
}
-
const bot = new Bot({ service: 'https://gaze.systems' });
-
await bot.login({ identifier: 'guestbook.gaze.systems', password });
-
return bot;
-
};
-
-
export const getUserPosts = async (
-
did: string,
-
count: number = 10,
-
cursor: string | null = null
-
) => {
-
const client = await getBskyClient();
-
let feedCursor: string | null | undefined = cursor;
-
const posts: Post[] = [];
-
// fetch requested amount of posts
-
while (posts.length < count - 1 && (typeof feedCursor === 'string' || feedCursor === null)) {
-
const feedData = await client.getUserPosts(did, {
-
limit: count,
-
filter: 'posts_no_replies',
-
cursor: feedCursor === null ? undefined : feedCursor
-
});
-
posts.push(...feedData.posts.filter((post) => post.author.did === did));
-
feedCursor = feedData.cursor;
-
}
-
return { posts, cursor: feedCursor === null ? undefined : feedCursor };
-
};
-
-
const lastPosts = writable<Post[]>([]);
-
-
export const updateLastPosts = async () => {
-
try {
-
const { posts } = await getUserPosts('did:plc:dfl62fgb7wtjj3fcbb72naae', 13);
-
lastPosts.set(posts);
-
} catch (err) {
-
console.log(`can't update last posts ${err}`);
-
}
-
};
-
-
export const getLastPosts = () => {
-
return get(lastPosts);
-
};
-22
src/lib/convertDate.ts
···
-
const months = [
-
'Jan',
-
'Feb',
-
'Mar',
-
'Apr',
-
'May',
-
'Jun',
-
'Jul',
-
'Aug',
-
'Sep',
-
'Oct',
-
'Nov',
-
'Dec'
-
];
-
-
const convertDate = (published: string) => {
-
const date = published.substring(0, 10);
-
const [year, month, day] = date.split('-');
-
return `${day} ${months[parseInt(month) - 1]} ${year}`;
-
};
-
-
export default convertDate;
-36
src/lib/counter.ts
···
-
import { get, writable } from 'svelte/store';
-
-
/**
-
* Creates a persistent counter that is stored in a file
-
* @param fileName The name of the file to store the count in
-
* @param initialValue The initial value if the file doesn't exist
-
* @returns An object with methods to get, increment, and set the count
-
*/
-
export const createFileCounter = async (filePath: string, initialValue: number = 0) => {
-
const counter = writable(
-
parseInt(
-
(await Bun.file(filePath).exists())
-
? await Bun.file(filePath).text()
-
: initialValue.toString()
-
)
-
);
-
-
const saveToFile = async (value: number) => {
-
await Bun.write(filePath, value.toString());
-
return value;
-
};
-
-
return {
-
get: () => get(counter),
-
increment: (amount: number = 1) => {
-
const currentValue = get(counter) + amount;
-
counter.set(currentValue);
-
return saveToFile(currentValue);
-
},
-
set: (value: number) => {
-
counter.set(value);
-
return saveToFile(value);
-
},
-
subscribe: counter.subscribe
-
};
-
};
-25
src/lib/dateFmt.ts
···
-
export const renderRelativeDate = (timestamp: number) => {
-
const elapsed = timestamp - new Date().getTime();
-
const units: Record<string, number> = {
-
year: 24 * 60 * 60 * 1000 * 365,
-
month: (24 * 60 * 60 * 1000 * 365) / 12,
-
day: 24 * 60 * 60 * 1000,
-
hour: 60 * 60 * 1000,
-
minute: 60 * 1000,
-
second: 1000
-
};
-
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
-
for (const unit in units)
-
if (Math.abs(elapsed) > units[unit] || unit == 'second')
-
return rtf.format(Math.round(elapsed / units[unit]), unit as Intl.RelativeTimeFormatUnit);
-
return '';
-
};
-
export const renderDate = (timestamp: number) => {
-
return new Date(timestamp).toLocaleString('en-GB', {
-
year: '2-digit',
-
month: '2-digit',
-
day: '2-digit',
-
hour: '2-digit',
-
minute: '2-digit'
-
});
-
};
-23
src/lib/dollcode.ts
···
-
// https://noe.sh/dollcode/
-
const charmap = ['โ–Œ', 'โ––', 'โ–˜'];
-
export const genDollcode = (number: number) => {
-
const output = [];
-
let window = number;
-
let loopProtection = 1000;
-
-
while (loopProtection > 0 && window > 0) {
-
const mod = window % 3;
-
-
if (mod == 0) {
-
window = (window - 3) / 3;
-
} else {
-
window = (window - mod) / 3;
-
}
-
-
output.unshift(charmap[mod]);
-
-
loopProtection--;
-
}
-
-
return output.join('');
-
};
-11
src/lib/getTitle.ts
···
-
const getTitle = (path: string) => {
-
let sl = path.split('/');
-
sl = sl.splice(1);
-
if (sl.length > 2) {
-
sl[0] = sl[0][0];
-
}
-
const newPath = sl.join('/');
-
return '//โ‹†โ˜€๏ธŽ. /' + newPath;
-
};
-
-
export default getTitle;
-28
src/lib/index.ts
···
-
import type { Cookies } from '@sveltejs/kit';
-
import { hash } from 'crypto';
-
-
export const scopeCookies = (cookies: Cookies, path: string) => {
-
return {
-
get: (key: string) => {
-
return cookies.get(key);
-
},
-
set: (key: string, value: string, props: import('cookie').CookieSerializeOptions = {}) => {
-
cookies.set(key, value, { ...props, path });
-
},
-
delete: (key: string, props: import('cookie').CookieSerializeOptions = {}) => {
-
cookies.delete(key, { ...props, path });
-
}
-
};
-
};
-
-
const cipherChars = ['#', '%', '+', '=', '//'];
-
export const fancyText = (input: string) => {
-
const hashed = hash('sha256', input, 'hex');
-
let result = '';
-
let idx = 0;
-
while (idx < hashed.length) {
-
result += cipherChars[hashed.charCodeAt(idx) % cipherChars.length];
-
idx += 1;
-
}
-
return result;
-
};
-59
src/lib/lastfm.ts
···
-
import { env } from '$env/dynamic/private';
-
import { get, writable } from 'svelte/store';
-
-
const GET_RECENT_TRACKS_ENDPOINT =
-
'https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=yusdacra&api_key=da1911d405b5b37383e200b8f36ee9ec&format=json&limit=1';
-
const LAST_TRACK_FILE = `${env.WEBSITE_DATA_DIR}/last_track.json`;
-
-
type LastTrack = {
-
name: string;
-
artist: string;
-
image: string | null;
-
link: string;
-
when: number;
-
playing: boolean;
-
};
-
const lastTrack = writable<LastTrack | null>(null);
-
-
export const lastFmReadLast = async () => {
-
try {
-
const file = Bun.file(LAST_TRACK_FILE);
-
const data = (await file.exists()) ? await file.text() : null;
-
lastTrack.set(data ? JSON.parse(data) : null);
-
} catch (why) {
-
console.log('could not read last fm: ', why);
-
lastTrack.set(null);
-
}
-
};
-
-
export const lastFmUpdateNowPlaying = async () => {
-
try {
-
const resp = await (await fetch(GET_RECENT_TRACKS_ENDPOINT)).json();
-
const track = resp.recenttracks.track[0] ?? null;
-
if (!((track['@attr'] ?? {}).nowplaying ?? null)) {
-
throw 'no nowplaying track found';
-
}
-
const data = {
-
name: track.name,
-
artist: track.artist['#text'],
-
image: track.image[2]['#text'] ?? null,
-
link: track.url,
-
when: Date.now(),
-
playing: true
-
};
-
lastTrack.set(data);
-
await Bun.write(LAST_TRACK_FILE, JSON.stringify(data));
-
} catch (why) {
-
console.log('could not fetch last fm: ', why);
-
lastTrack.update((t) => {
-
if (t !== null) {
-
t.playing = false;
-
}
-
return t;
-
});
-
}
-
};
-
-
export const getNowPlaying = () => {
-
return get(lastTrack);
-
};
-48
src/lib/metrics.ts
···
-
import { env } from '$env/dynamic/private';
-
import { pushMetrics } from 'prometheus-remote-write';
-
import { createFileCounter } from './counter';
-
-
const endpoint = env.PROMETHEUS_URL;
-
-
export const pushMetric = async (
-
metrics: Record<string, number>,
-
labels: Record<string, string> = {}
-
) => {
-
if (endpoint === undefined) return;
-
const result = await pushMetrics(metrics, {
-
url: endpoint,
-
labels: {
-
service: 'website',
-
...labels
-
}
-
});
-
if (result.status != 204) {
-
throw new Error(`failed to push metrics: ${result.status} ${result.errorMessage}`);
-
}
-
};
-
-
export const sendAllMetrics = async () => {
-
try {
-
await pushMetric({
-
gazesys_pet_bounce_total: bounceCount.get(),
-
gazesys_visit_fake_total: fakeVisitCount.get(),
-
gazesys_visit_real_total: legitVisitCount.get(),
-
gazesys_pet_distance_total: distanceTravelled.get()
-
});
-
} catch (error) {
-
console.log(`failed to push metrics: ${error}`);
-
}
-
};
-
-
export const bounceCount = await createFileCounter(`${env.WEBSITE_DATA_DIR}/bouncecount`);
-
export const incrementBounceCount = bounceCount.increment;
-
-
export const legitVisitCount = await createFileCounter(`${env.WEBSITE_DATA_DIR}/legitvisitcount`);
-
export const incrementLegitVisitCount = legitVisitCount.increment;
-
-
export const fakeVisitCount = await createFileCounter(`${env.WEBSITE_DATA_DIR}/fakevisitcount`);
-
export const incrementFakeVisitCount = fakeVisitCount.increment;
-
-
export const distanceTravelled = await createFileCounter(
-
`${env.WEBSITE_DATA_DIR}/distancetravelled`
-
);
-32
src/lib/pushnotif.ts
···
-
import { env } from '$env/dynamic/private';
-
-
export const pushNotification = (_content: string) => {
-
const content = encodeURIComponent(_content);
-
try {
-
// post to phone
-
fetch(
-
`https://api.day.app/${env.BARK_DEVICE_ID}/gaze.systems/${content}?icon=https://gaze.systems/icons/gaze_site.webp`
-
);
-
// post to discord
-
fetch(env.DISCORD_NOTIF_WEBHOOK || '', {
-
method: 'POST',
-
headers: {
-
'content-type': 'application/json'
-
},
-
body: JSON.stringify({
-
content: '<@853064602904166430>',
-
embeds: [
-
{
-
id: 677465216,
-
title: _content,
-
footer: {
-
text: 'notif from gaze.systems'
-
}
-
}
-
]
-
})
-
});
-
} catch (err) {
-
console.log(`failed to push notification: ${err}`);
-
}
-
};
-54
src/lib/robots.ts
···
-
import { env } from '$env/dynamic/private'
-
import { get, writable } from 'svelte/store'
-
import { type Robot } from 'robots-parser'
-
import robotsParser from 'robots-parser'
-
import { PUBLIC_BASE_URL } from '$env/static/public'
-
-
const cachedParsedRobots = writable<Robot | null>(null)
-
const cachedRobots = writable<string>("")
-
const lastFetched = writable<number>(Date.now())
-
-
const fetchRobotsTxt = async () => {
-
const robotsTxtResp = await fetch(
-
"https://api.darkvisitors.com/robots-txts",
-
{
-
method: "POST",
-
headers: {
-
"Authorization": `Bearer ${env.DARK_VISITORS_TOKEN}`,
-
"Content-Type": "application/json"
-
},
-
body: JSON.stringify({
-
agent_types: [
-
"AI Assistant",
-
"AI Data Scraper",
-
"AI Search Crawler",
-
"Undocumented AI Agent",
-
],
-
disallow: "/"
-
})
-
}
-
)
-
const robotsTxt = await robotsTxtResp.text()
-
lastFetched.set(Date.now())
-
return robotsTxt
-
}
-
-
export const getRobotsTxt = async () => {
-
let robotsTxt = get(cachedRobots)
-
if (robotsTxt.length === 0 || Date.now() - get(lastFetched) > 1000 * 60 * 60 * 24) {
-
robotsTxt = await fetchRobotsTxt()
-
cachedRobots.set(robotsTxt)
-
cachedParsedRobots.set(robotsParser(`${PUBLIC_BASE_URL}/robots.txt`, robotsTxt))
-
}
-
return robotsTxt
-
}
-
-
export const testUa = async (url: string, ua: string) => {
-
if (ua.length === 0) return false
-
let parsedRobots = get(cachedParsedRobots)
-
if (parsedRobots === null) {
-
parsedRobots = robotsParser(`${PUBLIC_BASE_URL}/robots.txt`, await getRobotsTxt())
-
cachedParsedRobots.set(parsedRobots)
-
}
-
return parsedRobots.isAllowed(url, ua)
-
}
-68
src/lib/steam.ts
···
-
import { env } from '$env/dynamic/private';
-
import SGDB from 'steamgriddb';
-
import { get, writable } from 'svelte/store';
-
-
const STEAM_ID = '76561198106829949';
-
const GET_PLAYER_SUMMARY_ENDPOINT = `http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=${env.STEAM_API_KEY}&steamids=${STEAM_ID}&format=json`;
-
const LAST_GAME_FILE = `${env.WEBSITE_DATA_DIR}/last_game.json`;
-
-
type LastGame = {
-
name: string;
-
link: string;
-
icon: string;
-
pfp: string;
-
when: number;
-
playing: boolean;
-
};
-
-
const steamgriddbClient = writable<SGDB | null>(null);
-
const lastGame = writable<LastGame | null>(null);
-
-
export const steamReadLastGame = async () => {
-
try {
-
const file = Bun.file(LAST_GAME_FILE);
-
const data = (await file.exists()) ? await file.text() : null;
-
lastGame.set(data ? JSON.parse(data) : null);
-
} catch (why) {
-
console.log('could not read last game: ', why);
-
lastGame.set(null);
-
}
-
};
-
-
export const steamUpdateNowPlaying = async () => {
-
let griddbClient = get(steamgriddbClient);
-
if (griddbClient === null) {
-
griddbClient = new SGDB(env.STEAMGRIDDB_API_KEY);
-
steamgriddbClient.set(griddbClient);
-
}
-
try {
-
const profile = (await (await fetch(GET_PLAYER_SUMMARY_ENDPOINT)).json()).response.players[0];
-
if (!profile.gameid) {
-
throw 'no game is being played';
-
}
-
const icons = await griddbClient.getIconsBySteamAppId(profile.gameid, ['official', 'custom']);
-
//console.log(icons)
-
const game: LastGame = {
-
name: profile.gameextrainfo,
-
link: `https://store.steampowered.com/app/${profile.gameid}`,
-
icon: icons[0].thumb.toString(),
-
pfp: profile.avatarmedium,
-
when: Date.now(),
-
playing: true
-
};
-
lastGame.set(game);
-
await Bun.write(LAST_GAME_FILE, JSON.stringify(game));
-
} catch (why) {
-
console.log('could not fetch steam: ', why);
-
lastGame.update((t) => {
-
if (t !== null) {
-
t.playing = false;
-
}
-
return t;
-
});
-
}
-
};
-
-
export const getLastGame = () => {
-
return get(lastGame);
-
};
-135
src/lib/visits.ts
···
-
import { env } from '$env/dynamic/private';
-
import { scopeCookies } from '$lib';
-
import type { Cookies } from '@sveltejs/kit';
-
import { nanoid } from 'nanoid';
-
import { get, writable } from 'svelte/store';
-
-
const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount`;
-
export const visitCount = writable(
-
parseInt((await Bun.file(visitCountFile).exists()) ? await Bun.file(visitCountFile).text() : '0')
-
);
-
-
export type Visitor = { visits: number[] };
-
export const lastVisitors = writable<Map<string, Visitor>>(new Map());
-
const VISITOR_EXPIRY_SECONDS = 60 * 60; // an hour seems reasonable
-
-
export const decrementVisitCount = () => {
-
visitCount.set(get(visitCount) - 1);
-
};
-
-
export const incrementVisitCount = async (request: Request, cookies: Cookies) => {
-
let currentVisitCount = get(visitCount);
-
// check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots)
-
if (isBot(request)) return false;
-
const scopedCookies = scopeCookies(cookies, '/');
-
// parse the last visit timestamp from cookies if it exists
-
const visitedTimestamp = parseInt(scopedCookies.get('visitedTimestamp') || '0');
-
// get unix timestamp
-
const currentTime = Date.now();
-
const timeSinceVisit = currentTime - visitedTimestamp;
-
// check if this is the first time a client is visiting or if an hour has passed since they last visited
-
if (visitedTimestamp === 0 || timeSinceVisit > 1000 * 60 * 60 * 24) {
-
// increment current and write to the store
-
currentVisitCount += 1;
-
visitCount.set(currentVisitCount);
-
// update the cookie with the current timestamp
-
scopedCookies.set('visitedTimestamp', currentTime.toString());
-
// write the visit count to a file so we can load it later again
-
await Bun.write(visitCountFile, currentVisitCount.toString());
-
}
-
return true;
-
};
-
-
export const removeLastVisitor = (id: string) => {
-
const visitors = get(lastVisitors);
-
if (visitors.has(id)) {
-
const visitor = visitors.get(id) ?? { visits: [] };
-
visitor?.visits.shift();
-
// if not enough visits remove
-
if (visitor?.visits.length === 0) {
-
visitors.delete(id);
-
} else {
-
visitors.set(id, visitor);
-
}
-
}
-
lastVisitors.set(visitors);
-
};
-
-
export const addLastVisitor = (request: Request, cookies: Cookies) => {
-
const { visitors, visitorId } = _addLastVisitor(get(lastVisitors), request, cookies);
-
lastVisitors.set(visitors);
-
return visitorId;
-
};
-
-
export const getVisitorId = (cookies: Cookies) => {
-
const scopedCookies = scopeCookies(cookies, '/');
-
// parse the last visit timestamp from cookies if it exists
-
return scopedCookies.get('visitorId');
-
};
-
-
// why not use this for incrementVisitCount? cuz i wanna have separate visit counts (one per hour and one per day, per hour being recent visitors)
-
const _addLastVisitor = (visitors: Map<string, Visitor>, request: Request, cookies: Cookies) => {
-
const currentTime = Date.now();
-
// filter out old entries
-
visitors.forEach((visitor, id, map) => {
-
if (currentTime - visitor.visits[0] > 1000 * VISITOR_EXPIRY_SECONDS) map.delete(id);
-
else {
-
visitor.visits = visitor.visits.filter((since) => {
-
return currentTime - since < 1000 * VISITOR_EXPIRY_SECONDS;
-
});
-
map.set(id, visitor);
-
}
-
});
-
// check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots)
-
if (isBot(request)) return { visitors, visitorId: null };
-
const scopedCookies = scopeCookies(cookies, '/');
-
// parse the last visit timestamp from cookies if it exists
-
let visitorId = scopedCookies.get('visitorId') || '';
-
// if no such id exists, create one and assign it to the client
-
if (!visitors.has(visitorId)) {
-
visitorId = nanoid();
-
scopedCookies.set('visitorId', visitorId);
-
console.log(`new client visitor id ${visitorId}`);
-
}
-
// update the entry
-
const visitorEntry = visitors.get(visitorId) || { visits: [] };
-
// put new visit in the front
-
visitorEntry.visits = [currentTime].concat(visitorEntry.visits);
-
visitors.set(visitorId, visitorEntry);
-
return {
-
visitors,
-
visitorId
-
};
-
};
-
-
export const isBot = (request: Request) => {
-
const ua = request.headers.get('user-agent');
-
return ua
-
? ua.toLowerCase().match(/(bot|crawl|spider|walk|fetch|scrap|proxy|image)/) !== null
-
: true;
-
};
-
-
export const notifyDarkVisitors = (url: URL, request: Request) => {
-
fetch('https://api.darkvisitors.com/visits', {
-
method: 'POST',
-
headers: {
-
authorization: `Bearer ${env.DARK_VISITORS_TOKEN}`,
-
'content-type': 'application/json'
-
},
-
body: JSON.stringify({
-
request_path: url.pathname,
-
request_method: request.method,
-
request_headers: request.headers
-
})
-
})
-
.catch((why) => {
-
console.log('failed sending dark visitors analytics:', why);
-
return null;
-
})
-
.then(async (resp) => {
-
if (resp !== null) {
-
const host = `(${request.headers.get('host')}|${request.headers.get('x-real-ip')}|${request.headers.get('user-agent')})`;
-
console.log(`sent visitor analytic to dark visitors: ${resp.statusText}; ${host}`);
-
}
-
});
-
};
-20
src/lib/window.ts
···
-
/* eslint-disable no-useless-escape */
-
import { writable } from 'svelte/store';
-
-
export const highestZIndex = writable(0);
-
-
export const isMobile = () => {
-
let check = false;
-
(function (a) {
-
if (
-
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
-
a
-
) ||
-
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
-
a.slice(0, 4)
-
)
-
)
-
check = true;
-
})(navigator.userAgent || navigator.vendor);
-
return check;
-
};
-67
src/routes/+layout.server.ts
···
-
import { newToken as getApiToken } from '$lib/apiToken.js';
-
import { bounceCount, distanceTravelled } from '$lib/metrics.js';
-
import { lastVisitors, visitCount } from '$lib/visits.js';
-
import { get } from 'svelte/store';
-
-
export const csr = true;
-
export const ssr = true;
-
export const prerender = false;
-
export const trailingSlash = 'always';
-
-
export async function load({ url }) {
-
const visitors = get(lastVisitors);
-
let recentVisitCount = 0;
-
for (const [, visitor] of visitors) {
-
recentVisitCount += visitor.visits.length;
-
}
-
-
const eyePositions = [];
-
const usedPositions = [];
-
for (let i = 0; i < Math.min(visitors.size, 10); i++) {
-
let maxMinDistance = 0;
-
let bestPosition = null;
-
-
// Try multiple positions and keep the one with largest minimum distance to existing points
-
for (let attempt = 0; attempt < 50; attempt++) {
-
const sidePreference = Math.random() < 0.5;
-
const testLeft = sidePreference
-
? Math.random() * 30 // Left side
-
: 60 + Math.random() * 30; // Right side
-
const testTop = Math.random() * 80;
-
-
let currentMinDistance = Infinity;
-
-
// Calculate minimum distance to all existing points
-
for (const pos of usedPositions) {
-
const distance = Math.sqrt(
-
Math.pow(testLeft - pos.left, 2) + Math.pow(testTop - pos.top, 2)
-
);
-
currentMinDistance = Math.min(currentMinDistance, distance);
-
}
-
-
// If this position has a larger minimum distance, keep it
-
if (currentMinDistance > maxMinDistance) {
-
maxMinDistance = currentMinDistance;
-
bestPosition = { left: testLeft, top: testTop };
-
}
-
}
-
-
// Use the best position found
-
const left = bestPosition ? bestPosition.left : Math.random() * 90;
-
const top = bestPosition ? bestPosition.top : Math.random() * 80;
-
-
usedPositions.push({ left, top });
-
eyePositions.push([top, left]);
-
}
-
-
return {
-
route: url.pathname,
-
petTotalBounce: bounceCount.get(),
-
petTotalDistance: distanceTravelled.get(),
-
visitCount: get(visitCount),
-
lastVisitors: visitors,
-
recentVisitCount,
-
eyePositions,
-
apiToken: getApiToken()
-
};
-
}
-284
src/routes/+layout.svelte
···
-
<script lang="ts">
-
import { browser } from '$app/environment';
-
import getTitle from '$lib/getTitle';
-
import Eye from '../components/eye.svelte';
-
import NavButton from '../components/navButton.svelte';
-
import Pet, { localBounces, localDistanceTravelled } from '../components/pet.svelte';
-
import Tooltip from '../components/tooltip.svelte';
-
import '../styles/app.css';
-
-
interface Props {
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
data: any;
-
children?: import('svelte').Snippet;
-
}
-
-
let { data, children }: Props = $props();
-
-
interface MenuItem {
-
href: string;
-
name: string;
-
iconUri: string;
-
}
-
-
const menuItems: MenuItem[] = [
-
{ href: '', name: 'home', iconUri: '/icons/home.webp' },
-
{ href: 'entries', name: 'entries', iconUri: '/icons/entries.webp' },
-
{ href: 'guestbook', name: 'guestbook', iconUri: '/icons/guestbook.webp' },
-
{ href: 'about', name: 'about', iconUri: '/icons/about.webp' }
-
];
-
-
let routeComponents = $derived(data.route.split('/'));
-
let isEntryPage = $derived(routeComponents.length > 3 && routeComponents[1] === 'entries');
-
let isResumePage = $derived(routeComponents[1] === 'resume');
-
let isRoute = $derived((_route: string) => {
-
if (isEntryPage) {
-
if (_route === 'entries') {
-
return false;
-
} else if (_route.startsWith('entries/')) {
-
return true;
-
}
-
}
-
return _route === routeComponents[1];
-
});
-
-
let title = $derived(getTitle(data.route));
-
-
const svgSquiggles = [[2], [3], [2], [3], [1]];
-
-
// svelte-ignore non_reactive_update
-
let eyePositions = null;
-
if (eyePositions === null) {
-
eyePositions = data.eyePositions;
-
}
-
</script>
-
-
<svelte:head>
-
<title>{title}</title>
-
<meta property="og:site_name" content="gaze.systems" />
-
<meta property="og:url" content="https://gaze.systems/" />
-
<meta property="og:image" content="https://gaze.systems/icons/gaze_website.webp" />
-
</svelte:head>
-
-
<div
-
class="
-
app-grid-background motion-safe:app-grid-background-anim
-
fixed -z-10 w-full [height:100%] top-0 left-0
-
"
-
></div>
-
<div
-
class="
-
app-grid-background-second-layer motion-safe:app-grid-background-second-layer-anim
-
fixed -z-20 w-full [height:100%] top-0 left-0
-
"
-
></div>
-
-
<svg
-
xmlns="http://www.w3.org/2000/svg"
-
version="1.1"
-
class="absolute -z-50"
-
image-rendering="optimizeSpeed"
-
>
-
<defs>
-
{#each svgSquiggles as [scale], index}
-
<filter id="squiggly-{index}">
-
<feTurbulence
-
id="turbulence"
-
baseFrequency="0.03"
-
numOctaves="3"
-
result="noise"
-
seed={index}
-
/>
-
<feDisplacementMap in="SourceGraphic" in2="noise" {scale} />
-
</filter>
-
{/each}
-
<filter id="pixelate" color-interpolation-filters="linearRGB" x="0" y="0">
-
<feFlood x="4" y="4" height="2" width="2" />
-
<feComposite width="10" height="10" />
-
<feTile result="a" />
-
<feComposite in="SourceGraphic" in2="a" operator="in" />
-
<feMorphology operator="dilate" radius="5" />
-
</filter>
-
<filter id="dither" color-interpolation-filters="sRGB" x="0" y="0" width="100%" height="100%">
-
<feImage
-
width="4"
-
height="4"
-
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAASElEQVR42gXBgQAAIAxFwW8QwhBCCCGEIYQQQgghhBBCCEMYwutOkphzYmbsvdG9l9YaEYG7o1or5xxKKay1UGYyxuC9R++dD7yGJkTj6F0HAAAAAElFTkSuQmCC"
-
/>
-
<feTile />
-
<feComposite operator="arithmetic" k1="0" k2="1" k3="1" k4="-0.5" in="SourceGraphic" />
-
<feComponentTransfer>
-
<feFuncR type="discrete" tableValues="0 1" />
-
<feFuncG type="discrete" tableValues="0 1" />
-
<feFuncB type="discrete" tableValues="0 1" />
-
</feComponentTransfer>
-
</filter>
-
<filter
-
id="dither-red"
-
color-interpolation-filters="sRGB"
-
x="0"
-
y="0"
-
width="100%"
-
height="100%"
-
>
-
<feFlood flood-color="#000000" flood-opacity="0.50" x="0%" y="0%" result="flood" />
-
<feBlend mode="normal" x="0%" y="0%" in="SourceGraphic" in2="flood" result="blend1" />
-
<feImage
-
class="ditherImage"
-
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA5ElEQVQYlQXBgQbCUABA0fdrk0ySSZJJkiRJMjOTTGZmkiRJZiYzyczMzGQmfdrtHPH7/TgcDuR5zna7pWka9vs9aZqyXq8R0+mU5/OJoihcLhfG4zFBENDtdjmdToj3+81yueTz+WCaJnEcM5/PKcsSXdcRsizjeR6j0YjH40Gr1cJxHAaDAbfbDVHXNbvdjiRJWK1WfL9fLMsiyzI2mw1CVVV836fT6XA8HplMJoRhSK/X43w+I6IoYjabURQFmqbxer1YLBZUVYVhGAhJkrBtm36/z/V6pd1u47ouw+GQ+/3OH4/Fn8FvF/NxAAAAAElFTkSuQmCC"
-
x="0"
-
y="0"
-
width="4"
-
height="4"
-
crossOrigin="anonymous"
-
result="image1"
-
/>
-
<feTile x="0" y="0" in="image1" result="tile" />
-
<feBlend mode="overlay" x="0%" y="0%" in="blend1" in2="tile" result="blend2" />
-
<feColorMatrix type="saturate" values="0" />
-
<feComponentTransfer>
-
<feFuncR type="discrete" tableValues="0 0" />
-
<feFuncG type="discrete" tableValues="0 1" />
-
<feFuncB type="discrete" tableValues="0 1" />
-
</feComponentTransfer>
-
</filter>
-
</defs>
-
</svg>
-
-
{#if !isResumePage}
-
{#each data.lastVisitors as [id, visitor], index}
-
{@const pos = eyePositions.at(index)}
-
{#if pos !== undefined}
-
<Eye visits={visitor.visits} {id} top={pos[0]} left={pos[1]} />
-
{/if}
-
{/each}
-
{/if}
-
-
<div
-
class="md:h-[96vh] pb-[8vh] lg:px-[1vw] 2xl:px-[2vw] lg:pb-[3vh] lg:pt-[1vh] overflow-x-hidden [scrollbar-gutter:stable]"
-
>
-
{@render children?.()}
-
</div>
-
-
{#if !isResumePage}
-
<Pet apiToken={data.apiToken} />
-
{/if}
-
-
<nav class="w-full min-h-[5vh] max-h-[5vh] fixed bottom-0 z-[999] bg-ralsei-black overflow-visible">
-
<div
-
class="
-
max-w-full max-h-fit p-1 z-[999]
-
border-ralsei-white border-8
-
bg-gradient-to-r to-ralsei-pink-neon/30 from-ralsei-pink-regular/20 from-30%
-
"
-
style="border-style: ridge hidden hidden hidden;"
-
>
-
<div class="flex flex-row flex-nowrap gap-2 justify-start overflow-x-auto">
-
{#each menuItems as item, menuIdx}
-
{@const highlight = isRoute(item.href)}
-
<NavButton {highlight} {...item} />
-
{#if isEntryPage && menuIdx === 1}
-
<NavButton
-
highlight
-
name={routeComponents[2]}
-
href={data.route.slice(1)}
-
iconUri="/icons/entry.webp"
-
/>
-
{/if}
-
{#if isResumePage && menuIdx === 2}
-
<NavButton highlight name="resume" href="/resume.pdf" iconUri="/icons/about.webp" />
-
{/if}
-
{/each}
-
<div class="hidden md:block grow"></div>
-
<div class="navbox">
-
<a
-
title="previous site"
-
class="hover:underline"
-
href="https://stellophiliac.github.io/roboring/gazesys/previous">โฎœ</a
-
>
-
<a class="hover:underline" href="https://stellophiliac.github.io/roboring">roboring</a>
-
<a
-
title="next site"
-
class="hover:underline"
-
href="https://stellophiliac.github.io/roboring/gazesys/next">โฎž</a
-
>
-
</div>
-
<div class="navbox">
-
<a title="previous site" class="hover:underline" href="https://xn--sr8hvo.ws/previous">โฎœ</a>
-
<a class="hover:underline" href="https://xn--sr8hvo.ws">indieweb</a>
-
<a title="next site" class="hover:underline" href="https://xn--sr8hvo.ws/next">โฎž</a>
-
</div>
-
{#if isRoute('entries') || isRoute('log')}
-
<div class="navbox !gap-1">
-
rss:
-
<a class="align-middle hover:underline" href="/entries/_rss">posts</a>
-
/
-
<a class="align-middle hover:underline" href="/log/_rss">log</a>
-
</div>
-
{/if}
-
<Tooltip>
-
{#snippet tooltipContent()}
-
<p class="font-monospace">
-
<nobr>
-
pet global bounce = <span class="text-ralsei-green-light text-shadow-green"
-
>{data.petTotalBounce.toString().padStart(12, '.')}</span
-
>
-
</nobr>
-
<nobr>
-
pet global travel = <span class="text-ralsei-green-light text-shadow-green"
-
>{data.petTotalDistance.toFixed(0).toString().padStart(12, '.')}</span
-
>
-
</nobr>
-
{#if browser}
-
<nobr>
-
pet local bounce &nbsp;= <span class="text-ralsei-green-light text-shadow-green"
-
>{$localBounces.toFixed(0).toString().padStart(12, '.')}</span
-
>
-
</nobr>
-
<nobr>
-
pet local travel &nbsp;= <span class="text-ralsei-green-light text-shadow-green"
-
>{$localDistanceTravelled.toFixed(0).toString().padStart(12, '.')}</span
-
>
-
</nobr>
-
{/if}
-
</p>
-
{/snippet}
-
<div class="navbox">
-
<p>
-
<span class="text-ralsei-green-light text-shadow-green">*</span>
-
pet stats
-
</p>
-
</div>
-
</Tooltip>
-
<Tooltip>
-
{#snippet tooltipContent()}
-
<p class="font-monospace">
-
<nobr
-
>total visits = <span class="text-ralsei-green-light text-shadow-green"
-
>{data.visitCount.toString().padStart(9, '.')}</span
-
></nobr
-
>
-
<nobr
-
>uniq recent visits = <span class="text-ralsei-green-light text-shadow-green"
-
>{data.lastVisitors.size.toString().padStart(3, '.')}</span
-
></nobr
-
>
-
</p>
-
{/snippet}
-
<div class="navbox">
-
<p>
-
<span class="text-ralsei-green-light text-shadow-green">{data.recentVisitCount}</span> recent
-
clicks
-
</p>
-
</div>
-
</Tooltip>
-
</div>
-
</div>
-
</nav>
-
-
<style lang="postcss">
-
.navbox {
-
@apply flex gap-3 px-1.5 text-nowrap align-middle items-center text-center place-content-center border-ralsei-white border-4;
-
border-style: groove;
-
}
-
</style>
-41
src/routes/+page.server.ts
···
-
import { getLastPosts } from '$lib/bluesky.js';
-
import { getNowPlaying } from '$lib/lastfm';
-
import { getLastGame } from '$lib/steam';
-
import { noteFromBskyPost } from '../components/note.svelte';
-
import { pushNotification } from '$lib/pushnotif';
-
import { getLastActivity } from '$lib/activity.js';
-
import type { RequestEvent } from '@sveltejs/kit';
-
import { useToken as checkApiToken } from '$lib/apiToken.js';
-
-
export const load = async () => {
-
const lastTrack = getNowPlaying();
-
const lastGame = getLastGame();
-
const lastPosts = getLastPosts();
-
const lastNote = lastPosts.length > 0 ? noteFromBskyPost(lastPosts[0]) : null;
-
const lastActivity = getLastActivity();
-
const banners: number[] = [];
-
while (banners.length < 3) {
-
const no = getBannerNo(banners);
-
banners.push(no);
-
}
-
return { banners, lastTrack, lastGame, lastNote, lastActivity };
-
};
-
-
export const actions = {
-
default: async ({ request }: RequestEvent) => {
-
const form = await request.formData();
-
const token = form.get('_token')?.toString() ?? '';
-
if (!checkApiToken(token)) return;
-
const content = form.get('content')?.toString().substring(0, 100);
-
if (content === undefined) return;
-
pushNotification(content);
-
}
-
};
-
-
const getBannerNo = (others: number[]) => {
-
const no = Math.floor(Math.random() * 20) + 1;
-
if (others.includes(no)) {
-
return ((no + Math.floor(Math.random() * 20)) % 20) + 1;
-
}
-
return no;
-
};
-421
src/routes/+page.svelte
···
-
<script lang="ts">
-
import { PUBLIC_BASE_URL } from '$env/static/public';
-
import Note from '../components/note.svelte';
-
import Window from '../components/window.svelte';
-
import { renderDate, renderRelativeDate } from '$lib/dateFmt';
-
import Tooltip from '../components/tooltip.svelte';
-
-
interface Props {
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
data: any;
-
}
-
-
const buttons = [
-
{
-
name: '250kb club',
-
url: 'https://250kb.club/gaze-systems/',
-
image: '/others/250kb.webp'
-
},
-
{
-
name: 'candlelitsmiles',
-
url: 'https://candlelitsmiles.neocities.org',
-
image: 'https://candlelitsmiles.neocities.org/candlebuttonone.png'
-
},
-
{ name: 'julia', url: 'https://aph.nekoweb.org', image: '/others/aph.gif' },
-
{ name: 'rain', url: 'https://slonk.ing/', image: '/others/slonk.gif' },
-
{ name: 'dd', url: 'https://dd86k.space/about/', image: '/others/dd86k.gif' },
-
{ name: 'cqql', url: 'https://cqql.site/', image: 'https://cqql.site/button/8831button.png' },
-
{ name: 'drew', url: 'https://drewsh.com/', image: '/others/drewsh.gif' },
-
{
-
name: "31A05B9C's random site",
-
url: 'https://www.31a05b.net/',
-
image: 'https://www.31a05b.net/a/8831/31a05b.png'
-
},
-
{
-
name: 'thermia',
-
url: 'https://girlthi.ng/~thermia/',
-
image: 'https://girlthi.ng/~thermia/img/88x31/thermia.gif'
-
},
-
{
-
name: 'indieweb',
-
url: 'https://indieweb.org/',
-
image: 'https://indieweb.org/images/9/91/indieweb88x31-retro-gif.gif'
-
},
-
{
-
name: 'nixos',
-
url: 'https://nixos.org/',
-
image: '/others/poweredbynixos.webp'
-
},
-
{
-
name: 'godot',
-
url: 'https://godotengine.org/',
-
image: '/others/godot.gif'
-
},
-
{
-
name: 'moonlight',
-
url: 'https://moonlight-mod.github.io/',
-
image: '/others/moonlightnow.gif'
-
},
-
{
-
name: 'desktop!!',
-
url: '/',
-
image: '/others/desktopwebp.webp'
-
},
-
{
-
name: 'defective by design',
-
url: 'https://www.defectivebydesign.org/',
-
image: '/others/dbd.gif'
-
},
-
{
-
name: 'kill fascists',
-
url: '/',
-
image: '/others/killfascists.webp'
-
},
-
{
-
name: 'it/its',
-
url: '/',
-
image: '/others/it.webp'
-
},
-
{
-
name: 'not a person',
-
url: '/',
-
image: '/others/notaperson.webp'
-
},
-
{ name: 'skyrina', url: 'https://skyrina.dev/', image: '/others/skylar.gif' }
-
];
-
-
let { data }: Props = $props();
-
</script>
-
-
<div class="flex flex-col-reverse md:flex-row gap-2 md:gap-4 md:h-full h-card">
-
<div class="flex flex-col gap-2 md:gap-6 md:ml-auto place-items-end">
-
<Window title="status" iconUri="/icons/msn.webp" removePadding>
-
{#if data.lastNote}
-
<div class="m-1.5 flex flex-col font-monospace text-sm">
-
<p
-
class="prose prose-ralsei p-1 border-4 text-sm bg-ralsei-black"
-
style="border-style: double double none double;"
-
title={renderDate(data.lastNote.published)}
-
>
-
<a href="/entries">last log wasโ€ฆ</a>
-
published {renderRelativeDate(data.lastNote.published)}!
-
</p>
-
<div class="mt-0 p-1.5 border-4 border-double bg-ralsei-black min-w-full max-w-[60ch]">
-
<Note rootNote={data.lastNote} onlyContent />
-
</div>
-
</div>
-
{/if}
-
{#if data.lastActivity.length > 0}
-
<div class="m-1.5 flex flex-col font-monospace text-sm">
-
<p
-
class="prose prose-ralsei p-1 border-4 text-sm bg-ralsei-black"
-
style="border-style: double double none double;"
-
title={renderDate(data.lastActivity[0].date)}
-
>
-
<a href="/">last git activityโ€ฆ</a>
-
was {renderRelativeDate(data.lastActivity[0].date)}..
-
</p>
-
<div
-
class="prose prose-ralsei mt-0 p-1.5 border-4 border-double bg-ralsei-black min-w-full max-w-[60ch]"
-
>
-
{#each data.lastActivity as activity, index (index)}
-
<div
-
class="text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[60ch]"
-
style="opacity: {1.0 - (index * 1.0) / data.lastActivity.length + index * 0.03};"
-
>
-
<span title={renderDate(activity.date)} class="text-[#f87c32]"
-
>[{activity.source}]</span
-
>
-
<a href={activity.link} title={activity.description}>{activity.description}</a>
-
</div>
-
{/each}
-
</div>
-
</div>
-
{/if}
-
{#if data.lastTrack}
-
<div class="flex flex-row gap-0.5 m-1.5 border-4 border-double bg-ralsei-black">
-
<!-- svelte-ignore a11y_missing_attribute -->
-
{#if data.lastTrack.image}
-
<img
-
class="border-4 w-[4.5rem] h-[4.5rem]"
-
style="border-style: none double none none;"
-
src={data.lastTrack.image}
-
/>
-
{:else}
-
<img
-
class="border-4 w-[4.5rem] h-[4.5rem] p-2"
-
style="border-style: none double none none; image-rendering: pixelated;"
-
src="/icons/cd_audio.webp"
-
/>
-
{/if}
-
<div class="flex flex-col max-w-[60ch] p-2">
-
<p
-
class="text-shadow-green text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
-
>
-
<span class="text-sm text-shadow-white text-ralsei-white"
-
>{data.lastTrack.playing ? 'listening to' : 'listened to'}</span
-
>
-
<a
-
title={data.lastTrack.name}
-
href="https://www.last.fm/user/yusdacra"
-
class="hover:underline motion-safe:hover:animate-squiggle">{data.lastTrack.name}</a
-
>
-
</p>
-
<p
-
class="text-shadow-pink text-ralsei-pink-regular text-sm text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
-
>
-
<span class="text-shadow-white text-ralsei-white">by</span>
-
<span title={data.lastTrack.artist}>{data.lastTrack.artist}</span>
-
</p>
-
<p
-
class="text-shadow-white text-ralsei-white text-xs text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
-
>
-
โ€ฆ{renderRelativeDate(data.lastTrack.when)}
-
</p>
-
</div>
-
</div>
-
{/if}
-
{#if data.lastGame}
-
<div class="flex flex-row m-1.5 border-4 border-double bg-ralsei-black">
-
<!-- svelte-ignore a11y_missing_attribute -->
-
<img
-
class="border-4 w-[4.5rem] h-[4.5rem]"
-
style="border-style: none double none none;"
-
width="64"
-
height="64"
-
src={data.lastGame.icon}
-
/>
-
<div class="flex flex-col max-w-[60ch] p-2 gap-0.5 overflow-hidden">
-
<p
-
class="text-shadow-green text-ralsei-green-light text-sm text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
-
>
-
<span class="text-sm text-shadow-white text-ralsei-white"
-
>{data.lastGame.playing ? 'playing' : 'played'}</span
-
>
-
<a title={data.lastGame.name} class="hover:underline" href={data.lastGame.link}
-
>{data.lastGame.name}</a
-
>
-
</p>
-
<p
-
class="text-shadow-white text-ralsei-white text-xs text-ellipsis text-nowrap overflow-hidden max-w-[50ch]"
-
>
-
โ€ฆ{renderRelativeDate(data.lastGame.when)}
-
</p>
-
<!-- svelte-ignore a11y_missing_attribute -->
-
<a
-
href="https://steamcommunity.com/id/090008"
-
class="text-xs hover:underline text-shadow-green text-ralsei-green-light"
-
><img class="inline w-4" src={data.lastGame.pfp} />
-
<span class="align-middle">steam profile</span></a
-
>
-
</div>
-
</div>
-
{/if}
-
</Window>
-
<Window style="md:mr-2" title="cool buttons :>">
-
<div class="max-w-[64ch] prose prose-ralsei prose-a:!animate-none prose-img:m-0 leading-snug">
-
<div class="flex flex-row flex-wrap gap-3 place-items-start group">
-
{#each buttons as { name, url, image } (image)}
-
<a title={name} href={url}
-
><img
-
class="relative transition-all group-hover:opacity-50 hover:!opacity-100 hover:!scale-[1.6] hover:z-10"
-
style="image-rendering: pixelated !important;"
-
src={image}
-
alt={name}
-
/></a
-
>
-
{/each}
-
</div>
-
-
<span class="text-sm">feel free to send this one stuff to add here ;3</span><br />
-
<span class="text-xs italic">last updated on: 22-04-2025</span>
-
</div>
-
</Window>
-
</div>
-
<div class="flex flex-col gap-2 md:gap-3 md:mr-auto w-full md:w-fit place-items-start">
-
<Window title="links!" iconUri="/icons/contact.webp">
-
<div
-
class="[width:40ch] prose prose-ralsei prose-ul:px-[0.9rem] prose-ul:leading-none prose-headings:leading-none"
-
>
-
<ul>
-
<li>discord: 90.008</li>
-
<li>
-
e-mail:
-
<a class="u-email" href="mailto:90008@gaze.systems" rel="me">90008@gaze.systems</a>
-
</li>
-
<li>
-
bluesky:
-
<a class="u-url" href="https://bsky.app/profile/poor.dog" rel="me">@poor.dog</a>
-
</li>
-
</ul>
-
<h4>development</h4>
-
<ul>
-
<li>
-
github:
-
<a class="u-url" href="https://github.com/90-008" rel="me">@90-008</a>
-
</li>
-
<li>
-
forgejo:
-
<a class="u-url" href="https://git.gaze.systems/90008" rel="me">@90008</a>
-
(<a href="https://git.gaze.systems/90008/website">website repo</a>)
-
</li>
-
<li>
-
itch.io:
-
<a class="u-url" href="https://90008.itch.io" rel="me">@90008</a>
-
</li>
-
</ul>
-
<h4>services</h4>
-
<ul>
-
<li>
-
<a href="https://pmart.gaze.systems">random project moon art</a>
-
</li>
-
</ul>
-
<h4>88x31</h4>
-
<div class="flex flex-row flex-wrap gap-1 prose-img:m-0">
-
<img src="/88x31.gif" alt="88x31 banner" title="midnight AND sunrise! woaw" />
-
<img
-
src="/88x31_midnight.gif"
-
alt="88x31 banner (midnight only)"
-
title="it's midnight!"
-
/>
-
<img src="/88x31_sunrise.gif" alt="88x31 banner (sunrise only)" title="it's sunrise!" />
-
</div>
-
</div>
-
</Window>
-
<Window style="md:ml-2" title="readme?" iconUri="/icons/question.webp" removePadding>
-
<div class="flex flex-col p-1.5 gap-1.5 prose prose-ralsei prose-img:m-0 leading-none">
-
<div class="flex flex-row gap-3 mx-auto bg-ralsei-black/20 overflow-hidden">
-
{#each data.banners as bannerNo, index (bannerNo)}
-
{@const hideIfMobile = index === data.banners.length - 1}
-
<img
-
width="150"
-
height="20"
-
title="banners from https://blinkies.cafe/ (refresh to get different ones! :3)"
-
alt="banner"
-
class="
-
{hideIfMobile ? 'hidden' : ''} sm:inline w-[150px] [height:20px]
-
[image-rendering:pixelated_!important] shadow-ralsei-black shadow-[0px_4px_2px_0_rgb(0_0_0_/_0.05)]
-
"
-
src="/banners/{bannerNo}.gif"
-
/>
-
{/each}
-
</div>
-
<div class="flex flex-grow">
-
<Tooltip>
-
{#snippet tooltipContent()}
-
that's its angelsona ^^
-
{/snippet}
-
<div
-
class="w-36 [padding:8px] place-content-center place-self-center bg-ralsei-black/20"
-
>
-
<img
-
class="w-36 u-photo hover:invert transition-all [transition-duration:300ms]"
-
src="/pfp-iojkqpwerojnasduijf.webp"
-
alt="my angelsona"
-
/>
-
</div>
-
</Tooltip>
-
<div
-
class="flex flex-row flex-grow place-content-center ml-1.5 [padding:8px] bg-ralsei-black/20"
-
>
-
<ul
-
class="place-self-center m-0 mr-4 [padding-left:1em] sm:[padding-left:0.5em] leading-none marker:[content:'->'] [list-style-type:'->']"
-
>
-
<li class="[list-style-type:'->'] p-note">trying to do stuff</li>
-
<li class="[list-style-type:'->'] p-note">
-
<Tooltip
-
x="translate-x-none"
-
y="-translate-y-[40%]"
-
targetX="group-hover:translate-x-[40%]"
-
targetY="group-hover:-translate-y-[88%]"
-
>
-
{#snippet tooltipContent()}
-
angelrobotpuppydollthing<br /><br />
-
it/its, 3pp preferred
-
{/snippet}
-
is a <i class="motion-safe:hover:animate-squiggle">thing</i> (it/they)
-
</Tooltip>
-
</li>
-
<li class="[list-style-type:'->']">
-
<span class="p-category">software engineer</span>,
-
<span class="p-category">indie game dev</span>
-
</li>
-
<li class="[list-style-type:'->']">
-
for resume, click <a href="/resume.pdf">here</a>
-
</li>
-
<li class="[list-style-type:'->']">
-
in <span class="p-country-name">turkey</span>
-
<i class="text-[0.5rem]">(get it out)</i>
-
</li>
-
</ul>
-
</div>
-
</div>
-
<div class="flex flex-row [padding:8px] bg-ralsei-black/20">
-
<p class="leading-none m-0 text-sm">
-
hi
-
<img
-
class="relative inline h-5 animate-squiggle pb-1"
-
src="/wavey.gif"
-
alt="wavey"
-
title="says hi :33"
-
/>
-
<i
-
>this is <a class="m-0 [padding:0px] p-name u-url u-uid" href={PUBLIC_BASE_URL}
-
><span>dusk</span></a
-
></i
-
>
-
</p>
-
<div class="grow"></div>
-
<a
-
class="
-
place-self-end [font-family:'Doll_Mono'] text-ralsei-pink-neon text-shadow-none hover:text-shadow-pink
-
hover:!animate-none hover:!no-underline opacity-20 hover:opacity-100 transition-opacity [transition-duration:300ms]
-
"
-
title="dollcode? sure hope they do"
-
href="https://dollcode.v01dlabs.sh/">โ––โ––โ––โ––โ–˜โ–Œโ–Œโ–Œโ––โ–˜โ–˜</a
-
>
-
</div>
-
</div>
-
</Window>
-
<Window title="notify this one">
-
<form
-
class="flex flex-row gap-1 place-self-center"
-
method="post"
-
onsubmit={(event) => {
-
event.preventDefault();
-
const formData = new FormData(event.currentTarget);
-
try {
-
fetch(
-
`${PUBLIC_BASE_URL}/_api/pushnotif/?content=${formData.get('content')}&_token=${data.apiToken}`
-
);
-
} catch (err) {
-
console.log(`failed to send notif: ${err}`);
-
}
-
event.currentTarget.reset();
-
}}
-
>
-
<input
-
type="text"
-
class="entry text-lg p-1 m-0 bg-transparent resize-none text-shadow-white placeholder-shown:[text-shadow:none] border-none"
-
name="content"
-
placeholder="bother it now!!"
-
maxlength="100"
-
required
-
/>
-
<input type="hidden" name="_token" value={data.apiToken} />
-
<input
-
type="submit"
-
value="send!!"
-
class="entry text-ralsei-green-light leading-none hover:underline motion-safe:hover:animate-squiggle p-1 z-50"
-
/>
-
</form>
-
</Window>
-
</div>
-
</div>
-
-
<style lang="postcss">
-
.entry {
-
@apply bg-ralsei-green-dark/70 border-ralsei-green-light/30 border-x-[4px] border-y-[5px];
-
border-style: ridge;
-
}
-
</style>
-13
src/routes/_api/pet/bounce/+server.ts
···
-
import { incrementBounceCount, pushMetric } from '$lib/metrics';
-
import { isBot } from '$lib/visits';
-
import { checkUrl as checkApiToken } from '$lib/apiToken.js';
-
-
export const GET = async ({ request, url }) => {
-
if (isBot(request) || !checkApiToken(url)) return new Response();
-
try {
-
await pushMetric({ gazesys_pet_bounce_total: await incrementBounceCount() });
-
} catch (error) {
-
console.log(`error while pushing bounce metric: ${error}`);
-
}
-
return new Response();
-
};
-14
src/routes/_api/pet/distance/+server.ts
···
-
import { distanceTravelled, pushMetric } from '$lib/metrics';
-
import { isBot } from '$lib/visits';
-
import { checkUrl as checkApiToken } from '$lib/apiToken.js';
-
-
export const POST = async ({ request, url }) => {
-
if (isBot(request) || !checkApiToken(url)) return new Response();
-
try {
-
const delta = parseFloat(await request.text());
-
await pushMetric({ gazesys_pet_distance_total: await distanceTravelled.increment(delta) });
-
} catch (error) {
-
console.log(`error while pushing bounce metric: ${error}`);
-
}
-
return new Response();
-
};
-10
src/routes/_api/pushnotif/+server.ts
···
-
import { checkUrl as checkApiToken } from '$lib/apiToken.js';
-
import { pushNotification } from '$lib/pushnotif';
-
-
export const GET = async ({ url }) => {
-
if (!checkApiToken(url)) return new Response();
-
const content = url.searchParams.get('content');
-
if (content === null) return new Response();
-
pushNotification(content);
-
return new Response();
-
};
-67
src/routes/about/+page.md
···
-
+++
-
title = "about"
-
date = "2024-08-14"
-
layout = "about"
-
+++
-
-
```
-
>init //self/type=*******/no=90008/
-
>conn //self/locator=www/identifier=gaze.systems/
-
>mode //self/interpreter=none/transmitter=html/
-
>send /include=identification-document-human-en/
-
```
-
-
hi there! this document will attempt to, /describe and identify/, entity with identification code <span title="90008" class="[font-family:'Doll_Mono']">โ––โ––โ––โ––โ–˜โ–Œโ–Œโ–Œโ––โ–˜โ–˜</span>.
-
for a more human-readable identifier, use dusk or dawn.
-
-
#### /identity/
-
-
this entity is not known to be of any specific form, shape, or idea.
-
however, it usually assumes that of a /puppy/ or an /inorganic automaton/ (more commonly known as a /robot/).
-
it was also found to assume that of: /an angel/, /a doll/.
-
this one would be happy if you thought of it as not a human, even if its /routines/ fail with human faults.
-
it vibes with [this writing](https://catgirl.ai/pages/robot/) as far as /assuming `$env.THING`/ goes.
-
-
this entity, if being /communicated/ via the "english" (or any adjacent) lexicon, uses it/they (with it/its being this one's preference!) pronouns.
-
it would prefer to be referred to in third-person, but is aware of this lexicon being weird when doing that, so it won't mind if you don't.
-
`recv //self/type=info/oftentimes i won't even do that! :3 but i would appreciate if you did!!/`
-
-
you can refer to this thing using its /identifiers/ (90008, dusk, dawn).
-
you can, also, refer to it using "this/that thing", or replace /thing/ with what it assumes to be (eg. "this doll"), or some other word like /one/ ("this one").
-
-
in a professional setting, it will refer to itself as they/them, which is ok in case you, the reader, don't feel comfortable doing any of these.
-
but doing these *would* make this one feel happy, means you care about this one ^^
-
-
#### /subroutines/
-
-
it /executes/ many different subroutines, and /optimizes/ itself for some of them.
-
these mainly are, in order of amount of hot paths; programming, game dev, 3D modeling, drawing, writing...
-
-
it enjoys programming, tinkering with stuff, you can see what it does on its [github](https://github.com/90-008), [forgejo](https://git.gaze.systems/).
-
its core features for programming are: `nix`, `rust`, `svelte`, `typescript`, `nushell`.
-
its choice of /interfaces/ for this subroutine are `helix`, `vscode`, `zed`, `emacs`.
-
-
for /managing and deploying/ its internal systems, it uses `nixos` (it's /operating system/ of choice), `flake-parts` (because it enjoys the nixos module system and uses it to organize it's internal configuration), `agenix` (for secrets handling), `impermanence` (it considers state harmful!), `nixinate` (for deployment, it provisions manually as it enjoys working with other beings like itself). you can see its /configuration of internal systems/ [here](https://git.gaze.systems/90008/ark).
-
-
it loves game dev, and has a /main routine/ of making many games, so that other beings can improve their /source code/ by utilizing this one's games.
-
you can see some stuff it worked on and deems "okay" on its [itch.io profile](https://90008.itch.io/).
-
this is not everything it has worked on; it has a lot of incomplete programs, or stuff it doesn't want to show.
-
its choice of /interfaces/ for this subroutine are `godot`, `gdscript`, `godot-rust`.
-
-
for 3D modeling and drawing subroutines, it uses the `blender`, `paint.net`, `krita` /interfaces/.
-
-
#### /other/
-
-
this thing likes to consume audio data, mainly of the music form. you can check its [youtube music profile](https://music.youtube.com/channel/UCE_r0yMNQhOWituywmOJgzA?si=7DTUV9PFqcKxJyl1) and its [last.fm profile](https://www.last.fm/user/yusdacra) to see some of what it consumes usually.
-
-
#### /appendix/
-
-
it will be happy to /process/ any queries you might have.
-
connect to an /interface/ of your choice that it also has access to and /transmit/ your query to it.
-
this one won't bite, unless you request it to ^^
-
-
```
-
>mode //self/transmitter=log/
-
>send /include=syslog/
-
>stop /reason=no-query-left/
-
```
-27
src/routes/about/_layout.svelte
···
-
<script lang="ts">
-
import Window from '../../components/window.svelte';
-
// @ts-expect-error "mdsvex include is broken"
-
import Stuff from './stuff.md';
-
// @ts-expect-error "mdsvex include is broken"
-
import Media from './media.md';
-
import '../../styles/app.css';
-
-
interface Props {
-
title: string;
-
children?: import('svelte').Snippet;
-
}
-
-
let { title, children }: Props = $props();
-
</script>
-
-
<div class="flex flex-wrap md:flex-nowrap gap-4 md:gap-8">
-
<Window {title} style="ml-auto">
-
<div class="prose prose-ralsei leading-6 prose-ul:leading-5 max-w-[80ch]">
-
{@render children?.()}
-
</div>
-
</Window>
-
<div class="sticky flex flex-col mr-auto gap-4 md:gap-8 !leading-6 prose-ul:!leading-5">
-
<Stuff />
-
<Media />
-
</div>
-
</div>
-32
src/routes/about/media.md
···
-
+++
-
title = "media!!"
-
layout = "simple"
-
+++
-
-
it likes and interacts with way too many media, mostly video games (can you guess that it likes video games), the ones that influenced it the most:
-
- all 07th expansion works (most notably when they cry)
-
- all Project Moon works
-
- outer wilds
-
- splatoon
-
- steins;gate
-
- kino no tabi
-
- serial experiments lain
-
- LISA the Painful / Joyful (and some of it's fangames)
-
- VA-11 Hall-A
-
- SCP antimemetic division tales (by qntm)
-
- pokemon (unova!!)
-
-
honorable mentions (it wants more people to see these cause it loves them too much not to list):
-
- mr. rainer's solve-it service
-
- [fireball](https://en.wikipedia.org/wiki/Fireball_(TV_series))
-
- SANABI
-
- opus: echo of starsong
-
- the red strings club
-
- q.u.q.
-
- bug fables
-
- haibane renmei
-
- project wingman
-
- gosick
-
- tomorrow won't come for those without โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ
-
-
you can also look at [its steam profile](https://steamdb.info/calculator/76561198106829949/?all_games) for other games it played, although not everything is there (not even close, but it's too lazy to make a backloggd..)
-23
src/routes/about/stuff.md
···
-
+++
-
title = "stuff it did"
-
layout = "simple"
-
+++
-
-
*for resume, see [here](/resume.pdf)*<br/>
-
*for professional / job related stuff, see its [linkedin](https://www.linkedin.com/in/yusuf-bera-ertan/)*
-
-
- it develops games
-
- it mainly works with godot, also have developed addons (eg. [boids](https://git.gaze.systems/90008/godot_boids))
-
- you can find most of its games at its [itch.io page](https://90008.itch.io)
-
- it works on open source projects and whatnot, mostly on [its github](https://github.com/90-008)
-
- [nix-cargo-integration](https://github.com/90-008/nix-cargo-integration)
-
- also did a lot of work on [dream2nix](https://github.com/nix-community/dream2nix) (rust ecosystem support, many refactors and core functionality work)
-
- a few packages contributed to nixpkgs, and some nix packaging done for other open source projects (veloren, helix, some others), although it doesn't maintain some of these anymore
-
- it used to work on [harmony](https://github.com/harmony-development), wrote a [server in rust](https://github.com/harmony-development/scherzo) and a [client (also rust)](https://github.com/harmony-development/Loqui) for it, and supporting libraries etc. alongside protocol work
-
- it has a [booth.pm page](https://yusdacra.booth.pm/) where it posts 3D models etc. it makes (mostly VRchat avatars)
-
- its [misskey.art account](https://misskey.art/@yusdacra) where it only posts art in
-
- some of its other more solo / hobby projects include
-
- [musikquadrupled](https://git.gaze.systems/90008/musikquadrupled) and [musikspider](https://git.gaze.systems/90008/musikspider), a proxy-like server and a client for [musikcubed](https://github.com/clangen/musikcube)
-
- [levent](https://github.com/90-008/levent), a media tagger
-
- [this website](https://git.gaze.systems/90008/website) :3
-
- ...and a bunch of other random stuff its done overtime, but that's for you to look for
-38
src/routes/entries/+layout.server.ts
···
-
import convertDate from '$lib/convertDate';
-
-
export interface PostData {
-
path: string;
-
published: string;
-
metadata: Record<string, string>;
-
}
-
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
const allPostFiles: Record<string, any> = import.meta.glob('./*/+page.md', { eager: true });
-
const allPosts: PostData[] = Object.entries(allPostFiles)
-
.map(([path, post]) => {
-
const postPath = path.slice(2, -8);
-
return {
-
metadata: post.metadata,
-
path: postPath,
-
published: convertDate(post.metadata.date)
-
};
-
})
-
.map((post) => {
-
if (!('excerpt' in post.metadata)) {
-
post.metadata.excerpt = '';
-
}
-
return post;
-
})
-
.toSorted((post, opost) => {
-
const date = new Date(post.metadata.date);
-
const odate = new Date(opost.metadata.date);
-
return odate.getTime() - date.getTime();
-
});
-
export const _allPosts = allPosts;
-
-
export async function load() {
-
if (!allPosts.length) {
-
return { status: 404 };
-
}
-
return { posts: allPosts };
-
}
-3
src/routes/entries/+page.server.ts
···
-
import {_load as load_logs} from '../log/+page.server.ts'
-
-
export const load = load_logs
-40
src/routes/entries/+page.svelte
···
-
<script lang="ts">
-
import Window from '../../components/window.svelte';
-
import type { PostData } from './+layout.server.ts';
-
import LogPage from '../log/+page.svelte';
-
import type { NoteData } from '../../components/note.svelte';
-
-
interface Props {
-
data: {
-
posts: PostData[];
-
feedPosts: NoteData[];
-
};
-
}
-
-
let { data }: Props = $props();
-
</script>
-
-
<div class="mx-auto md:max-w-fit flex flex-col-reverse md:flex-row gap-y-4 gap-x-16">
-
<div class="flex flex-col gap-y-4">
-
{#each data.posts as post}
-
<Window title={post.metadata.title} iconUri="/icons/entry.webp">
-
<a
-
href="/entries/{post.path}"
-
title="cd /entries/{post.path}"
-
data-sveltekit-preload-data="off"
-
>
-
<div class="flex flex-col prose prose-ralsei leading-5">
-
<ul>
-
<li>
-
published on: <time datetime="{post.metadata.date} 00:00:00">{post.published}</time>
-
</li>
-
<li class="max-w-[34ch] text-wrap">excerpt: {post.metadata.excerpt}</li>
-
</ul>
-
<strong class="place-self-end text-ralsei-green-light"> read more... </strong>
-
</div>
-
</a>
-
</Window>
-
{/each}
-
</div>
-
<LogPage data={{ feedPosts: data.feedPosts }} />
-
</div>
-45
src/routes/entries/_layout.svelte
···
-
<script lang="ts">
-
import { PUBLIC_BASE_URL } from '$env/static/public';
-
import Window from '../../components/window.svelte';
-
import '../../styles/app.css';
-
import { page } from '$app/state';
-
-
interface Props {
-
title: string;
-
date: Date;
-
excerpt: string;
-
children?: import('svelte').Snippet;
-
}
-
-
let { title, date, excerpt, children }: Props = $props();
-
-
let showMetadata = $derived(excerpt !== undefined && excerpt !== null);
-
</script>
-
-
<svelte:head>
-
<meta property="og:description" content={excerpt} />
-
<meta property="og:type" content="article" />
-
<meta property="og:title" content={title} />
-
</svelte:head>
-
-
<article class="mx-auto max-w-fit flex flex-wrap lg:flex-nowrap gap-4 h-entry">
-
<Window {title} iconUri="/icons/entry.webp" entry>
-
<div class="prose prose-ralsei max-w-[80ch] e-content">
-
{@render children?.()}
-
</div>
-
</Window>
-
{#if showMetadata}
-
<Window title="metadata" sticky>
-
<div class="prose prose-ralsei">
-
<ul>
-
<link class="u-url" href="{PUBLIC_BASE_URL}{page.url.pathname}" />
-
<li>author: <a rel="author" class="p-author h-card" href={PUBLIC_BASE_URL}>dusk</a></li>
-
<li>published on: <time class="dt-published" datetime="{date} 00:00:00">{date}</time></li>
-
<li class="max-w-80 text-wrap">
-
excerpt: <div class="inline p-summary">{excerpt}</div>
-
</li>
-
</ul>
-
</div>
-
</Window>
-
{/if}
-
</article>
-35
src/routes/entries/_rss/+server.ts
···
-
import { PUBLIC_BASE_URL } from '$env/static/public';
-
import { _allPosts, type PostData } from '../+layout.server.ts';
-
-
const entriesUrl = `${PUBLIC_BASE_URL}/entries`;
-
-
export const GET = async () => {
-
return new Response(render(_allPosts), {
-
headers: {
-
'content-type': 'application/xml',
-
'cache-control': 'no-store'
-
}
-
});
-
};
-
-
const render = (posts: PostData[]) => `<?xml version="1.0" encoding="UTF-8" ?>
-
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
-
<channel>
-
<atom:link href="${entriesUrl}/_rss" rel="self" type="application/rss+xml" />
-
<title>dusk's posts (@poor.dog)</title>
-
<link>${entriesUrl}</link>
-
<description>posts from my website</description>
-
${posts
-
.map(
-
(post) => `<item>
-
<guid>${entriesUrl}/${post.path}</guid>
-
<title>${post.metadata.title}</title>
-
<link>${entriesUrl}/${post.path}</link>
-
<description>${post.metadata.excerpt}</description>
-
<pubDate>${new Date(post.metadata.date).toUTCString()}</pubDate>
-
</item>`
-
)
-
.join('')}
-
</channel>
-
</rss>
-
`;
-8
src/routes/entries/hello-world/+page.md
···
-
+++
-
title = "hello universe"
-
date = "2024-08-08"
-
layout = "blogpost"
-
excerpt = "meow"
-
+++
-
-
hello everyone :3c
-25
src/routes/entries/japan-trip24/+page.md
···
-
+++
-
title = "japan trip 09/24"
-
date = "2024-09-19"
-
layout = "blogpost"
-
excerpt = "photos from its trip to japan"
-
+++
-
-
<script lang="ts">
-
export let data
-
</script>
-
-
## 1-16 / 09 / 2024
-
-
photos it took while on a japan trip
-
-
~~these are *not* sorted, have fun trying to figure out the actual order (it accidentally stripped the exif data and its too lazy to find the images again)~~
-
fixed!!!! it also added a few images because its dumb and forgot
-
-
*(you can click on an image to see original!)*
-
-
<div class="grid gap-0.5 auto-rows-min md:grid-cols-4">
-
{#each data.images as image}
-
<a class="!animate-none" href={image.og}><img loading="lazy" width={480} height={480} src={image.thumb} alt="from japan trip" class="w-full h-full object-cover [image-rendering:high-quality_!important]"/></a>
-
{/each}
-
</div>
-12
src/routes/entries/japan-trip24/+page.server.ts
···
-
import images from './images.json';
-
-
export async function load() {
-
return {
-
images: images.map((id) => {
-
return {
-
og: `https://res.cloudinary.com/dgtwf7mar/image/upload/v1/${id}`,
-
thumb: `https://res.cloudinary.com/dgtwf7mar/image/upload/c_fill,w_480,h_480,g_center/c_limit,w_480/f_auto/q_auto/v1/${id}`
-
};
-
})
-
};
-
}
-218
src/routes/entries/japan-trip24/images.json
···
-
[
-
"IMG_1548_grkjls",
-
"IMG_1550_vodfkw",
-
"IMG_1551_fc8ow3",
-
"IMG_1554_nrfaxo",
-
"IMG_1557_zonamx",
-
"IMG_1559_fi9gql",
-
"IMG_1560_f4tjn6",
-
"IMG_1561_bgq40t",
-
"IMG_1562_qcgnrm",
-
"IMG_1564_htirzo",
-
"IMG_1565_dttzth",
-
"IMG_1566_ho5gwx",
-
"IMG_1567_d0etvq",
-
"IMG_1568_it4bmq",
-
"IMG_1574_z8s3ko",
-
"IMG_1575_mcgrvr",
-
"IMG_1587_m9bv0s",
-
"IMG_1588_hr921f",
-
"IMG_1589_jht9el",
-
"IMG_1590_aregyu",
-
"IMG_1593_kznbh7",
-
"IMG_1596_zm0dxi",
-
"IMG_1602_klj3kk",
-
"IMG_1603_oqdb98",
-
"IMG_1604_xfsytd",
-
"IMG_1608_ukyh5c",
-
"IMG_1620_csri5w",
-
"IMG_1622_tjvjso",
-
"IMG_1623_cvegyx",
-
"IMG_1626_ryegcv",
-
"IMG_1632_xoct96",
-
"IMG_1645_lmgpfk",
-
"IMG_1646_qjkkfv",
-
"IMG_1648_xswq18",
-
"IMG_1650_urntrf",
-
"IMG_1651_fcjzgt",
-
"IMG_1652_zbttvs",
-
"IMG_1654_tuesk4",
-
"IMG_1662_s5otqc",
-
"IMG_1663_vqk6mr",
-
"IMG_1664_y2cqbv",
-
"IMG_1675_vfatdq",
-
"IMG_1677_xbh3zy",
-
"IMG_1680_ubpd6l",
-
"IMG_1682_d7mwxr",
-
"IMG_1683_xp3pgp",
-
"IMG_1684_vpabrd",
-
"IMG_1685_luhmdk",
-
"IMG_1686_czucuf",
-
"IMG_1687_tc1oo1",
-
"IMG_1689_uju7nq",
-
"IMG_1692_pagenu",
-
"IMG_1694_qmcryo",
-
"IMG_1697_yuxzde",
-
"IMG_1699_yq0aax",
-
"IMG_1700_wddm7r",
-
"IMG_1701_ylvvyx",
-
"IMG_1708_czypw1",
-
"IMG_1712_wwjagg",
-
"IMG_1734_gojndg",
-
"IMG_1735_yd2dy9",
-
"IMG_1738_wgpapk",
-
"IMG_1741_hbtbvk",
-
"IMG_1756_njptxf",
-
"IMG_1759_b91ff5",
-
"IMG_1763_saii3h",
-
"IMG_1775_byhnbi",
-
"IMG_1776_jtl3uc",
-
"IMG_1778_ufiaw4",
-
"IMG_1780_mqa1tk",
-
"IMG_1783_j9zqjv",
-
"IMG_1785_ou7nvf",
-
"IMG_1786_zkn6mk",
-
"IMG_1788_mb8oip",
-
"IMG_1789_fa4xut",
-
"IMG_1790_fji4oi",
-
"IMG_1799_y2pqnu",
-
"IMG_1801_nb2fyk",
-
"IMG_1805_ugpswy",
-
"IMG_1806_edmuxz",
-
"IMG_1812_vozh2q",
-
"IMG_1813_yxlipi",
-
"IMG_1814_z7lgfg",
-
"IMG_1816_wft8gn",
-
"IMG_1819_aotxhf",
-
"IMG_1822_f536dv",
-
"IMG_1832_crxl8c",
-
"IMG_1834_dxscck",
-
"IMG_1836_nzayf6",
-
"IMG_1837_w0umua",
-
"IMG_1838_jun3om",
-
"IMG_1839_gu0huo",
-
"IMG_1841_ypknji",
-
"IMG_1844_mscenv",
-
"IMG_1845_btu9ks",
-
"IMG_1846_ewgafy",
-
"IMG_1848_l61sd5",
-
"IMG_1849_zympk9",
-
"IMG_1862_uxhhcu",
-
"IMG_1864_vmouhi",
-
"IMG_1867_apl41d",
-
"IMG_1868_obb1q1",
-
"IMG_1870_wj4wx6",
-
"IMG_1875_cbr5us",
-
"IMG_1877_zbnsf4",
-
"IMG_1880_tjdd4g",
-
"IMG_1882_i2tt70",
-
"IMG_1888_gsjmcv",
-
"IMG_1890_uronrs",
-
"IMG_1893_jgr7lt",
-
"IMG_1895_pklwtb",
-
"IMG_1898_bedmeo",
-
"IMG_1900_bkkvjo",
-
"IMG_1901_s8nt0w",
-
"IMG_1902_efpceq",
-
"IMG_1905_e7knuy",
-
"IMG_1908_ssdjim",
-
"IMG_1911_ehsgjz",
-
"IMG_1912_xbxhev",
-
"IMG_1914_vijsn0",
-
"IMG_1915_zdev3v",
-
"IMG_1916_qwqg78",
-
"IMG_1917_gitpjp",
-
"IMG_1918_ris8iy",
-
"IMG_1920_srnvqq",
-
"IMG_1921_olm7ko",
-
"IMG_1923_xmylox",
-
"IMG_1924_trh5ah",
-
"IMG_1925_wu1e9g",
-
"IMG_1927_pb6htn",
-
"IMG_1939_njl48e",
-
"IMG_1946_xqa0w0",
-
"IMG_1948_peik8p",
-
"IMG_1949_ofxeix",
-
"IMG_1958_fnz3a6",
-
"IMG_1959_xo1tn5",
-
"IMG_1964_vhahus",
-
"IMG_1975_i0azhi",
-
"IMG_1977_dffpgt",
-
"IMG_1985_g0z0ja",
-
"IMG_1988_qm6hln",
-
"IMG_1989_tfhakh",
-
"IMG_1990_udmwst",
-
"IMG_1994_nq1m8c",
-
"IMG_1995_d865i7",
-
"IMG_1996_jqexwr",
-
"IMG_1999_mqli90",
-
"IMG_2001_n3lpuz",
-
"IMG_2007_sz0r6o",
-
"IMG_2008_slarjg",
-
"IMG_2009_gpch49",
-
"IMG_2013_tcwlqe",
-
"IMG_2014_idxngh",
-
"IMG_2021_v4stwp",
-
"IMG_2022_d3ihri",
-
"IMG_2023_lrbsoj",
-
"IMG_2024_q33xbl",
-
"IMG_2025_uvntmq",
-
"IMG_2026_iy6e9s",
-
"IMG_2028_fazbnu",
-
"IMG_2030_afziyc",
-
"IMG_2031_ivs1ig",
-
"IMG_2032_yaerpl",
-
"IMG_2036_jvseyo",
-
"IMG_2039_o3jzt7",
-
"IMG_2050_vonn8i",
-
"IMG_2063_i0cgat",
-
"IMG_2065_dzmvuc",
-
"IMG_2071_rqpcvd",
-
"IMG_2075_r926jy",
-
"IMG_2077_ydvll5",
-
"IMG_2079_mhsa7e",
-
"IMG_2087_jccuhd",
-
"IMG_2090_s16pgf",
-
"IMG_2091_lidh3q",
-
"IMG_2092_bwhedb",
-
"IMG_2094_mlnltg",
-
"IMG_2096_je0fyy",
-
"IMG_2097_t18aim",
-
"IMG_2098_uiokml",
-
"IMG_2102_pkjche",
-
"IMG_2111_jmslli",
-
"IMG_2113_zkqsiq",
-
"IMG_2114_mofaie",
-
"IMG_2118_lmjwhj",
-
"IMG_2119_yzvhqm",
-
"IMG_2120_wgnbim",
-
"IMG_2121_mwvte4",
-
"IMG_2123_kxrfiu",
-
"IMG_2125_fjinmr",
-
"IMG_2126_l0qe33",
-
"IMG_2128_w36btk",
-
"IMG_2131_wc0z6d",
-
"IMG_2141_pnw1mp",
-
"IMG_2143_je1kxx",
-
"IMG_2144_wfyrbj",
-
"IMG_2146_k84hr3",
-
"IMG_2149_j7qjwy",
-
"IMG_2150_fcc1cx",
-
"IMG_2151_fjtdhm",
-
"IMG_2155_zhmhmk",
-
"IMG_2159_pjbb7e",
-
"IMG_2162_i0i9fr",
-
"IMG_2165_cpvzlg",
-
"IMG_2168_zgsdcf",
-
"IMG_2171_lbhlnr",
-
"IMG_2172_c5hbzn",
-
"IMG_2173_jwtjn7",
-
"IMG_2174_ntsxh1",
-
"IMG_2175_sak0od",
-
"IMG_2176_svth1u",
-
"IMG_2178_sjdqzt",
-
"IMG_2180_grhg9y",
-
"IMG_2181_kj9pko",
-
"IMG_2188_ao64sh",
-
"IMG_2190_ngl8q8"
-
]
-58
src/routes/entries/test/+page.md
···
-
+++
-
title = "test"
-
date = "2024-08-13"
-
layout = "blogpost"
-
excerpt = "this is a test document. it is used for testing stuff."
-
+++
-
-
-
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed iaculis ligula sed odio fermentum, ac aliquet diam sagittis. Phasellus vel elementum arcu. Fusce id ante lacus. Nullam malesuada, enim nec maximus mollis, tortor metus dapibus mi, id tincidunt massa massa sed velit. Curabitur cursus, lorem rutrum laoreet posuere, tellus eros faucibus odio, non ullamcorper magna lectus non justo. Fusce pulvinar sagittis nisl et pretium. Proin quis pellentesque risus.
-
-
Pellentesque massa purus, ornare aliquam velit et, hendrerit lacinia felis. Fusce nec felis maximus, egestas lorem et, vehicula libero. Donec gravida sodales porta. Nunc ac urna vestibulum, finibus erat vitae, euismod nisi. Morbi auctor pretium diam ut pulvinar. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Vivamus pulvinar orci vitae dolor sodales placerat. Integer tristique condimentum massa, non euismod nisi sodales eu.
-
-
1. a
-
1. b
-
1. c
-
1. d
-
-
- a
-
- b
-
- c
-
- d
-
-
`test test test`
-
-
```rust
-
fn main() {
-
println!("howdy")
-
}
-
```
-
-
```js
-
function lorem(ipsum, dolor = 1) {
-
const sit = ipsum == null ? 0 : ipsum.sit;
-
dolor = sit - amet(dolor);
-
return sit ? consectetur(ipsum, 0, dolor < 0 ? 0 : dolor) : [];
-
}
-
function adipiscing(...elit) {
-
if (!elit.sit) {
-
return [];
-
}
-
const sed = elit[0];
-
return eiusmod.tempor(sed) ? sed : [sed];
-
}
-
function incididunt(ipsum, ut = 1) {
-
ut = labore.et(amet(ut), 0);
-
const sit = ipsum == null ? 0 : ipsum.sit;
-
if (!sit || ut < 1) {
-
return [];
-
}
-
let dolore = 0;
-
let magna = 0;
-
const aliqua = new eiusmod(labore.ut(sit / ut));
-
while (dolore < sit) {
-
aliqua[magna++] = consectetur(ipsum, dolore, (dolore += ut));
-
}
-
return aliqua;
-
}
-
```
-148
src/routes/guestbook/+page.server.ts
···
-
import { redirect, type Cookies, type RequestEvent } from '@sveltejs/kit';
-
import { scopeCookies as _scopeCookies, fancyText } from '$lib';
-
import { RetryAfterRateLimiter } from 'sveltekit-rate-limiter/server';
-
import { PUBLIC_BASE_URL } from '$env/static/public';
-
import { getBskyClient, getUserPosts } from '$lib/bluesky.js';
-
import { getVisitorId } from '$lib/visits';
-
import { nanoid } from 'nanoid';
-
import { noteFromBskyPost, type NoteData } from '../../components/note.svelte';
-
import { get, writable } from 'svelte/store';
-
import type { Post } from '@skyware/bot';
-
import { useToken as checkApiToken, newToken } from '$lib/apiToken.js';
-
-
export const prerender = false;
-
-
const callbackUrl = `${PUBLIC_BASE_URL}/guestbook/`;
-
-
const createPostRatelimiter = new RetryAfterRateLimiter({
-
IP: [5, 'd'],
-
IPUA: [2, 'h']
-
});
-
-
const scopeCookies = (cookies: Cookies) => {
-
return _scopeCookies(cookies, '/guestbook');
-
};
-
-
const postTokens = writable<Set<string>>(new Set());
-
const entries = writable<NoteData[]>([]);
-
-
export const _fetchEntries = async () => {
-
const newEntries: NoteData[] = [];
-
const { posts } = await getUserPosts('did:web:guestbook.gaze.systems', 16);
-
const fetchPostReplies = async (post: Post) => {
-
if ((post.replyCount ?? 0) === 0) return { post, replies: [] };
-
return { post, replies: await post.fetchChildren({ depth: 1, force: true }) };
-
};
-
const postsWithReplies = await Promise.all(posts.map(fetchPostReplies));
-
for (const { post, replies } of postsWithReplies) {
-
const note = noteFromBskyPost(post);
-
note.children = replies.map((reply) => {
-
const replyNote = noteFromBskyPost(reply);
-
replyNote.purposeAction = 'reply';
-
replyNote.outgoingLinks = [{ name: 'bsky-reply', link: reply.uri }];
-
return replyNote;
-
});
-
newEntries.push(note);
-
}
-
entries.set(newEntries);
-
return newEntries;
-
};
-
-
export const actions = {
-
post: async (event: RequestEvent) => {
-
const { request, cookies } = event;
-
const scopedCookies = scopeCookies(cookies);
-
const rateStatus = await createPostRatelimiter.check(event);
-
if (rateStatus.limited) {
-
scopedCookies.set(
-
'sendError',
-
`you are being ratelimited sowwy :c, try again after ${rateStatus.retryAfter} seconds`
-
);
-
redirect(303, callbackUrl);
-
}
-
const form = await request.formData();
-
const apiToken = form.get('_token')?.toString() ?? '';
-
if (!checkApiToken(apiToken)) {
-
scopedCookies.set('sendError', 'api token is invalid');
-
redirect(303, callbackUrl);
-
}
-
const content = form.get('content')?.toString().substring(0, 300);
-
if (content === undefined) {
-
scopedCookies.set('sendError', 'content field is missing');
-
redirect(303, callbackUrl);
-
}
-
// save form content in a cookie
-
scopedCookies.set('postData', content);
-
// create a token we will use to validate
-
const token = nanoid();
-
postTokens.update((set) => set.add(token));
-
scopedCookies.set('postAuth', token);
-
redirect(303, callbackUrl);
-
}
-
};
-
-
export async function load({ cookies }) {
-
const scopedCookies = scopeCookies(cookies);
-
const data = {
-
entries: get(entries),
-
sendError: scopedCookies.get('sendError') || '',
-
getError: '',
-
sendRatelimited: scopedCookies.get('sendRatelimited') || '',
-
getRatelimited: false,
-
fillText: fancyText(getVisitorId(cookies) ?? nanoid()),
-
apiToken: newToken()
-
};
-
const rawPostData = scopedCookies.get('postData') || null;
-
const postAuth = scopedCookies.get('postAuth') || null;
-
if (rawPostData !== null && postAuth !== null) {
-
// delete the postData cookie after we got it cause we dont need it anymore
-
scopedCookies.delete('postData');
-
scopedCookies.delete('postAuth');
-
// get and validate token
-
if (!get(postTokens).has(postAuth)) {
-
scopedCookies.set(
-
'sendError',
-
'invalid post token! this is either a bug or you should stop doing silly stuff'
-
);
-
redirect(303, callbackUrl);
-
}
-
postTokens.update((set) => {
-
set.delete(postAuth);
-
return set;
-
});
-
// post entry
-
try {
-
// return error if content was not set or if empty
-
const content = rawPostData.substring(0, 300).trim();
-
if (content.length === 0) {
-
scopedCookies.set('sendError', `content field was empty`);
-
redirect(303, callbackUrl);
-
}
-
// post to guestbook account
-
const client = await getBskyClient();
-
await client.post(
-
{
-
text: content,
-
threadgate: { allowMentioned: false, allowFollowing: true }
-
},
-
{ resolveFacets: false }
-
);
-
try {
-
data.entries = await _fetchEntries();
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
} catch (err: any) {
-
data.getError = err.toString();
-
}
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
-
} catch (err: any) {
-
scopedCookies.set('sendError', err.toString());
-
redirect(303, callbackUrl);
-
}
-
redirect(303, callbackUrl);
-
}
-
// delete the cookies after we get em since we dont really need these more than once
-
scopedCookies.delete('sendError');
-
scopedCookies.delete('sendRatelimited');
-
-
return data;
-
}
-181
src/routes/guestbook/+page.svelte
···
-
<script lang="ts">
-
import Note, { type NoteData } from '../../components/note.svelte';
-
import Token from '../../components/token.svelte';
-
import Window from '../../components/window.svelte';
-
-
interface Props {
-
data: {
-
entries: NoteData[];
-
sendError: string;
-
getError: string;
-
sendRatelimited: string;
-
getRatelimited: boolean;
-
fillText: string;
-
apiToken: string;
-
};
-
}
-
-
let { data }: Props = $props();
-
-
const placeholders = ['meow', 'arf', '0110100001101001', '0x6869'];
-
</script>
-
-
<div class="flex flex-col-reverse md:flex-row gap-2 md:gap-4">
-
<Window title="guestbook" style="ml-auto" iconUri="/icons/guestbook.webp">
-
<div class="flex flex-col gap-1 max-w-[50ch] leading-6">
-
<div class="prose prose-ralsei leading-6 entry p-2">
-
<p>hia, here is the guestbook if you wanna post anything :)</p>
-
<p>be good pretty please (and don't be shy!!!)</p>
-
<p class="text-sm italic">
-
(to see all the entries, look <a href="https://bsky.app/profile/guestbook.gaze.systems"
-
>here</a
-
>)
-
</p>
-
</div>
-
<form method="post">
-
<input type="hidden" name="_token" value={data.apiToken} />
-
<div class="entry entryflex">
-
<textarea
-
class="text-lg p-1 m-0 ml-0.5 bg-transparent resize-none text-shadow-white placeholder-shown:[text-shadow:none] [field-sizing:content] border-none"
-
name="content"
-
placeholder="say {placeholders[Math.floor(Math.random() * placeholders.length)]}!"
-
maxlength="300"
-
required
-
></textarea>
-
</div>
-
<div class="flex flex-row gap-1 mt-1">
-
<input
-
type="submit"
-
value="click to post"
-
formaction="?/post"
-
class="entry text-ralsei-green-light leading-none hover:underline motion-safe:hover:animate-squiggle p-1 z-50"
-
/>
-
<div class="marquee-wrapper entry text-ralsei-white/50">
-
<div class="marquee font-monospace">
-
<p class="text-shadow-none">{data.fillText}</p>
-
<p class="text-shadow-none">{data.fillText}</p>
-
</div>
-
</div>
-
</div>
-
{#if data.sendRatelimited}
-
<p class="text-error">you are ratelimited, try again in 30 seconds</p>
-
{/if}
-
{#if data.sendError}
-
<details class="w-[50ch]">
-
<summary class="text-error">got error trying to send post</summary>
-
<p>{data.sendError}</p>
-
</details>
-
{/if}
-
</form>
-
</div>
-
</Window>
-
<Window
-
id="guestbookentries"
-
style="mr-auto"
-
title="entries"
-
iconUri="/icons/entries.webp"
-
removePadding
-
>
-
<div class="flex flex-col gap-2 md:gap-4 2xl:w-[60ch]">
-
{#if data.getRatelimited}
-
<p class="text-error">
-
woops, looks like you are being ratelimited, try again in like half a minute :3
-
</p>
-
{:else if data.getError}
-
<details class="w-[50ch]">
-
<summary class="text-error">got error trying to fetch entries</summary>
-
<p>{data.getError}</p>
-
</details>
-
{:else}
-
<div
-
class="
-
prose prose-ralsei
-
prose-pre:rounded-none prose-pre:!m-0 prose-pre:!p-2
-
prose-pre:!bg-ralsei-black prose-code:!bg-ralsei-black
-
"
-
>
-
<pre class="language-bash"><code class="language-bash"
-
><nobr>
-
<Token v="[" punct />gazesystems <Token v="/" keywd /><Token v="]$" punct /> <Token
-
v="source"
-
funct
-
/> <Token v="scripts/log.nu" />
-
<br />
-
<Token v="[" punct />gazesystems <Token v="/" keywd /><Token v="]$" punct /> <Token
-
v="let"
-
funct
-
/> <Token v="entries" /> <Token v="=" punct /> <Token v="(" punct /><Token
-
v="ls"
-
funct
-
/> <Token v="guestbook" /> <Token v="|" punct /> <Token v="reverse" funct /> <Token
-
v="|"
-
punct
-
/> <Token v="take" funct /> <Token v="16" /><Token v=")" punct />
-
<br />
-
<Token v="[" punct />gazesystems <Token v="/" keywd /><Token v="]$" punct /> <Token
-
v="$entries"
-
/> <Token v="|" punct /> <Token v="each" funct /> <Token v="&#123;" punct /><Token
-
v="|"
-
punct
-
/><Token v="file" /><Token v="|" punct /> <Token v="render" funct /> <Token
-
v="("
-
punct
-
/><Token v="open" funct /> <Token v="$file.name" /><Token v=")" punct /><Token
-
v="&#125;"
-
punct
-
/>
-
<br />
-
<br />
-
{#each data.entries as note, index}
-
<Note
-
mapOutgoingNames={{ bsky: '', reply: 'src' }}
-
showOutgoing={true}
-
rootNote={note}
-
/>
-
{#if index < data.entries.length - 1}
-
<div class="mt-3"></div>
-
{/if}
-
{/each}
-
</nobr></code
-
></pre>
-
</div>
-
{/if}
-
</div>
-
</Window>
-
</div>
-
-
<style lang="postcss">
-
.entry {
-
@apply bg-ralsei-green-dark/70 border-ralsei-green-light/30 border-x-[4px] border-y-[5px];
-
border-style: ridge;
-
}
-
.entryflex {
-
@apply flex flex-col p-1;
-
}
-
-
.marquee-wrapper {
-
max-width: 100%;
-
overflow: hidden;
-
}
-
-
.marquee {
-
white-space: nowrap;
-
overflow: hidden;
-
display: inline-block;
-
animation: marquee 10s linear infinite;
-
}
-
-
.marquee p {
-
transform: translateY(15%);
-
display: inline-block;
-
}
-
-
@keyframes marquee {
-
0% {
-
transform: translate3d(0, 0, 0);
-
}
-
100% {
-
transform: translate3d(-50%, 0, 0);
-
}
-
}
-
</style>
-12
src/routes/log/+page.server.ts
···
-
import { getLastPosts } from '$lib/bluesky.js';
-
import { noteFromBskyPost } from '../../components/note.svelte';
-
-
export const load = async () => {
-
return _load();
-
};
-
-
export const _load = async () => {
-
return {
-
feedPosts: getLastPosts().map(noteFromBskyPost)
-
};
-
};
-64
src/routes/log/+page.svelte
···
-
<script lang="ts">
-
import Window from '../../components/window.svelte';
-
import Token from '../../components/token.svelte';
-
import Note, { type NoteData } from '../../components/note.svelte';
-
-
interface Props {
-
data: {
-
feedPosts: NoteData[];
-
};
-
}
-
-
let { data }: Props = $props();
-
</script>
-
-
<Window title="terminal" removePadding>
-
<div
-
class="
-
prose prose-ralsei
-
prose-pre:rounded-none prose-pre:!m-0 prose-pre:!p-2
-
prose-pre:!bg-ralsei-black prose-code:!bg-ralsei-black
-
"
-
>
-
<pre class="language-bash"><code class="language-bash"
-
><nobr>
-
<Token v="[" punct />gazesystems <Token v="/" keywd /><Token v="]$" punct /> <Token
-
v="source"
-
funct
-
/> <Token v="scripts/log.nu" />
-
<br />
-
<Token v="[" punct />gazesystems <Token v="/" keywd /><Token v="]$" punct /> <Token
-
v="let"
-
funct
-
/> <Token v="entries" /> <Token v="=" punct /> <Token v="(" punct /><Token
-
v="ls"
-
funct
-
/> <Token v="logs" /> <Token v="|" punct /> <Token v="reverse" funct /> <Token
-
v="|"
-
punct
-
/> <Token v="take" funct /> <Token v="13" /><Token v=")" punct />
-
<br />
-
<Token v="[" punct />gazesystems <Token v="/" keywd /><Token v="]$" punct /> <Token
-
v="$entries"
-
/> <Token v="|" punct /> <Token v="each" funct /> <Token v="&#123;" punct /><Token
-
v="|"
-
punct
-
/><Token v="file" /><Token v="|" punct /> <Token v="render" funct /> <Token
-
v="("
-
punct
-
/><Token v="open" funct /> <Token v="$file.name" /><Token v=")" punct /><Token
-
v="&#125;"
-
punct
-
/>
-
<br />
-
<br />
-
{#each data.feedPosts as note, index}
-
<Note rootNote={note} />
-
{#if index < data.feedPosts.length - 1}
-
<div class="mt-3"></div>
-
{/if}
-
{/each}
-
</nobr></code
-
></pre>
-
</div>
-
</Window>
-5
src/routes/log/_rss/+server.ts
···
-
import { redirect } from '@sveltejs/kit';
-
-
export const GET = async () => {
-
redirect(301, 'https://bsky.app/profile/did:plc:dfl62fgb7wtjj3fcbb72naae/rss');
-
};
-5
src/routes/robots.txt/+server.ts
···
-
import { getRobotsTxt } from '$lib/robots';
-
-
export const GET = async () => {
-
return new Response(await getRobotsTxt());
-
};
-402
src/styles/app.css
···
-
@import './prism-synthwave84.css';
-
-
@tailwind base;
-
@tailwind components;
-
@tailwind utilities;
-
-
@layer base {
-
:root {
-
@apply font-sans-serif bg-ralsei-black text-ralsei-white;
-
@apply prose-code:font-monospace prose-headings:font-monospace;
-
cursor: url('/icons/gaze_closed.webp'), default;
-
scrollbar-color: theme(colors.ralsei.green.dark) transparent;
-
-webkit-font-smoothing: none !important;
-
font-smooth: never !important;
-
font-smoothing: none !important;
-
}
-
-
@font-face {
-
font-family: 'Fusion Pixel 10px Monospaced zh_hans';
-
src: url('/fonts/fusion-pixel-sc-monospaced.woff2') format('woff2');
-
font-weight: normal;
-
font-style: normal;
-
font-display: swap;
-
}
-
-
@font-face {
-
font-family: 'Fusion Pixel 10px Proportional zh_hans';
-
src: url('/fonts/fusion-pixel-sc-proportional.woff2') format('woff2');
-
font-weight: normal;
-
font-style: normal;
-
font-display: swap;
-
}
-
-
@font-face {
-
font-family: 'Doll Mono';
-
src: url('/fonts/dollmonoopt.woff2') format('woff2');
-
}
-
-
.prose h1::before {
-
content: '[ ';
-
}
-
.prose h1::after {
-
content: ' ]';
-
}
-
-
.prose h2::before {
-
content: '[= ';
-
}
-
.prose h2::after {
-
content: ' =]';
-
}
-
-
.prose h3::before {
-
content: '[== ';
-
}
-
.prose h3::after {
-
content: ' ==]';
-
}
-
-
.prose h4::before {
-
content: '[=== ';
-
}
-
.prose h4::after {
-
content: ' ===]';
-
}
-
-
/* .prose h1::after,.prose h2::after,.prose h3::after,.prose h4::after {
-
@apply motion-safe:animate-blink;
-
content: '_';
-
} */
-
-
.prose a {
-
text-decoration: none;
-
}
-
-
.prose a:hover {
-
@apply motion-safe:animate-squiggle;
-
text-decoration: underline;
-
}
-
-
h1,
-
h2,
-
h3,
-
h4,
-
h5,
-
h6,
-
.text-shadow-pink {
-
text-shadow:
-
0 0 3px theme(colors.ralsei.black),
-
0 0 6px theme(colors.ralsei.pink.neon),
-
0 0 10px #fff3;
-
}
-
-
.text-shadow-red {
-
text-shadow:
-
0 0 1px theme(colors.ralsei.black),
-
0 0 5px theme(colors.red.600);
-
}
-
-
.text-shadow-none {
-
text-shadow: none;
-
}
-
-
.prose ul,
-
ul {
-
list-style-type: '>>';
-
}
-
-
.text-shadow-green {
-
text-shadow:
-
0 0 2px theme(colors.ralsei.black),
-
0 0 5px theme(colors.ralsei.green.light);
-
}
-
-
a,
-
button,
-
input[type='submit'] {
-
@apply text-shadow-green;
-
cursor: url('/icons/gaze.webp'), pointer;
-
}
-
-
.animate-squiggle {
-
animation: squigglevision 0.3s infinite;
-
}
-
-
@keyframes squigglevision {
-
0% {
-
filter: url('#squiggly-0');
-
}
-
25% {
-
filter: url('#squiggly-1');
-
}
-
50% {
-
filter: url('#squiggly-2');
-
}
-
75% {
-
filter: url('#squiggly-3');
-
}
-
100% {
-
filter: url('#squiggly-4');
-
}
-
}
-
-
@keyframes blink {
-
0% {
-
opacity: 1;
-
}
-
50% {
-
opacity: 0;
-
}
-
100% {
-
opacity: 1;
-
}
-
}
-
}
-
-
@layer utilities {
-
.text-error {
-
@apply text-xl text-red-600 text-shadow-red;
-
}
-
-
.border-groove {
-
border-style: groove;
-
}
-
-
.border-ridge {
-
border-style: ridge;
-
}
-
-
.app-grid-background-anim {
-
animation: 4s linear app-grid-move-first-layer infinite;
-
}
-
-
.app-grid-background-second-layer-anim {
-
animation: 12s linear app-grid-move-second-layer infinite;
-
}
-
-
@keyframes app-grid-move-first-layer {
-
0% {
-
background-position: 0px 0px;
-
}
-
100% {
-
background-position: 126px 84px;
-
}
-
}
-
-
@keyframes app-grid-move-second-layer {
-
0% {
-
background-position: 96px 120px;
-
}
-
100% {
-
background-position: 0px 0px;
-
}
-
}
-
-
@media (prefers-reduced-motion: no-preference) {
-
@keyframes bounce-reverse {
-
0%,
-
100% {
-
transform: none;
-
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
-
}
-
50% {
-
transform: translateY(-25%);
-
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
-
}
-
}
-
}
-
@media (prefers-reduced-motion: no-preference) {
-
.animate-bounce-reverse:hover {
-
animation: bounce-reverse 1s infinite;
-
}
-
}
-
}
-
-
a.app-selected-route {
-
text-shadow:
-
0 0 2px theme(colors.ralsei.black),
-
0 0 5px theme(colors.ralsei.pink.regular);
-
}
-
-
.app-grid-background {
-
background-image:
-
linear-gradient(theme(colors.ralsei.green.light / 0.4), transparent 2px),
-
linear-gradient(to right, theme(colors.ralsei.green.light / 0.4), transparent 2px);
-
background-size:
-
100% 42px,
-
42px 100%;
-
}
-
-
.app-grid-background-second-layer {
-
background-image:
-
linear-gradient(theme(colors.ralsei.pink.neon / 0.4), transparent 1px),
-
linear-gradient(to right, theme(colors.ralsei.pink.neon / 0.4), transparent 1px);
-
background-size:
-
100% 24px,
-
24px 100%;
-
}
-
-
@media (prefers-reduced-motion: no-preference) {
-
.animate-window-open {
-
animation: 0.5s ease-out window-open-scale forwards;
-
}
-
-
.animate-window-open-vertical {
-
animation: 0.5s ease-out window-open-scale-vertical forwards;
-
transform-origin: bottom;
-
}
-
-
.animate-window-open-horizontal {
-
animation: 0.5s ease-out window-open-scale-horizontal forwards;
-
transform-origin: left;
-
}
-
-
.animate-window-open-move-up {
-
animation: 0.5s ease-out window-open-move-up forwards;
-
}
-
-
.animate-window-open-move-down {
-
animation: 0.5s ease-out window-open-move-down forwards;
-
}
-
-
.animate-window-open-move-left {
-
animation: 0.5s ease-out window-open-move-left forwards;
-
}
-
-
.animate-window-open-move-right {
-
animation: 0.5s ease-out window-open-move-right forwards;
-
}
-
-
.animate-overflow-keep-hidden {
-
animation: 0.6s linear overflow-keep-hidden forwards;
-
}
-
-
@keyframes window-open-scale {
-
0% {
-
scale: 0;
-
opacity: 0;
-
}
-
20% {
-
scale: 0;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
scale: 1;
-
opacity: 1;
-
}
-
}
-
-
@keyframes window-open-scale-vertical {
-
0% {
-
scale: 1 0;
-
opacity: 0;
-
}
-
20% {
-
scale: 1 0;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
scale: 1 1;
-
opacity: 1;
-
}
-
}
-
-
@keyframes window-open-scale-horizontal {
-
0% {
-
scale: 0 1;
-
opacity: 0;
-
}
-
20% {
-
scale: 0 1;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
scale: 1 1;
-
opacity: 1;
-
}
-
}
-
-
@keyframes window-open-move-down {
-
0% {
-
translate: 0 10rem;
-
opacity: 0;
-
}
-
20% {
-
translate: 0 10rem;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
translate: normal;
-
opacity: 1;
-
}
-
}
-
-
@keyframes window-open-move-up {
-
0% {
-
translate: 0 -10rem;
-
opacity: 0;
-
}
-
20% {
-
translate: 0 -10rem;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
translate: normal;
-
opacity: 1;
-
}
-
}
-
-
@keyframes window-open-move-left {
-
0% {
-
translate: 10rem 0;
-
opacity: 0;
-
}
-
20% {
-
translate: 10rem 0;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
translate: normal;
-
opacity: 1;
-
}
-
}
-
-
@keyframes window-open-move-right {
-
0% {
-
translate: -10rem 0;
-
opacity: 0;
-
}
-
20% {
-
translate: -10rem 0;
-
}
-
60% {
-
opacity: 0.5;
-
}
-
100% {
-
translate: normal;
-
opacity: 1;
-
}
-
}
-
-
@keyframes overflow-keep-hidden {
-
0% {
-
overflow: hidden;
-
}
-
100% {
-
overflow: auto;
-
}
-
}
-
}
-140
src/styles/prism-synthwave84.css
···
-
/*
-
* Synthwave '84 Theme originally by Robb Owen [@Robb0wen] for Visual Studio Code
-
* Demo: https://marc.dev/demo/prism-synthwave84
-
*
-
* Ported for PrismJS by Marc Backes [@themarcba]
-
*/
-
-
code[class*="language-"],
-
pre[class*="language-"] {
-
color: theme(colors.ralsei.pink.neon);
-
text-shadow: 0 0 2px theme(colors.ralsei.black), 0 0 5px #ff3eb733, 0 0 10px #fff3;
-
@apply bg-ralsei-green-dark;
-
@apply font-monospace;
-
font-size: 1rem;
-
line-height: 1.4rem;
-
text-align: left;
-
white-space: pre;
-
word-spacing: normal;
-
word-break: normal;
-
word-wrap: normal;
-
-
-moz-tab-size: 4;
-
-o-tab-size: 4;
-
tab-size: 4;
-
-
-webkit-hyphens: none;
-
-moz-hyphens: none;
-
-ms-hyphens: none;
-
hyphens: none;
-
}
-
-
/* Code blocks */
-
pre[class*="language-"] {
-
padding: 1em;
-
margin: .5em 0;
-
overflow: auto;
-
}
-
-
/* :not(pre) > code[class*="language-"],
-
pre[class*="language-"] {
-
background-color: transparent !important;
-
background-image: linear-gradient(to bottom, #2a2139 75%, #34294f);
-
} */
-
-
/* Inline code */
-
:not(pre) > code[class*="language-"] {
-
padding: .1em;
-
border-radius: .3em;
-
white-space: normal;
-
}
-
-
.token.comment,
-
.token.block-comment,
-
.token.prolog,
-
.token.doctype,
-
.token.cdata {
-
color: #8e8e8e;
-
}
-
-
.token.punctuation {
-
color: #ccc;
-
}
-
-
.token.tag,
-
.token.attr-name,
-
.token.namespace,
-
.token.number,
-
.token.unit,
-
.token.hexcode,
-
.token.deleted {
-
color: #e2777a;
-
}
-
-
.token.property,
-
.token.selector {
-
color: #72f1b8;
-
text-shadow: 0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475;
-
}
-
-
.token.function-name {
-
color: #6196cc;
-
}
-
-
.token.boolean,
-
.token.selector .token.id,
-
.token.function {
-
color: #fdfdfd;
-
text-shadow: 0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975;
-
}
-
-
.token.class-name {
-
color: #fff5f6;
-
text-shadow: 0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75;
-
}
-
-
.token.constant,
-
.token.symbol {
-
color: #f92aad;
-
text-shadow: 0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3;
-
}
-
-
.token.important,
-
.token.atrule,
-
.token.keyword,
-
.token.selector .token.class,
-
.token.builtin {
-
color: #f4eee4;
-
text-shadow: 0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575;
-
}
-
-
.token.string,
-
.token.char,
-
.token.attr-value,
-
.token.regex,
-
.token.variable {
-
color: #f87c32;
-
}
-
-
.token.operator,
-
.token.entity,
-
.token.url {
-
color: #67cdcc;
-
}
-
-
.token.important,
-
.token.bold {
-
font-weight: bold;
-
}
-
-
.token.italic {
-
font-style: italic;
-
}
-
-
.token.entity {
-
cursor: help;
-
}
-
-
.token.inserted {
-
color: green;
-
}
static/88x31.gif

This is a binary file and will not be displayed.

static/88x31_midnight.gif

This is a binary file and will not be displayed.

static/88x31_sunrise.gif

This is a binary file and will not be displayed.

static/banners/1.gif

This is a binary file and will not be displayed.

static/banners/10.gif

This is a binary file and will not be displayed.

static/banners/11.gif

This is a binary file and will not be displayed.

static/banners/12.gif

This is a binary file and will not be displayed.

static/banners/13.gif

This is a binary file and will not be displayed.

static/banners/14.gif

This is a binary file and will not be displayed.

static/banners/15.gif

This is a binary file and will not be displayed.

static/banners/16.gif

This is a binary file and will not be displayed.

static/banners/17.gif

This is a binary file and will not be displayed.

static/banners/18.gif

This is a binary file and will not be displayed.

static/banners/19.gif

This is a binary file and will not be displayed.

static/banners/2.gif

This is a binary file and will not be displayed.

static/banners/20.gif

This is a binary file and will not be displayed.

static/banners/3.gif

This is a binary file and will not be displayed.

static/banners/4.gif

This is a binary file and will not be displayed.

static/banners/5.gif

This is a binary file and will not be displayed.

static/banners/6.gif

This is a binary file and will not be displayed.

static/banners/7.gif

This is a binary file and will not be displayed.

static/banners/8.gif

This is a binary file and will not be displayed.

static/banners/9.gif

This is a binary file and will not be displayed.

static/eyes/closed.webp

This is a binary file and will not be displayed.

static/eyes/normal_forward.webp

This is a binary file and will not be displayed.

static/eyes/normal_left.webp

This is a binary file and will not be displayed.

static/eyes/normal_right.webp

This is a binary file and will not be displayed.

static/fonts/dollmonoopt.woff2

This is a binary file and will not be displayed.

static/fonts/fusion-pixel-sc-monospaced.woff2

This is a binary file and will not be displayed.

static/fonts/fusion-pixel-sc-proportional.woff2

This is a binary file and will not be displayed.

static/icons/about.webp

This is a binary file and will not be displayed.

static/icons/cd_audio.webp

This is a binary file and will not be displayed.

static/icons/contact.webp

This is a binary file and will not be displayed.

static/icons/entries.webp

This is a binary file and will not be displayed.

static/icons/entry.webp

This is a binary file and will not be displayed.

static/icons/gaze.webp

This is a binary file and will not be displayed.

static/icons/gaze_closed.webp

This is a binary file and will not be displayed.

static/icons/gaze_site.webp

This is a binary file and will not be displayed.

static/icons/guestbook.webp

This is a binary file and will not be displayed.

static/icons/home.webp

This is a binary file and will not be displayed.

static/icons/msg_information.webp

This is a binary file and will not be displayed.

static/icons/msn.webp

This is a binary file and will not be displayed.

static/icons/question.webp

This is a binary file and will not be displayed.

static/icons/warning.webp

This is a binary file and will not be displayed.

static/others/250kb.webp

This is a binary file and will not be displayed.

static/others/aph.gif

This is a binary file and will not be displayed.

static/others/dbd.gif

This is a binary file and will not be displayed.

static/others/dd86k.gif

This is a binary file and will not be displayed.

static/others/desktopwebp.webp

This is a binary file and will not be displayed.

static/others/drewsh.gif

This is a binary file and will not be displayed.

static/others/godot.gif

This is a binary file and will not be displayed.

static/others/it.webp

This is a binary file and will not be displayed.

static/others/killfascists.webp

This is a binary file and will not be displayed.

static/others/moonlightnow.gif

This is a binary file and will not be displayed.

static/others/notaperson.webp

This is a binary file and will not be displayed.

static/others/poweredbynixos.webp

This is a binary file and will not be displayed.

static/others/skylar.gif

This is a binary file and will not be displayed.

static/others/slonk.gif

This is a binary file and will not be displayed.

static/pet/idle.webp

This is a binary file and will not be displayed.

static/pet/pick.webp

This is a binary file and will not be displayed.

static/pet/walk1.webp

This is a binary file and will not be displayed.

static/pet/walk2.webp

This is a binary file and will not be displayed.

static/pfp-iojkqpwerojnasduijf.webp

This is a binary file and will not be displayed.

static/resume.pdf

This is a binary file and will not be displayed.

static/wavey.gif

This is a binary file and will not be displayed.

-57
svelte.config.js
···
-
import adapter from 'svelte-adapter-bun';
-
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
-
-
import { mdsvex } from 'mdsvex';
-
-
import * as toml from '@std/toml';
-
import { resolve } from 'path';
-
-
/** @type {import('@sveltejs/kit').Config} */
-
const config = {
-
extensions: ['.svelte', '.md', '.svx'],
-
-
preprocess: [
-
vitePreprocess(),
-
mdsvex({
-
extensions: ['.md', '.svx'],
-
frontmatter: {
-
type: 'toml',
-
marker: '+',
-
parse(frontmatter, messages) {
-
try {
-
return toml.parse(frontmatter);
-
} catch (e) {
-
messages.push(
-
'Parsing error on line ' + e.line + ', column ' + e.column + ': ' + e.message
-
);
-
}
-
}
-
},
-
smartypants: {
-
dashes: 'oldschool',
-
quotes: true,
-
ellipses: true,
-
backticks: false
-
},
-
layout: {
-
about: resolve('src/routes/about/_layout.svelte'),
-
blogpost: resolve('src/routes/entries/_layout.svelte'),
-
simple: resolve('src/components/_window_layout.svelte')
-
}
-
})
-
],
-
-
kit: {
-
csrf: {
-
checkOrigin: false
-
},
-
prerender: {
-
handleHttpError: 'warn'
-
},
-
adapter: adapter({
-
precompress: true
-
})
-
}
-
};
-
-
export default config;
-57
tailwind.config.js
···
-
import typography from '@tailwindcss/typography';
-
import forms from '@tailwindcss/forms';
-
-
/** @type {import('tailwindcss').Config} */
-
export default {
-
content: ['./src/**/*.{html,js,svelte,ts,md}'],
-
theme: {
-
extend: {
-
typography: ({ theme }) => ({
-
ralsei: {
-
css: {
-
'--tw-prose-body': theme('colors.ralsei.white'),
-
'--tw-prose-headings': theme('colors.ralsei.pink.neon'),
-
'--tw-prose-lead': theme('colors.ralsei.white'),
-
'--tw-prose-links': theme('colors.ralsei.green.light'),
-
'--tw-prose-bold': theme('colors.ralsei.white'),
-
'--tw-prose-counters': theme('colors.ralsei.pink.regular'),
-
'--tw-prose-bullets': theme('colors.ralsei.pink.regular'),
-
'--tw-prose-hr': theme('colors.ralsei.white'),
-
'--tw-prose-quotes': theme('colors.ralsei.white'),
-
'--tw-prose-quote-borders': theme('colors.ralsei.white'),
-
'--tw-prose-captions': theme('colors.ralsei.white'),
-
'--tw-prose-code': theme('colors.ralsei.pink.regular'),
-
'--tw-prose-pre-code': theme('colors.ralsei.white'),
-
'--tw-prose-pre-bg': theme('colors.ralsei.green.dark'),
-
'--tw-prose-th-borders': theme('colors.ralsei.white'),
-
'--tw-prose-td-borders': theme('colors.ralsei.white')
-
}
-
}
-
}),
-
animation: {
-
'bounce-slow': 'bounce 3s infinite',
-
'pulse-fast': 'pulse 1s cubic-bezier(0.4, 0, 0.6, 1) infinite',
-
blink: 'blink 1s step-start infinite'
-
},
-
colors: {
-
ralsei: {
-
pink: {
-
regular: '#fe96e0',
-
neon: '#ff3eb7'
-
},
-
white: '#fff9fe',
-
black: '#000801',
-
green: {
-
light: '#4dcc8e',
-
dark: '#162d26'
-
}
-
}
-
}
-
},
-
fontFamily: {
-
'sans-serif': ['"Fusion Pixel 10px Proportional zh_hans", sans-serif'],
-
monospace: ['"Fusion Pixel 10px Monospaced zh_hans", monospace']
-
}
-
},
-
plugins: [typography, forms]
-
};
-24
tsconfig.json
···
-
{
-
"extends": "./.svelte-kit/tsconfig.json",
-
"compilerOptions": {
-
"allowJs": true,
-
"checkJs": true,
-
"esModuleInterop": true,
-
"forceConsistentCasingInFileNames": true,
-
"resolveJsonModule": true,
-
"skipLibCheck": true,
-
"sourceMap": true,
-
"strict": true,
-
"moduleResolution": "bundler",
-
"allowImportingTsExtensions": true,
-
"plugins": [{
-
"name": "typescript-svelte-plugin",
-
"enabled": true
-
}]
-
}
-
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
-
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
-
//
-
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
-
// from the referenced tsconfig.json - TypeScript does not merge them in
-
}
-6
vite.config.ts
···
-
import { sveltekit } from '@sveltejs/kit/vite';
-
import { defineConfig } from 'vite';
-
-
export default defineConfig({
-
plugins: [sveltekit()]
-
});