From e4441c98e3f03a3410fcc9624e600253acc89f49 Mon Sep 17 00:00:00 2001 From: HorizonCode Date: Thu, 26 Jun 2025 23:37:56 +0200 Subject: [PATCH] chore: do new design mockup --- .prettierrc | 30 + bun.lock | 630 ++++++++ bun.lockb | Bin 107615 -> 0 bytes components.json | 7 +- package.json | 65 +- src-tauri/Cargo.lock | 1290 ++++++++--------- src-tauri/Cargo.toml | 20 +- src-tauri/src/lib.rs | 130 +- src-tauri/src/reading_loop.rs | 462 ------ src-tauri/src/structs.rs | 1065 -------------- src-tauri/tauri.conf.json | 4 +- src/app.html | 2 +- src/lib/api/ezpp.ts | 17 + .../alert-dialog/alert-dialog-action.svelte | 13 + .../alert-dialog/alert-dialog-cancel.svelte | 17 + .../alert-dialog/alert-dialog-content.svelte | 26 + .../alert-dialog-description.svelte | 16 + .../alert-dialog/alert-dialog-footer.svelte | 20 + .../alert-dialog/alert-dialog-header.svelte | 20 + .../alert-dialog/alert-dialog-overlay.svelte | 19 + .../ui/alert-dialog/alert-dialog-title.svelte | 18 + src/lib/components/ui/alert-dialog/index.ts | 39 + .../ui/background/background.svelte | 2 +- src/lib/components/ui/logo/logo.svelte | 4 +- src/lib/components/ui/progress/index.ts | 7 + .../components/ui/progress/progress.svelte | 44 + .../ui/progressbar/progressbar.svelte | 20 - src/lib/components/ui/select/index.ts | 34 + .../ui/select/select-content.svelte | 39 + .../ui/select/select-group-heading.svelte | 16 + .../components/ui/select/select-item.svelte | 37 + .../select/select-scroll-down-button.svelte | 19 + .../ui/select/select-scroll-up-button.svelte | 19 + .../ui/select/select-separator.svelte | 13 + .../ui/select/select-trigger.svelte | 24 + src/lib/components/ui/separator/index.ts | 7 + .../components/ui/separator/separator.svelte | 22 + .../components/ui/titlebar/titlebar.svelte | 14 +- src/lib/global.ts | 44 + src/routes/+layout.svelte | 8 +- src/routes/+page.svelte | 282 +++- svelte.config.js | 4 +- tailwind.config.ts | 201 +-- tsconfig.json | 2 +- 44 files changed, 2145 insertions(+), 2627 deletions(-) create mode 100644 .prettierrc create mode 100644 bun.lock delete mode 100644 bun.lockb delete mode 100644 src-tauri/src/reading_loop.rs delete mode 100644 src-tauri/src/structs.rs create mode 100644 src/lib/api/ezpp.ts create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-action.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-content.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-description.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-header.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte create mode 100644 src/lib/components/ui/alert-dialog/alert-dialog-title.svelte create mode 100644 src/lib/components/ui/alert-dialog/index.ts create mode 100644 src/lib/components/ui/progress/index.ts create mode 100644 src/lib/components/ui/progress/progress.svelte delete mode 100644 src/lib/components/ui/progressbar/progressbar.svelte create mode 100644 src/lib/components/ui/select/index.ts create mode 100644 src/lib/components/ui/select/select-content.svelte create mode 100644 src/lib/components/ui/select/select-group-heading.svelte create mode 100644 src/lib/components/ui/select/select-item.svelte create mode 100644 src/lib/components/ui/select/select-scroll-down-button.svelte create mode 100644 src/lib/components/ui/select/select-scroll-up-button.svelte create mode 100644 src/lib/components/ui/select/select-separator.svelte create mode 100644 src/lib/components/ui/select/select-trigger.svelte create mode 100644 src/lib/components/ui/separator/index.ts create mode 100644 src/lib/components/ui/separator/separator.svelte create mode 100644 src/lib/global.ts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..e4375aa --- /dev/null +++ b/.prettierrc @@ -0,0 +1,30 @@ +{ + "bracketSameLine": false, + "insertPragma": false, + "arrowParens": "always", + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "printWidth": 100, + "tabWidth": 2, + "useTabs": false, + "bracketSpacing": true, + "svelteBracketNewLine": true, + "plugins": ["prettier-plugin-svelte"], + "overrides": [ + { + "files": "*.svelte", + "options": { + "parser": "svelte" + } + }, + { + "files": "*.{css,pcss}", + "options": { + "tabWidth": 2, + "useTabs": false, + "singleQuote": false + } + } + ] +} \ No newline at end of file diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..bd27728 --- /dev/null +++ b/bun.lock @@ -0,0 +1,630 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "ezpplauncher", + "dependencies": { + "@elron/svelte-audio-store": "1.0.0", + "@number-flow/svelte": "^0.3.9", + "@tailwindcss/typography": "0.5.16", + "@tauri-apps/api": "2.6.0", + "@tauri-apps/plugin-dialog": "2.3.0", + "@tauri-apps/plugin-fs": "2.4.0", + "@tauri-apps/plugin-shell": "2.3.0", + "@tauri-apps/plugin-sql": "2.3.0", + "ky": "1.8.1", + "lucide-svelte": "0.523.0", + "osu-classes": "3.1.0", + "osu-parsers": "4.1.7", + "radix-icons-svelte": "1.2.1", + }, + "devDependencies": { + "@lucide/svelte": "^0.482.0", + "@sveltejs/adapter-static": "3.0.8", + "@sveltejs/kit": "2.22.2", + "@sveltejs/vite-plugin-svelte": "5.1.0", + "@tauri-apps/cli": "2.6.1", + "autoprefixer": "10.4.21", + "bits-ui": "^1.4.7", + "clsx": "2.1.1", + "prettier": "^3.6.1", + "prettier-plugin-svelte": "^3.4.0", + "sass-embedded": "1.89.2", + "svelte": "5.34.8", + "svelte-check": "4.2.2", + "tailwind-merge": "2.5.5", + "tailwind-variants": "0.3.1", + "tailwindcss": "3.4.17", + "tailwindcss-animate": "1.0.7", + "tslib": "2.8.1", + "typescript": "5.8.3", + "vite": "7.0.0", + }, + }, + }, + "packages": { + "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + + "@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="], + + "@bufbuild/protobuf": ["@bufbuild/protobuf@2.5.2", "", {}, "sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg=="], + + "@elron/svelte-audio-store": ["@elron/svelte-audio-store@1.0.0", "", { "peerDependencies": { "svelte": "^4.0.0" } }, "sha512-ksBF88rG4cbIt+ZLrxMKDdr1CxWxxEiyyZfHfNHCF/G9O2eDflSnCytSpid0Y43R4DwK+AukUlFfc0j5evqqEw=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.5", "", { "os": "android", "cpu": "arm" }, "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.5", "", { "os": "android", "cpu": "arm64" }, "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.5", "", { "os": "android", "cpu": "x64" }, "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.5", "", { "os": "linux", "cpu": "arm" }, "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.5", "", { "os": "linux", "cpu": "none" }, "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.5", "", { "os": "linux", "cpu": "x64" }, "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.5", "", { "os": "none", "cpu": "arm64" }, "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.5", "", { "os": "none", "cpu": "x64" }, "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.5", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g=="], + + "@floating-ui/core": ["@floating-ui/core@1.7.1", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-azI0DrjMMfIug/ExbBaeDVJXcY0a7EPvPjb2xAJPa4HeimBX+Z18HK8QQR3jb6356SnDDdxx+hinMLcJEDdOjw=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.7.1", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/utils": "^0.2.9" } }, "sha512-cwsmW/zyw5ltYTUeeYJ60CnQuPqmGwuGVhG9w0PRaRKkAyi38BT5CKrpIbb+jtahSwUl04cWzSx9ZOIxeS6RsQ=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="], + + "@internationalized/date": ["@internationalized/date@3.8.2", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA=="], + + "@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=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], + + "@lucide/svelte": ["@lucide/svelte@0.482.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-n2ycHU9cNcleRDwwpEHBJ6pYzVhHIaL3a+9dQa8kns9hB2g05bY+v2p2KP8v0pZwtNhYTHk/F2o2uZ1bVtQGhw=="], + + "@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=="], + + "@number-flow/svelte": ["@number-flow/svelte@0.3.9", "", { "dependencies": { "esm-env": "^1.1.4", "number-flow": "0.5.8" }, "peerDependencies": { "svelte": "^4 || ^5" } }, "sha512-CTw1+e0074GzbPX2IHcNCaK8nqxGNCOIUnQUjEjhcmBwBxOAhN3GYLQ6cJHvhQnWwplVe4eQ3z+c25Vttr2stQ=="], + + "@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=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.44.1", "", { "os": "android", "cpu": "arm" }, "sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.44.1", "", { "os": "android", "cpu": "arm64" }, "sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.44.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.44.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.44.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.44.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.44.1", "", { "os": "linux", "cpu": "arm" }, "sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.44.1", "", { "os": "linux", "cpu": "arm" }, "sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.44.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.44.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g=="], + + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.44.1", "", { "os": "linux", "cpu": "none" }, "sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew=="], + + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.44.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.44.1", "", { "os": "linux", "cpu": "none" }, "sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.44.1", "", { "os": "linux", "cpu": "none" }, "sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.44.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.44.1", "", { "os": "linux", "cpu": "x64" }, "sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.44.1", "", { "os": "linux", "cpu": "x64" }, "sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.44.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.44.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.44.1", "", { "os": "win32", "cpu": "x64" }, "sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug=="], + + "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="], + + "@sveltejs/adapter-static": ["@sveltejs/adapter-static@3.0.8", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg=="], + + "@sveltejs/kit": ["@sveltejs/kit@2.22.2", "", { "dependencies": { "@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", "vitefu": "^1.0.6" }, "peerDependencies": { "@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" }, "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-2MvEpSYabUrsJAoq5qCOBGAlkICjfjunrnLcx3YAk2XV7TvAIhomlKsAgR4H/4uns5rAfYmj7Wet5KRtc8dPIg=="], + + "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@5.1.0", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", "vitefu": "^1.0.6" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw=="], + + "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@4.0.1", "", { "dependencies": { "debug": "^4.3.7" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte": "^5.0.0", "vite": "^6.0.0" } }, "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw=="], + + "@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="], + + "@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=="], + + "@tauri-apps/api": ["@tauri-apps/api@2.6.0", "", {}, "sha512-hRNcdercfgpzgFrMXWwNDBN0B7vNzOzRepy6ZAmhxi5mDLVPNrTpo9MGg2tN/F7JRugj4d2aF7E1rtPXAHaetg=="], + + "@tauri-apps/cli": ["@tauri-apps/cli@2.6.1", "", { "optionalDependencies": { "@tauri-apps/cli-darwin-arm64": "2.6.1", "@tauri-apps/cli-darwin-x64": "2.6.1", "@tauri-apps/cli-linux-arm-gnueabihf": "2.6.1", "@tauri-apps/cli-linux-arm64-gnu": "2.6.1", "@tauri-apps/cli-linux-arm64-musl": "2.6.1", "@tauri-apps/cli-linux-riscv64-gnu": "2.6.1", "@tauri-apps/cli-linux-x64-gnu": "2.6.1", "@tauri-apps/cli-linux-x64-musl": "2.6.1", "@tauri-apps/cli-win32-arm64-msvc": "2.6.1", "@tauri-apps/cli-win32-ia32-msvc": "2.6.1", "@tauri-apps/cli-win32-x64-msvc": "2.6.1" }, "bin": { "tauri": "tauri.js" } }, "sha512-8NrwfZjeyKH1zwg+Xu4epx8WLjffoiW1Zs9CCFYCJns7uUghzudDm92o+8ROosg5Njlvp1GXBuIRsdrEwBsDhg=="], + + "@tauri-apps/cli-darwin-arm64": ["@tauri-apps/cli-darwin-arm64@2.6.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-67aVLeXcJrl9D+4xQLR8NCQYKXQyZB96Tai+uy53jOY0u+uKvFngjbSS9CmntILFhLWoueDxQj3Ws5OSvjekiA=="], + + "@tauri-apps/cli-darwin-x64": ["@tauri-apps/cli-darwin-x64@2.6.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-6mQp/VikM0pKVKau1p/NMVyGq1JakOFbk6YlCzwdd04OwmiDuVe9PTxzqcA/JnqWXEhSGlRKeyMXUxqifPBPYw=="], + + "@tauri-apps/cli-linux-arm-gnueabihf": ["@tauri-apps/cli-linux-arm-gnueabihf@2.6.1", "", { "os": "linux", "cpu": "arm" }, "sha512-iY9cr2k3h2nh6I0bExEWCOgWloN4q0p/evhfNBIAIly1kycy+xWHEsFj2WfzU31Ce8RkqxilPHNuCp36gDM+Yw=="], + + "@tauri-apps/cli-linux-arm64-gnu": ["@tauri-apps/cli-linux-arm64-gnu@2.6.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-AT+SpHShi/uJipzj+A9kHPDUgZfzHYyl0B3/4UXYtHB9hQfQUmjh9wLadmx0ai/ESyJFxkJJK6FFRvxotQ3gIQ=="], + + "@tauri-apps/cli-linux-arm64-musl": ["@tauri-apps/cli-linux-arm64-musl@2.6.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-CCgE0uqcWTtU48TmK/J03h5x/hxi3PEc11ci3LQ9WqIE15btyhynNzDKbxKwOyDCMcfbDT+MweoiCPnely2ZRA=="], + + "@tauri-apps/cli-linux-riscv64-gnu": ["@tauri-apps/cli-linux-riscv64-gnu@2.6.1", "", { "os": "linux", "cpu": "none" }, "sha512-2i3MYr2oKaJk7Tz2FZ+R5x8cV827CudvEXW6FzCER26pfx/PofH/55N7aRQf4+qPXi5O3T+3myq88nRerzHr6g=="], + + "@tauri-apps/cli-linux-x64-gnu": ["@tauri-apps/cli-linux-x64-gnu@2.6.1", "", { "os": "linux", "cpu": "x64" }, "sha512-of5i3FW1tjTXECtMdirQsQnVIzcKq1s5Cad9YLVa6agEnFnZbFU3rKQ6/Wfu5SZbjSiI7SBO1hksjIAq1vkVcg=="], + + "@tauri-apps/cli-linux-x64-musl": ["@tauri-apps/cli-linux-x64-musl@2.6.1", "", { "os": "linux", "cpu": "x64" }, "sha512-QfAgg7VIlOrTa2X3fBLRp6ugbC5ZonSWgVhNCLDgHLp5Cga41XOi5qU7ZtZhjjCdcWNiE0DtBQmSb1YVhCp+SA=="], + + "@tauri-apps/cli-win32-arm64-msvc": ["@tauri-apps/cli-win32-arm64-msvc@2.6.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-ee1h3jwamumGjLEXZA4VsSUcVWTtGpuvxy+nqFfu7wb2k6IcBrFEJGa6yXa7sQjuCAAorLfSIXGuDEJARqnpFw=="], + + "@tauri-apps/cli-win32-ia32-msvc": ["@tauri-apps/cli-win32-ia32-msvc@2.6.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-WEZVYekxuG9X9mFJEeJPHsSAl8sHOEEbJQriim+OziFbLA9pv/gfcRRqsbmEJL8uBC8GLTEOdUVolohwXk6S9g=="], + + "@tauri-apps/cli-win32-x64-msvc": ["@tauri-apps/cli-win32-x64-msvc@2.6.1", "", { "os": "win32", "cpu": "x64" }, "sha512-fBsjPqIIHaaQt7tnjIGmPHu5p/BNBVD4JfOhO3QqIVBzAb+W2bDyIQPdoDMI943soLr/+N10xeTiPu+3L74+dQ=="], + + "@tauri-apps/plugin-dialog": ["@tauri-apps/plugin-dialog@2.3.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-ylSBvYYShpGlKKh732ZuaHyJ5Ie1JR71QCXewCtsRLqGdc8Is4xWdz6t43rzXyvkItM9syNPMvFVcvjgEy+/GA=="], + + "@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g=="], + + "@tauri-apps/plugin-shell": ["@tauri-apps/plugin-shell@2.3.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-6GIRxO2z64uxPX4CCTuhQzefvCC0ew7HjdBhMALiGw74vFBDY95VWueAHOHgNOMV4UOUAFupyidN9YulTe5xlA=="], + + "@tauri-apps/plugin-sql": ["@tauri-apps/plugin-sql@2.3.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-JYwIocfsLaDWa41LMiZWuzts7yCJR+EpZPRmgpO7Gd7XiAS9S67dKz306j/k/d9XntB0YopMRBol2OIWMschuA=="], + + "@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/node": ["@types/node@20.19.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA=="], + + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], + + "ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], + + "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=="], + + "aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="], + + "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=="], + + "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=="], + + "bits-ui": ["bits-ui@1.8.0", "", { "dependencies": { "@floating-ui/core": "^1.6.4", "@floating-ui/dom": "^1.6.7", "@internationalized/date": "^3.5.6", "css.escape": "^1.5.1", "esm-env": "^1.1.2", "runed": "^0.23.2", "svelte-toolbelt": "^0.7.1", "tabbable": "^6.2.0" }, "peerDependencies": { "svelte": "^5.11.0" } }, "sha512-CXD6Orp7l8QevNDcRPLXc/b8iMVgxDWT2LyTwsdLzJKh9CxesOmPuNePSPqAxKoT59FIdU4aFPS1k7eBdbaCxg=="], + + "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], + + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + + "browserslist": ["browserslist@4.25.1", "", { "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw=="], + + "buffer-builder": ["buffer-builder@0.2.0", "", {}, "sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg=="], + + "camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="], + + "caniuse-lite": ["caniuse-lite@1.0.30001726", "", {}, "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw=="], + + "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=="], + + "colorjs.io": ["colorjs.io@0.5.2", "", {}, "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw=="], + + "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], + + "cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "css.escape": ["css.escape@1.5.1", "", {}, "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg=="], + + "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "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=="], + + "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], + + "electron-to-chromium": ["electron-to-chromium@1.5.176", "", {}, "sha512-2nDK9orkm7M9ZZkjO3PjbEd3VUulQLyg5T9O3enJdFvUg46Hzd4DUvTvAuEgbdHYXyFsiG4A5sO9IzToMH1cDg=="], + + "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + + "esbuild": ["esbuild@0.25.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.5", "@esbuild/android-arm": "0.25.5", "@esbuild/android-arm64": "0.25.5", "@esbuild/android-x64": "0.25.5", "@esbuild/darwin-arm64": "0.25.5", "@esbuild/darwin-x64": "0.25.5", "@esbuild/freebsd-arm64": "0.25.5", "@esbuild/freebsd-x64": "0.25.5", "@esbuild/linux-arm": "0.25.5", "@esbuild/linux-arm64": "0.25.5", "@esbuild/linux-ia32": "0.25.5", "@esbuild/linux-loong64": "0.25.5", "@esbuild/linux-mips64el": "0.25.5", "@esbuild/linux-ppc64": "0.25.5", "@esbuild/linux-riscv64": "0.25.5", "@esbuild/linux-s390x": "0.25.5", "@esbuild/linux-x64": "0.25.5", "@esbuild/netbsd-arm64": "0.25.5", "@esbuild/netbsd-x64": "0.25.5", "@esbuild/openbsd-arm64": "0.25.5", "@esbuild/openbsd-x64": "0.25.5", "@esbuild/sunos-x64": "0.25.5", "@esbuild/win32-arm64": "0.25.5", "@esbuild/win32-ia32": "0.25.5", "@esbuild/win32-x64": "0.25.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="], + + "esrap": ["esrap@1.4.9", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-3OMlcd0a03UGuZpPeUC1HxR3nA23l+HEyCiZw3b3FumJIN9KphoGzDJKMXI1S72jVS1dsenDyQC0kJlO1U9E1g=="], + + "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=="], + + "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=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + + "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=="], + + "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=="], + + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], + + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + + "immutable": ["immutable@5.1.3", "", {}, "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg=="], + + "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], + + "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=="], + + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + + "ky": ["ky@1.8.1", "", {}, "sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw=="], + + "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=="], + + "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=="], + + "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "lucide-svelte": ["lucide-svelte@0.523.0", "", { "peerDependencies": { "svelte": "^3 || ^4 || ^5.0.0-next.42" } }, "sha512-aFLBJxFLY7e2Hu0yPb/vG+UwfAYWMkT4ZBhqC3wv9AmfNW7P/b8XDjfcSY1GREihBDgUo9fWoQiXVWsNHGIUJg=="], + + "lzma-js-simple-v2": ["lzma-js-simple-v2@1.2.3", "", { "dependencies": { "@types/node": "^20.12.7" } }, "sha512-6kgy86Q3YLolV6dOwCqdQXg3V07e3XJJ6wqfrN8/s65mvCfqkr+jMJkfiSZNvk+u2ig+G8rLdtaoW/g1oJiwow=="], + + "magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "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=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="], + + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], + + "normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="], + + "number-flow": ["number-flow@0.5.8", "", { "dependencies": { "esm-env": "^1.1.4" } }, "sha512-FPr1DumWyGi5Nucoug14bC6xEz70A1TnhgSHhKyfqjgji2SOTz+iLJxKtv37N5JyJbteGYCm6NQ9p1O4KZ7iiA=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="], + + "osu-classes": ["osu-classes@3.1.0", "", {}, "sha512-kz38FWMGnz5lr6ofovUrNaDAcs1gNpwlDc1qHjW86ILQZXG44w/+NflV7EyFomkI05XCADGfltE4FVoPwrkrmg=="], + + "osu-parsers": ["osu-parsers@4.1.7", "", { "dependencies": { "lzma-js-simple-v2": "^1.2.3" }, "peerDependencies": { "osu-classes": "^3.1.0" } }, "sha512-b8aYJy9vK0Yk8zVbxVN+HSChGnXufSxePb3gABG8s5YGCY+31CKJTUHDAVRST0kX4lyeI4Z3iRxsCRftHFHEug=="], + + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + + "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.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "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@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=="], + + "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-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], + + "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], + + "prettier": ["prettier@3.6.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-5xGWRa90Sp2+x1dQtNpIpeOQpTDBs9cZDmA/qs2vDNN2i18PdapqY7CmBeyLlMuGqXJRIOPaCaVZTLNQRWUH/A=="], + + "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=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "radix-icons-svelte": ["radix-icons-svelte@1.2.1", "", {}, "sha512-svmiMd0ocpdTm9cvAz0klcZpnh639lVctj6psQiawd4pYalVzOG4cX+JizAgRckyTAsRVdzObP7D2EBrSfdghA=="], + + "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=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "rollup": ["rollup@4.44.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.44.1", "@rollup/rollup-android-arm64": "4.44.1", "@rollup/rollup-darwin-arm64": "4.44.1", "@rollup/rollup-darwin-x64": "4.44.1", "@rollup/rollup-freebsd-arm64": "4.44.1", "@rollup/rollup-freebsd-x64": "4.44.1", "@rollup/rollup-linux-arm-gnueabihf": "4.44.1", "@rollup/rollup-linux-arm-musleabihf": "4.44.1", "@rollup/rollup-linux-arm64-gnu": "4.44.1", "@rollup/rollup-linux-arm64-musl": "4.44.1", "@rollup/rollup-linux-loongarch64-gnu": "4.44.1", "@rollup/rollup-linux-powerpc64le-gnu": "4.44.1", "@rollup/rollup-linux-riscv64-gnu": "4.44.1", "@rollup/rollup-linux-riscv64-musl": "4.44.1", "@rollup/rollup-linux-s390x-gnu": "4.44.1", "@rollup/rollup-linux-x64-gnu": "4.44.1", "@rollup/rollup-linux-x64-musl": "4.44.1", "@rollup/rollup-win32-arm64-msvc": "4.44.1", "@rollup/rollup-win32-ia32-msvc": "4.44.1", "@rollup/rollup-win32-x64-msvc": "4.44.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "runed": ["runed@0.23.4", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA=="], + + "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], + + "sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="], + + "sass-embedded": ["sass-embedded@1.89.2", "", { "dependencies": { "@bufbuild/protobuf": "^2.5.0", "buffer-builder": "^0.2.0", "colorjs.io": "^0.5.0", "immutable": "^5.0.2", "rxjs": "^7.4.0", "supports-color": "^8.1.1", "sync-child-process": "^1.0.2", "varint": "^6.0.0" }, "optionalDependencies": { "sass-embedded-android-arm": "1.89.2", "sass-embedded-android-arm64": "1.89.2", "sass-embedded-android-riscv64": "1.89.2", "sass-embedded-android-x64": "1.89.2", "sass-embedded-darwin-arm64": "1.89.2", "sass-embedded-darwin-x64": "1.89.2", "sass-embedded-linux-arm": "1.89.2", "sass-embedded-linux-arm64": "1.89.2", "sass-embedded-linux-musl-arm": "1.89.2", "sass-embedded-linux-musl-arm64": "1.89.2", "sass-embedded-linux-musl-riscv64": "1.89.2", "sass-embedded-linux-musl-x64": "1.89.2", "sass-embedded-linux-riscv64": "1.89.2", "sass-embedded-linux-x64": "1.89.2", "sass-embedded-win32-arm64": "1.89.2", "sass-embedded-win32-x64": "1.89.2" }, "bin": { "sass": "dist/bin/sass.js" } }, "sha512-Ack2K8rc57kCFcYlf3HXpZEJFNUX8xd8DILldksREmYXQkRHI879yy8q4mRDJgrojkySMZqmmmW1NxrFxMsYaA=="], + + "sass-embedded-android-arm": ["sass-embedded-android-arm@1.89.2", "", { "os": "android", "cpu": "arm" }, "sha512-oHAPTboBHRZlDBhyRB6dvDKh4KvFs+DZibDHXbkSI6dBZxMTT+Yb2ivocHnctVGucKTLQeT7+OM5DjWHyynL/A=="], + + "sass-embedded-android-arm64": ["sass-embedded-android-arm64@1.89.2", "", { "os": "android", "cpu": "arm64" }, "sha512-+pq7a7AUpItNyPu61sRlP6G2A8pSPpyazASb+8AK2pVlFayCSPAEgpwpCE9A2/Xj86xJZeMizzKUHxM2CBCUxA=="], + + "sass-embedded-android-riscv64": ["sass-embedded-android-riscv64@1.89.2", "", { "os": "android", "cpu": "none" }, "sha512-HfJJWp/S6XSYvlGAqNdakeEMPOdhBkj2s2lN6SHnON54rahKem+z9pUbCriUJfM65Z90lakdGuOfidY61R9TYg=="], + + "sass-embedded-android-x64": ["sass-embedded-android-x64@1.89.2", "", { "os": "android", "cpu": "x64" }, "sha512-BGPzq53VH5z5HN8de6jfMqJjnRe1E6sfnCWFd4pK+CAiuM7iw5Fx6BQZu3ikfI1l2GY0y6pRXzsVLdp/j4EKEA=="], + + "sass-embedded-darwin-arm64": ["sass-embedded-darwin-arm64@1.89.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UCm3RL/tzMpG7DsubARsvGUNXC5pgfQvP+RRFJo9XPIi6elopY5B6H4m9dRYDpHA+scjVthdiDwkPYr9+S/KGw=="], + + "sass-embedded-darwin-x64": ["sass-embedded-darwin-x64@1.89.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-D9WxtDY5VYtMApXRuhQK9VkPHB8R79NIIR6xxVlN2MIdEid/TZWi1MHNweieETXhWGrKhRKglwnHxxyKdJYMnA=="], + + "sass-embedded-linux-arm": ["sass-embedded-linux-arm@1.89.2", "", { "os": "linux", "cpu": "arm" }, "sha512-leP0t5U4r95dc90o8TCWfxNXwMAsQhpWxTkdtySDpngoqtTy3miMd7EYNYd1znI0FN1CBaUvbdCMbnbPwygDlA=="], + + "sass-embedded-linux-arm64": ["sass-embedded-linux-arm64@1.89.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-2N4WW5LLsbtrWUJ7iTpjvhajGIbmDR18ZzYRywHdMLpfdPApuHPMDF5CYzHbS+LLx2UAx7CFKBnj5LLjY6eFgQ=="], + + "sass-embedded-linux-musl-arm": ["sass-embedded-linux-musl-arm@1.89.2", "", { "os": "linux", "cpu": "arm" }, "sha512-Z6gG2FiVEEdxYHRi2sS5VIYBmp17351bWtOCUZ/thBM66+e70yiN6Eyqjz80DjL8haRUegNQgy9ZJqsLAAmr9g=="], + + "sass-embedded-linux-musl-arm64": ["sass-embedded-linux-musl-arm64@1.89.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-nTyuaBX6U1A/cG7WJh0pKD1gY8hbg1m2SnzsyoFG+exQ0lBX/lwTLHq3nyhF+0atv7YYhYKbmfz+sjPP8CZ9lw=="], + + "sass-embedded-linux-musl-riscv64": ["sass-embedded-linux-musl-riscv64@1.89.2", "", { "os": "linux", "cpu": "none" }, "sha512-N6oul+qALO0SwGY8JW7H/Vs0oZIMrRMBM4GqX3AjM/6y8JsJRxkAwnfd0fDyK+aICMFarDqQonQNIx99gdTZqw=="], + + "sass-embedded-linux-musl-x64": ["sass-embedded-linux-musl-x64@1.89.2", "", { "os": "linux", "cpu": "x64" }, "sha512-K+FmWcdj/uyP8GiG9foxOCPfb5OAZG0uSVq80DKgVSC0U44AdGjvAvVZkrgFEcZ6cCqlNC2JfYmslB5iqdL7tg=="], + + "sass-embedded-linux-riscv64": ["sass-embedded-linux-riscv64@1.89.2", "", { "os": "linux", "cpu": "none" }, "sha512-g9nTbnD/3yhOaskeqeBQETbtfDQWRgsjHok6bn7DdAuwBsyrR3JlSFyqKc46pn9Xxd9SQQZU8AzM4IR+sY0A0w=="], + + "sass-embedded-linux-x64": ["sass-embedded-linux-x64@1.89.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Ax7dKvzncyQzIl4r7012KCMBvJzOz4uwSNoyoM5IV6y5I1f5hEwI25+U4WfuTqdkv42taCMgpjZbh9ERr6JVMQ=="], + + "sass-embedded-win32-arm64": ["sass-embedded-win32-arm64@1.89.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-j96iJni50ZUsfD6tRxDQE2QSYQ2WrfHxeiyAXf41Kw0V4w5KYR/Sf6rCZQLMTUOHnD16qTMVpQi20LQSqf4WGg=="], + + "sass-embedded-win32-x64": ["sass-embedded-win32-x64@1.89.2", "", { "os": "win32", "cpu": "x64" }, "sha512-cS2j5ljdkQsb4PaORiClaVYynE9OAPZG/XjbOMxpQmjRIf7UroY4PEIH+Waf+y47PfXFX9SyxhYuw2NIKGbEng=="], + + "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=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "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=="], + + "style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="], + + "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@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], + + "svelte": ["svelte@5.34.8", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@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": "^1.4.8", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-TF+8irl7rpj3+fpaLuPRX5BqReTAqckp0Fumxa/mCeK3fo0/MnBb9W/Z2bLwtqj3C3r5Lm6NKIAw7YrgIv1Fwg=="], + + "svelte-check": ["svelte-check@4.2.2", "", { "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-1+31EOYZ7NKN0YDMKusav2hhEoA51GD9Ws6o//0SphMT0ve9mBTsTUEX7OmDMadUP3KjNHsSKtJrqdSaD8CrGQ=="], + + "svelte-toolbelt": ["svelte-toolbelt@0.7.1", "", { "dependencies": { "clsx": "^2.1.1", "runed": "^0.23.2", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ=="], + + "sync-child-process": ["sync-child-process@1.0.2", "", { "dependencies": { "sync-message-port": "^1.0.0" } }, "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA=="], + + "sync-message-port": ["sync-message-port@1.1.3", "", {}, "sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg=="], + + "tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="], + + "tailwind-merge": ["tailwind-merge@2.5.5", "", {}, "sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA=="], + + "tailwind-variants": ["tailwind-variants@0.3.1", "", { "dependencies": { "tailwind-merge": "2.5.4" }, "peerDependencies": { "tailwindcss": "*" } }, "sha512-krn67M3FpPwElg4FsZrOQd0U26o7UDH/QOkK8RNaiCCrr052f6YJPBUfNKnPo/s/xRzNPtv1Mldlxsg8Tb46BQ=="], + + "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=="], + + "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="], + + "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=="], + + "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-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=="], + + "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "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=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "varint": ["varint@6.0.0", "", {}, "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="], + + "vite": ["vite@7.0.0", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.2", "postcss": "^8.5.6", "rollup": "^4.40.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-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g=="], + + "vitefu": ["vitefu@1.0.7", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-eRWXLBbJjW3X5z5P5IHcSm2yYbYRPb2kQuc+oqsbAl99WB5kVsPbiiox+cymo8twTzifA6itvhr2CmjnaZZp0Q=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "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@2.8.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ=="], + + "zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="], + + "@tailwindcss/typography/postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="], + + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "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=="], + + "tailwind-variants/tailwind-merge": ["tailwind-merge@2.5.4", "", {}, "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q=="], + + "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=="], + + "wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "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=="], + + "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=="], + + "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=="], + } +} diff --git a/bun.lockb b/bun.lockb deleted file mode 100644 index a09b4b3fa68eb0fbc3d812320cf7b56e29b6937e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107615 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 p, - Err(e) => { - println!("{:?}", Report::new(e)); - thread::sleep(Duration::from_millis(5000)); - continue 'init_loop; - } - }; - - let mut values = state.values.lock().unwrap(); - - println!("Using auto-detected osu! folder path"); - if let Some(ref dir) = p.executable_dir { - values.osu_path.clone_from(dir); - } else { - println!( - "{:?}", - Report::msg( - "Can't auto-detect osu! folder path \ - nor any was provided through command \ - line argument", - ) - ); - continue 'init_loop; - } - - if !values.osu_path.exists() { - println!( - "Provided osu path doesn't exists!\n Path: {}", - &values.osu_path.to_str().unwrap() - ); - - println!( - "{:?}", - Report::msg( - "Can't auto-detect osu! folder path \ - nor any was provided through command \ - line argument", - ) - ); - continue 'init_loop; - }; - - drop(values); - - println!("Reading static signatures..."); - match StaticAddresses::new(&p) { - Ok(v) => state.addresses = v, - Err(e) => match e.downcast_ref::() { - Some(&ProcessError::ProcessNotFound) => { - thread::sleep(Duration::from_millis(2000)); - continue 'init_loop; - } - #[cfg(target_os = "windows")] - Some(&ProcessError::OsError { .. }) => { - println!("{:?}", e); - thread::sleep(Duration::from_millis(2000)); - continue 'init_loop; - } - Some(_) | None => { - println!("{:?}", e); - thread::sleep(Duration::from_millis(2000)); - continue 'init_loop; - } - }, - }; - - println!("osu! process found, Starting reading loop"); - - 'main_loop: loop { - if let Err(e) = process_reading_loop(&p, &mut state) { - match e.downcast_ref::() { - Some(&ProcessError::ProcessNotFound) => { - thread::sleep(Duration::from_millis(5000)); - continue 'init_loop; - } - #[cfg(target_os = "windows")] - Some(&ProcessError::OsError { .. }) => { - println!("{:?}", e); - thread::sleep(Duration::from_millis(5000)); - continue 'init_loop; - } - Some(_) | None => { - println!("{:?}", e); - thread::sleep(Duration::from_millis(5000)); - continue 'main_loop; - } - } - } - let cloned_values = state.values.clone(); - let values_lock = cloned_values.lock().unwrap(); - let values = &*values_lock; - - println!("{:?}", values.current_stars); - thread::sleep(Duration::from_millis(2000)); - } - } - }); -} +} \ No newline at end of file diff --git a/src-tauri/src/reading_loop.rs b/src-tauri/src/reading_loop.rs deleted file mode 100644 index 3f1e0ab..0000000 --- a/src-tauri/src/reading_loop.rs +++ /dev/null @@ -1,462 +0,0 @@ -use std::{borrow::Cow, mem::size_of}; - -use rosu_pp::Beatmap; -use tracy_client::*; -use eyre::Result; - -use rosu_mem::process::{Process, ProcessTraits}; - -use crate::structs::{State, GameState, BeatmapStatus, OutputValues}; - - -/// Here cases when key overlay is not gonna be available for reading: -/// 1. Map is not fully loaded -/// 2. If key overlay is not enabled in settings -pub fn process_key_overlay( - p: &Process, - values: &mut OutputValues, - ruleset_addr: i32, -) -> Result<()> { - let keyoverlay_ptr = p.read_i32(ruleset_addr + 0xB0)?; - - if keyoverlay_ptr == 0 { - return Ok(()) - } - - // TODO optimize using batches? - - let keyoverlay_addr = p.read_i32( - p.read_i32(keyoverlay_ptr + 0x10)? + 0x4 - )?; - - values.keyoverlay.k1_pressed = p.read_i8( - p.read_i32(keyoverlay_addr + 0x8)? + 0x1C - )? != 0; - - values.keyoverlay.k1_count = p.read_i32( - p.read_i32(keyoverlay_addr + 0x8)? + 0x14 - )? as u32; - - values.keyoverlay.k2_pressed = p.read_i8( - p.read_i32(keyoverlay_addr + 0xC)? + 0x1C - )? != 0; - - values.keyoverlay.k2_count = p.read_i32( - p.read_i32(keyoverlay_addr + 0xC)? + 0x14 - )? as u32; - - values.keyoverlay.m1_pressed = p.read_i8( - p.read_i32(keyoverlay_addr + 0x10)? + 0x1C - )? != 0; - - values.keyoverlay.m1_count = p.read_i32( - p.read_i32(keyoverlay_addr + 0x10)? + 0x14 - )? as u32; - - values.keyoverlay.m2_pressed = p.read_i8( - p.read_i32(keyoverlay_addr + 0x14)? + 0x1C - )? != 0; - - values.keyoverlay.m2_count = p.read_i32( - p.read_i32(keyoverlay_addr + 0x14)? + 0x14 - )? as u32; - - Ok(()) -} - -pub fn process_gameplay( - p: &Process, - state: &mut State, - values: &mut OutputValues, - ruleset_addr: i32, -) -> Result<()> { - let _span = span!("Gameplay data"); - - if values.prev_playtime > values.playtime { - values.reset_gameplay(); - state.ivalues.reset(); - } - - values.prev_playtime = values.playtime; - - if ruleset_addr == 0 { - return Ok(()) - }; - - let gameplay_base = - p.read_i32(ruleset_addr + 0x68)?; - - if gameplay_base == 0 { - return Ok(()) - } - - let score_base = p.read_i32(gameplay_base + 0x38)?; - - let hp_base = p.read_i32(gameplay_base + 0x40)?; - - // Random value but seems to work pretty well - // TODO sometimes playtime is >150 but game doesn't have - // values yet unreal to debug, occurs rarely and randomly - if values.playtime > 150 { - values.gameplay.current_hp = p.read_f64(hp_base + 0x1C)?; - values.gameplay.current_hp_smooth = - p.read_f64(hp_base + 0x14)?; - } - - let hit_errors_base = p.read_i32(score_base + 0x38)?; - - p.read_i32_array( - hit_errors_base, - &mut values.gameplay.hit_errors - )?; - - values.gameplay.unstable_rate = - values.gameplay.calculate_unstable_rate(); - - // TODO batch - values.gameplay.mode = p.read_i32(score_base + 0x64)?; - - // TODO batch - values.gameplay.hit_300 = p.read_i16(score_base + 0x8a)?; - values.gameplay.hit_100 = p.read_i16(score_base + 0x88)?; - values.gameplay.hit_50 = p.read_i16(score_base + 0x8c)?; - - values.gameplay.username = p.read_string(score_base + 0x28)?; - - // TODO batch - values.gameplay.hit_geki = p.read_i16(score_base + 0x8e)?; - values.gameplay.hit_katu = p.read_i16(score_base + 0x90)?; - values.gameplay.hit_miss = p.read_i16(score_base + 0x92)?; - - let passed_objects = values.gameplay.passed_objects()?; - - values.gameplay.passed_objects = passed_objects; - - values.gameplay.update_accuracy(); - - values.gameplay.score = p.read_i32(score_base + 0x78)?; - - values.gameplay.combo = p.read_i16(score_base + 0x94)?; - values.gameplay.max_combo = p.read_i16(score_base + 0x68)?; - - if values.gameplay.combo < values.prev_combo - && values.gameplay.hit_miss == values.prev_hit_miss { - values.gameplay.slider_breaks += 1; - } - - values.prev_hit_miss = values.gameplay.hit_miss; - - let mods_xor_base = p.read_i32(score_base + 0x1C)?; - - let mods_raw = p.read_u64(mods_xor_base + 0x8)?; - - let mods_xor1 = mods_raw & 0xFFFFFFFF; - let mods_xor2 = mods_raw >> 32; - - // Read key overlay - process_key_overlay( - p, - values, - ruleset_addr - )?; - - values.gameplay.mods = (mods_xor1 ^ mods_xor2) as u32; - values.update_readable_mods(); - - // Calculate pp - values.update_current_pp(&mut state.ivalues); - values.update_fc_pp(&mut state.ivalues); - - values.prev_passed_objects = passed_objects; - values.prev_combo = values.gameplay.combo; - - values.gameplay.grade = values.gameplay.get_current_grade(); - values.update_current_bpm(); - values.update_kiai(); - - Ok(()) -} - -pub fn process_reading_loop( - p: &Process, - state: &mut State -) -> Result<()> { - let _span = span!("reading loop"); - - let values = state.values.clone(); - let mut values = values.lock().unwrap(); - - let menu_mods_ptr = p.read_i32( - state.addresses.menu_mods + 0x9 - )?; - - let menu_mods = p.read_u32(menu_mods_ptr)?; - values.menu_mods = menu_mods; - - let playtime_ptr = p.read_i32(state.addresses.playtime + 0x5)?; - values.playtime = p.read_i32(playtime_ptr)?; - - let beatmap_ptr = p.read_i32(state.addresses.base - 0xC)?; - let beatmap_addr = p.read_i32(beatmap_ptr)?; - - let status_ptr = p.read_i32(state.addresses.status - 0x4)?; - - let skin_ptr = p.read_i32(state.addresses.skin + 0x4)?; - let skin_data = p.read_i32(skin_ptr)?; - values.skin = p.read_string(skin_data + 0x44)?; - - values.state = GameState::from( - p.read_u32(status_ptr)? - ); - - // Handle leaving `Playing` state - if values.prev_state == GameState::Playing - && values.state != GameState::Playing { - values.reset_gameplay(); - state.ivalues.reset(); - values.update_stars_and_ss_pp(); - } - - if beatmap_addr == 0 { - return Ok(()) - } - - if values.state != GameState::MultiplayerLobby { - let mut beatmap_stats_buff = [0u8; size_of::() * 4]; - - p.read( - beatmap_addr + 0x2c, - size_of::() * 4, - &mut beatmap_stats_buff - )?; - - // Safety: unwrap here because buff is already initialized - // and filled with zeros, the worst case scenario is - // ar, cs, od, hp going to be zero's - values.beatmap.ar = f32::from_le_bytes( - beatmap_stats_buff[0..4].try_into().unwrap() - ); - - values.beatmap.cs = f32::from_le_bytes( - beatmap_stats_buff[4..8].try_into().unwrap() - ); - - values.beatmap.hp = f32::from_le_bytes( - beatmap_stats_buff[8..12].try_into().unwrap() - ); - - values.beatmap.od = f32::from_le_bytes( - beatmap_stats_buff[12..].try_into().unwrap() - ); - - let plays_addr = p.read_i32(state.addresses.base - 0x33)? + 0xC; - values.plays = p.read_i32(plays_addr)?; - - values.beatmap.artist = p.read_string(beatmap_addr + 0x18)?; - values.beatmap.title = p.read_string(beatmap_addr + 0x24)?; - values.beatmap.creator = p.read_string(beatmap_addr + 0x7C)?; - values.beatmap.difficulty = p.read_string(beatmap_addr + 0xAC)?; - values.beatmap.map_id = p.read_i32(beatmap_addr + 0xC8)?; // TODO batch - values.beatmap.mapset_id = p.read_i32(beatmap_addr + 0xCC)?; // TODO batch - } - - values.beatmap.beatmap_status = BeatmapStatus::from( - p.read_i16(beatmap_addr + 0x12C)? - ); - - let mut new_map = false; - - // All time values that available everywhere - values.chat_enabled = p.read_i8( - state.addresses.chat_checker - 0x20 - )? != 0; - - // Skin folder - let skin_data_ptr = p.read_i32( - p.read_i32(state.addresses.skin + 4)? - )?; - - values.skin_folder = p.read_string( - skin_data_ptr + 68 - )?; - - if values.state != GameState::PreSongSelect - && values.state != GameState::MultiplayerLobby - && values.state != GameState::MultiplayerResultScreen { - let menu_mode_addr = p.read_i32(state.addresses.base - 0x33)?; - - let beatmap_file = p.read_string(beatmap_addr + 0x90)?; - let beatmap_folder = p.read_string(beatmap_addr + 0x78)?; - let audio_file = p.read_string(beatmap_addr + 0x64)?; - values.menu_mode = p.read_i32(menu_mode_addr)?; - - values.beatmap.paths.beatmap_full_path - = values.osu_path.join("Songs/"); - - values.beatmap.paths.beatmap_full_path.push(&beatmap_folder); - values.beatmap.paths.beatmap_full_path.push(&beatmap_file); - - values.beatmap.md5 = - p.read_string(beatmap_addr + 0x6C)?; - - // Check if beatmap changed - if (beatmap_folder != values.beatmap.paths.beatmap_folder - || beatmap_file != values.beatmap.paths.beatmap_file - || values.prev_menu_mode != values.menu_mode) - && values.beatmap.paths.beatmap_full_path.exists() { - let current_beatmap = match Beatmap::from_path( - &values.beatmap.paths.beatmap_full_path - ) { - Ok(beatmap) => { - new_map = true; - - values.beatmap.paths.background_file.clone_from( - &beatmap.background.filename - ); - - if let Some(hobj) = beatmap.hit_objects.last() { - values.beatmap.last_obj_time = hobj.start_time; - } - - if let Some(hobj) = beatmap.hit_objects.first() { - values.beatmap.first_obj_time = hobj.start_time; - } - - values.beatmap.bpm = beatmap.bpm(); - - Some(beatmap) - }, - Err(_) => { - println!("Failed to parse beatmap"); - None - }, - }; - - values.current_beatmap = current_beatmap; - - values.beatmap.paths.beatmap_folder = beatmap_folder; - values.beatmap.paths.beatmap_file = beatmap_file; - values.beatmap.paths.audio_file = audio_file; - - values.update_min_max_bpm(); - values.update_full_paths(); - values.adjust_bpm(); - } - } - - // store the converted map so it's not converted - // everytime it's used for pp calc - if new_map { - if let Some(map) = &values.current_beatmap { - if let Cow::Owned(converted) = map - .convert_mode(values.menu_gamemode()) - { - values.current_beatmap = Some(converted); - } - } - - values.update_stars_and_ss_pp(); - values.update_current_pp(&mut state.ivalues); - } - - let ruleset_addr = p.read_i32( - p.read_i32(state.addresses.rulesets - 0xb)? + 0x4 - )?; - - let audio_time_ptr = p.read_i32(state.addresses.audio_time_base + 0x9)?; - values.precise_audio_time = p.read_i32(audio_time_ptr)?; - - // If this happened there is zero sense to continue - // reading because all the values depends on this - // address - if ruleset_addr == 0 { - return Ok(()) - } - - // Process result screen - // TODO handle situations when result screen is not ready - if values.state == GameState::ResultScreen { - let result_base = p.read_i32(ruleset_addr+ 0x38)?; - - values.result_screen.username = p.read_string(result_base + 0x28)?; - - let mods_xor_base = p.read_i32(result_base + 0x1C)?; - - // TODO batch - let mods_xor1 = p.read_i32(mods_xor_base + 0xC)?; - let mods_xor2 = p.read_i32(mods_xor_base + 0x8)?; - - values.result_screen.mods = (mods_xor1 ^ mods_xor2) as u32; - values.result_screen.mode = p.read_i32(result_base + 0x64)? as u8; - values.result_screen.score = p.read_i32(result_base + 0x78)?; - - // TODO batch - values.result_screen.hit_300 = p.read_i16(result_base + 0x8A)?; - values.result_screen.hit_100 = p.read_i16(result_base + 0x88)?; - values.result_screen.hit_50 = p.read_i16(result_base + 0x8C)?; - values.result_screen.hit_geki = p.read_i16(result_base + 0x8E)?; - values.result_screen.hit_katu = p.read_i16(result_base + 0x90)?; - - values.result_screen.update_accuracy(); - } - - // Process gameplay - if values.state == GameState::Playing { - let res = process_gameplay( - p, - state, - &mut values, - ruleset_addr - ); - - if let Err(e) = res { - println!("{:?}", e); - println!("Skipped gameplay reading, probably it's not ready yet"); - } - } - - // Handling entering `ResultScreen` state - if values.prev_state != GameState::ResultScreen - && values.state == GameState::ResultScreen { - if values.prev_state != GameState::Playing { - values.update_current_pp(&mut state.ivalues); - } - - values.update_stars_and_ss_pp(); - } - - // Handling entering `SongSelect` state - if values.prev_state != GameState::SongSelect - && values.state == GameState::SongSelect { - // Reseting pp's from result screen - if values.prev_state == GameState::ResultScreen { - values.current_pp = 0.0; - } - - values.update_current_pp(&mut state.ivalues); - values.update_stars_and_ss_pp(); - values.adjust_bpm(); - } - - // Update stars when entering `Playing` state - if values.prev_state != GameState::Playing - && values.state == GameState::Playing { - values.reset_gameplay(); - values.update_stars_and_ss_pp(); - values.adjust_bpm(); - } - - // Handle mods changes inside `SongSelect` state - if values.state == GameState::SongSelect - && values.prev_menu_mods != values.menu_mods { - values.update_stars_and_ss_pp(); - values.update_current_pp(&mut state.ivalues); - values.adjust_bpm(); - } - - values.prev_menu_mode = values.menu_mode; - values.prev_menu_mods = menu_mods; - values.prev_state = values.state; - - Ok(()) -} \ No newline at end of file diff --git a/src-tauri/src/structs.rs b/src-tauri/src/structs.rs deleted file mode 100644 index 150037d..0000000 --- a/src-tauri/src/structs.rs +++ /dev/null @@ -1,1065 +0,0 @@ -use std::{ - num::TryFromIntError, - path::PathBuf, - str::FromStr, - sync::{Arc, Mutex} -}; - -use rosu_mem::{ - process::{Process, ProcessTraits}, - signature::Signature -}; - -use rosu_pp::{Beatmap, BeatmapExt, GameMode, - PerformanceAttributes, GradualPerformance, - beatmap::EffectPoint, ScoreState, AnyPP -}; -use eyre::Result; -use serde::Serialize; -use serde_repr::Serialize_repr; - -pub type Arm = Arc>; - -macro_rules! calculate_accuracy { - ($self: expr) => {{ - match $self.gamemode() { - GameMode::Osu => - ($self.hit_300 as f64 * 6. - + $self.hit_100 as f64 * 2. - + $self.hit_50 as f64) - / - (($self.hit_300 - + $self.hit_100 - + $self.hit_50 - + $self.hit_miss) as f64 * 6. - ), - GameMode::Taiko => - ($self.hit_300 as f64 * 2. + $self.hit_100 as f64) - / - (($self.hit_300 - + $self.hit_100 - + $self.hit_50 - + $self.hit_miss) as f64 * 2.), - GameMode::Catch => - ($self.hit_300 + $self.hit_100 + $self.hit_50) as f64 - / - ($self.hit_300 + $self.hit_100 + $self.hit_50 - + $self.hit_katu + $self.hit_miss) as f64, - GameMode::Mania => - (($self.hit_geki + $self.hit_300) as f64 - * 6. + $self.hit_katu as f64 - * 4. + $self.hit_100 as f64 - * 2. + $self.hit_50 as f64) - / - (($self.hit_geki - + $self.hit_300 - + $self.hit_katu - + $self.hit_100 - + $self.hit_50 - + $self.hit_miss) as f64 * 6. - ) - } - }} -} - -//TODO use bitflags & enum & bitflags iterator for converting to string? -const MODS: [(u32, &str); 31] = [ - (1 << 0, "NF"), - (1 << 1, "EZ"), - (1 << 2, "TD"), - (1 << 3, "HD"), - (1 << 4, "HR"), - (1 << 5, "SD"), - (1 << 6, "DT"), - (1 << 7, "RX"), - (1 << 8, "HT"), - (1 << 9, "NC"), - (1 << 10, "FL"), - (1 << 11, "AU"), - (1 << 12, "SO"), - (1 << 13, "AP"), - (1 << 14, "PF"), - (1 << 15, "K4"), - (1 << 16, "K5"), - (1 << 17, "K6"), - (1 << 18, "K7"), - (1 << 19, "K8"), - (1 << 20, "FI"), - (1 << 21, "RN"), - (1 << 22, "CN"), - (1 << 23, "TP"), - (1 << 24, "K9"), - (1 << 25, "Coop"), - (1 << 26, "K1"), - (1 << 27, "K3"), - (1 << 28, "K2"), - (1 << 29, "V2"), - (1 << 30, "MR"), -]; - -#[derive(Serialize_repr, Debug, Default, PartialEq, Eq, Clone, Copy)] -#[repr(u32)] -pub enum GameState { - PreSongSelect = 0, - Playing = 2, - SongSelect = 5, - EditorSongSelect = 4, - ResultScreen = 7, - MultiplayerLobbySelect = 11, - MultiplayerLobby = 12, - MultiplayerResultScreen = 14, - - #[default] - Unknown, -} - -impl From for GameState { - fn from(value: u32) -> Self { - match value { - 0 => Self::PreSongSelect, - 2 => Self::Playing, - 4 => Self::EditorSongSelect, - 5 => Self::SongSelect, - 7 => Self::ResultScreen, - 11 => Self::MultiplayerLobbySelect, - 12 => Self::MultiplayerLobby, - 14 => Self::MultiplayerResultScreen, - _ => Self::Unknown, - } - } -} - -#[derive(Serialize_repr, Debug, Default, PartialEq, Eq, Copy, Clone)] -#[repr(i16)] -pub enum BeatmapStatus { - #[default] - Unknown = 0, - Unsubmitted = 1, - Unranked = 2, - Unused = 3, - Ranked = 4, - Approved = 5, - Qualified = 6, - Loved = 7, -} - -impl From for BeatmapStatus { - fn from(value: i16) -> Self { - match value { - 1 => Self::Unsubmitted, - 2 => Self::Unranked, - 3 => Self::Unused, - 4 => Self::Ranked, - 5 => Self::Approved, - 6 => Self::Qualified, - 7 => Self::Loved, - _ => Self::Unknown, - } - } -} - -#[derive(Default)] -pub struct StaticAddresses { - pub base: i32, - pub status: i32, - pub menu_mods: i32, - pub rulesets: i32, - pub playtime: i32, - pub skin: i32, - pub chat_checker: i32, - pub audio_time_base: i32, -} - -impl StaticAddresses { - pub fn new(p: &Process) -> Result { - let _span = tracy_client::span!("static addresses"); - - let base_sign = Signature::from_str("F8 01 74 04 83 65")?; - let status_sign = Signature::from_str("48 83 F8 04 73 1E")?; - let menu_mods_sign = Signature::from_str( - "C8 FF ?? ?? ?? ?? ?? 81 0D ?? ?? ?? ?? 00 08 00 00" - )?; - - let rulesets_sign = Signature::from_str( - "7D 15 A1 ?? ?? ?? ?? 85 C0" - )?; - - let playtime_sign = Signature::from_str( - "5E 5F 5D C3 A1 ?? ?? ?? ?? 89 ?? 04" - )?; - - let skin_sign = Signature::from_str("75 21 8B 1D")?; - - let chat_checker = Signature::from_str("0A D7 23 3C 00 00 ?? 01")?; - - let audio_time_base = Signature::from_str("DB 5C 24 34 8B 44 24 34")?; - - Ok(Self { - base: p.read_signature(&base_sign)?, - status: p.read_signature(&status_sign)?, - menu_mods: p.read_signature(&menu_mods_sign)?, - rulesets: p.read_signature(&rulesets_sign)?, - playtime: p.read_signature(&playtime_sign)?, - skin: p.read_signature(&skin_sign)?, - chat_checker: p.read_signature(&chat_checker)?, - audio_time_base: p.read_signature(&audio_time_base)?, - }) - } -} - - -pub struct State { - pub addresses: StaticAddresses, - pub values: Arm, - pub ivalues: InnerValues, -} - -// Inner values that used only inside -// reading loop and shouldn't be -// shared between any threads -#[derive(Default)] -pub struct InnerValues { - pub gradual_performance_current: - Option>, - - pub current_beatmap_perf: Option, -} - -impl InnerValues { - pub fn reset(&mut self) { - self.current_beatmap_perf = None; - self.gradual_performance_current = None; - } -} - -#[derive(Debug, Default, Serialize)] -pub struct KeyOverlayValues { - pub k1_pressed: bool, - pub k1_count: u32, - pub k2_pressed: bool, - pub k2_count: u32, - pub m1_pressed: bool, - pub m1_count: u32, - pub m2_pressed: bool, - pub m2_count: u32, -} - -impl KeyOverlayValues { - pub fn reset(&mut self) { - self.k1_pressed = false; - self.k1_count = 0; - self.k2_pressed = false; - self.k2_count = 0; - self.m1_pressed = false; - self.m1_count = 0; - self.m2_pressed = false; - self.m2_count = 0; - } -} - -#[derive(Debug, Default, Serialize)] -pub struct ResultScreenValues { - pub username: String, - pub mods: u32, - pub mode: u8, - pub max_combo: i16, - pub score: i32, - pub hit_300: i16, - pub hit_100: i16, - pub hit_50: i16, - pub hit_geki: i16, - pub hit_katu: i16, - pub hit_miss: i16, - pub accuracy: f64, -} - -impl ResultScreenValues { - pub fn gamemode(&self) -> GameMode { - GameMode::from(self.mode) - } - - pub fn update_accuracy(&mut self) { - let _span = tracy_client::span!("result_screen: calculate accuracy"); - - self.accuracy = calculate_accuracy!(self); - } -} - -#[derive(Debug, Default, Serialize)] -pub struct BeatmapPathValues { - /// Absolute beatmap file path - /// Example: `/path/to/osu/Songs/124321 Artist - Title/my_map.osu` - pub beatmap_full_path: PathBuf, - - /// Relative to osu! folder beatmap folder path - /// Example: `124321 Artist - Title` - pub beatmap_folder: String, - - /// Relative to beatmap folder background file path - /// Example: `my_map.osu` - pub beatmap_file: String, - - /// Relative to beatmap folder background file path - /// Example: `background.jpg` - pub background_file: String, - - /// Absolute background file path - /// Example: `/path/to/osu/Songs/beatmap/background.jpg` - pub background_path_full: PathBuf, - - /// Relative to beatmap folder audio file path - /// Example: `` - pub audio_file: String, -} - -#[derive(Debug, Default, Serialize)] -pub struct BeatmapValues { - pub artist: String, - pub title: String, - pub creator: String, - pub difficulty: String, - - /// ID of particular difficulty inside mapset - pub map_id: i32, - - /// ID of whole mapset - pub mapset_id: i32, - - /// MD5 hash of the beatmap - pub md5: String, - - pub ar: f32, - pub cs: f32, - pub hp: f32, - pub od: f32, - - /// Beatmap Status aka Ranked, Pending, Loved, etc - pub beatmap_status: BeatmapStatus, - - /// Time in milliseconds of last object of beatmap - pub last_obj_time: f64, - - /// Time in milliseconds of first object of beatmap - pub first_obj_time: f64, - - /// BPM of currently selected beatmap - pub bpm: f64, - - /// Max BPM of currently selected beatmap - pub max_bpm: f64, - - /// Min BPM of currently selected beatmap - pub min_bpm: f64, - - /// Paths of files used by beatmap - /// .osu file, background file, etc - pub paths: BeatmapPathValues, -} - -#[derive(Debug, Default, Serialize)] -pub struct GameplayValues { - #[serde(skip)] - pub hit_errors: Vec, - - pub mods: u32, - - pub username: String, - pub score: i32, - pub hit_300: i16, - pub hit_100: i16, - pub hit_50: i16, - pub hit_geki: i16, - pub hit_katu: i16, - pub hit_miss: i16, - pub accuracy: f64, - pub combo: i16, - pub max_combo: i16, - pub mode: i32, - pub slider_breaks: i16, - pub unstable_rate: f64, - - pub passed_objects: usize, - - #[serde(default = "SS")] - pub grade: &'static str, - pub current_hp: f64, - pub current_hp_smooth: f64, -} - -impl GameplayValues { - #[inline] - pub fn gamemode(&self) -> GameMode { - let _span = tracy_client::span!("gamplay gamemode"); - GameMode::from(self.mode as u8) - } - - pub fn passed_objects(&self) -> Result { - let _span = tracy_client::span!("passed objects"); - - let value = match self.gamemode() { - GameMode::Osu => - self.hit_300 + self.hit_100 - + self.hit_50 + self.hit_miss, - GameMode::Taiko => - self.hit_300 + self.hit_100 + self.hit_miss, - GameMode::Catch => - self.hit_300 + self.hit_100 - + self.hit_50 + self.hit_miss - + self.hit_katu, - GameMode::Mania => - self.hit_300 + self.hit_100 - + self.hit_50 + self.hit_miss - + self.hit_katu + self.hit_geki, - }; - - usize::try_from(value) - } - - - pub fn get_current_grade(&self) -> &'static str { - let _span = tracy_client::span!("calculate current grade"); - let total_hits = self.passed_objects as f64; - let base_grade = match self.gamemode() { - GameMode::Osu => { - let ratio300 = self.hit_300 as f64 / total_hits; - let ratio50 = self.hit_50 as f64 / total_hits; - if self.accuracy == 1. { - "SS" - } else if ratio300 > 0.9 - && self.hit_miss == 0 - && ratio50 <= 0.1 { - "S" - } else if ratio300 > 0.8 - && self.hit_miss == 0 || ratio300 > 0.9 { - "A" - } else if ratio300 > 0.7 - && self.hit_miss == 0 - || ratio300 > 0.8 { - "B" - } else if ratio300 > 0.6 { - "C" - } else { - "D" - } - }, - GameMode::Taiko => { - let ratio300 = self.hit_300 as f64 / total_hits; - if self.accuracy == 1. { - "SS" - } else if ratio300 > 0.9 && self.hit_miss == 0 { - "S" - } else if ratio300 > 0.8 - && self.hit_miss == 0 - || ratio300 > 0.9 { - "A" - } else if ratio300 > 0.7 - && self.hit_miss == 0 - || ratio300 > 0.8 { - "B" - } else if ratio300 > 0.6 { - "C" - } else { - "D" - } - }, - GameMode::Catch => { - if self.accuracy == 1. { - "SS" - } else if self.accuracy > 0.98 { - "S" - } else if self.accuracy > 0.94 { - "A" - } else if self.accuracy > 0.90 { - "B" - } else if self.accuracy > 0.85 { - "C" - } else { - "D" - } - }, - GameMode::Mania => { - if self.accuracy == 1. { - "SS" - } else if self.accuracy > 0.95 { - "S" - } else if self.accuracy > 0.9 { - "A" - } else if self.accuracy > 0.8 { - "B" - } else if self.accuracy > 0.7 { - "C" - } else { - "D" - } - } - }; - - // Hidden | Flashlight | Fade In - match (base_grade, self.mods & (8 | 1024 | 1048576)) { - ("SS", conj) if conj > 0 => "SSH", - ("S", conj) if conj > 0 => "SH", - _ => base_grade - } - } - - pub fn update_accuracy(&mut self) { - let _span = tracy_client::span!("calculate accuracy"); - - let acc: f64 = 'blk: { - if self.passed_objects == 0 { - break 'blk 1.; - } - - calculate_accuracy!(self) - }; - - self.accuracy = acc; - } - - pub fn calculate_unstable_rate(&self) -> f64 { - let _span = tracy_client::span!("calculate ur"); - - if self.hit_errors.is_empty() { - return 0.0 - }; - - let hit_errors_len = self.hit_errors.len() as i32; - - let total: &i32 = &self.hit_errors.iter().sum(); - let average = total / hit_errors_len; - - let mut variance = 0; - for hit in &self.hit_errors { - variance += i32::pow(*hit - average, 2) - } - - variance /= hit_errors_len; - - f64::sqrt(variance as f64) * 10.0 - } -} - -#[derive(Debug, Default, Serialize)] -pub struct OutputValues { - /// Absolute path to the osu! folder - /// Example: `/path/to/osu` - /// Used internally - #[serde(skip)] - pub osu_path: PathBuf, - - #[serde(skip)] - pub current_beatmap: Option, - - #[serde(skip)] - pub prev_combo: i16, - #[serde(skip)] - pub prev_hit_miss: i16, - #[serde(skip)] - pub prev_playtime: i32, - #[serde(skip)] - pub prev_passed_objects: usize, - #[serde(skip)] - pub prev_state: GameState, - #[serde(skip)] - pub prev_menu_mods: u32, - #[serde(skip)] - pub prev_menu_mode: i32, - #[serde(skip)] - pub delta_sum: usize, - - /// Name of the current skin - pub skin: String, - - /// Skin folder relative to the osu! folder - pub skin_folder: String, - - /// Is chat enabled (F9/F8) - pub chat_enabled: bool, - - /// Playtime in milliseconds - /// `Playing` => represents your progress into current beatmap - /// `SongSelect` => represents progress of mp3 - /// Note: can be negative - pub playtime: i32, - - /// Current gamemode on `SongSelect` state - pub menu_mode: i32, - - /// Current state of the game - pub state: GameState, - - /// Stars of current beatmap without any mods - pub stars: f64, - - /// Stars of current beatmap taking in account state and mods - /// `Playing` => using gameplay mods - /// `SongSelect` => using menu_mods - /// `ResultScreen` => using result_screen mods - pub stars_mods: f64, - - /// Stars calculated during gameplay and based on - /// current gameplay mods and passed objects - /// calculated gradually - pub current_stars: f64, - - /// Result Screen info - pub result_screen: ResultScreenValues, - - /// Gameplay info - pub gameplay: GameplayValues, - - /// Beatmap info - pub beatmap: BeatmapValues, - - // KeyOverlay infi - pub keyoverlay: KeyOverlayValues, - - /// BPM calculated during gameplay - /// based on your progress into the beatmap and gameplay mods - pub current_bpm: f64, - - /// Is kiai is active now - /// based on your progress into the beatmap - pub kiai_now: bool, - - /// Current PP based on your state - /// - /// `Playing` => based on your progress into the beatmap - /// and gameplay mods - /// `SongSelect` => ss_pp for current map using menu_mods - /// `ResultScreen` => pp calculated for score on the screen - /// (values are taken from result_screen) - pub current_pp: f64, - - /// Fullcombo PP during gameplay - /// based on your progress into the beatmap and gameplay mods - /// basically just removes misses - pub fc_pp: f64, - - /// SS PP's - /// based on your progress into the beatmap and mods - /// `Playing` => using gameplay mods - /// `SongSelect` => using menu_mods - /// `ResultScreen` => using result_screen mods - pub ss_pp: f64, - - /// Mods on `SongSelect` state - pub menu_mods: u32, - - /// String representation of current selected mods - /// `Playing` => using gameplay mods - /// `SongSelect` => using menu_mods - /// `ResultScreen` => using result_screen mods - pub mods_str: Vec<&'static str>, - - pub plays: i32, - - /// Position of current playing audio in milliseconds - /// (to be honest it have nothing to do with precision) - pub precise_audio_time: i32, -} - -impl OutputValues { - // Reseting values should happen from `OutputValues` functions - // Separating it in individual functions gonna decrease readability - // a lot - pub fn reset_gameplay(&mut self) { - let _span = tracy_client::span!("reset gameplay!"); - - self.keyoverlay.reset(); - - self.prev_combo = 0; - self.prev_hit_miss = 0; - self.prev_playtime = 0; - - self.mods_str.clear(); - - self.current_pp = 0.0; - self.fc_pp = 0.0; - self.ss_pp = 0.0; - - self.current_bpm = 0.0; - self.prev_passed_objects = 0; - self.delta_sum = 0; - self.kiai_now = false; - - self.gameplay.slider_breaks = 0; - self.gameplay.score = 0; - self.gameplay.hit_300 = 0; - self.gameplay.hit_100 = 0; - self.gameplay.hit_50 = 0; - self.gameplay.hit_geki = 0; - self.gameplay.passed_objects = 0; - self.gameplay.hit_katu = 0; - self.gameplay.hit_miss = 0; - self.gameplay.combo = 0; - self.gameplay.max_combo = 0; - self.gameplay.mode = 0; - self.gameplay.slider_breaks = 0; - self.gameplay.current_hp = 0.0; - self.gameplay.current_hp_smooth = 0.0; - - self.gameplay.unstable_rate = 0.0; - } - - #[inline] - pub fn menu_gamemode(&self) -> GameMode { - let _span = tracy_client::span!("menu gamemody"); - GameMode::from(self.menu_mode as u8) - } - - pub fn update_min_max_bpm(&mut self) { - if let Some(beatmap) = &self.current_beatmap { - // Maybe this is not very idiomatic approach - // but atleast we dont need to iterate twice - // to calculate min and max values - let mut max_bpm = f64::MIN; - let mut min_bpm = f64::MAX; - - for timing_point in beatmap.timing_points.iter() { - let bpm = 60000.0 / timing_point.beat_len; - - if bpm > max_bpm { max_bpm = bpm }; - if bpm < min_bpm { min_bpm = bpm }; - } - - self.beatmap.max_bpm = max_bpm; - self.beatmap.min_bpm = min_bpm; - } - - } - - pub fn update_current_bpm(&mut self) { - let _span = tracy_client::span!("get current bpm"); - - let bpm = if let Some(beatmap) = &self.current_beatmap { - 60000.0 / beatmap - .timing_point_at(self.playtime as f64) - .beat_len - } else { - self.current_bpm - }; - - self.current_bpm = bpm; - } - - pub fn update_kiai(&mut self) { - let _span = tracy_client::span!("get_kiai"); - - self.kiai_now = if let Some(beatmap) = &self.current_beatmap { - // TODO: get rid of extra allocation? - let kiai_data: Option = beatmap - .effect_point_at(self.playtime as f64); - if let Some(kiai) = kiai_data { - kiai.kiai - } else { - self.kiai_now - } - } else { - self.kiai_now - } - } - - /// Depends on `GameplayValues` and `ResultScreenValues` - pub fn update_current_pp(&mut self, ivalues: &mut InnerValues) { - // TODO refactor this function in near future - // maybe even split pp into struct aka `GameplayValues` -> pp - // etc - let _span = tracy_client::span!("get_current_pp"); - - if self.state == GameState::ResultScreen { - if let Some(beatmap) = &self.current_beatmap { - let attr = beatmap - .pp() - .mode(self.result_screen.gamemode()) - .mods(self.result_screen.mods) - .n300(self.result_screen.hit_300 as usize) - .n100(self.result_screen.hit_100 as usize) - .n50(self.result_screen.hit_50 as usize) - .n_geki(self.result_screen.hit_geki as usize) - .n_katu(self.result_screen.hit_katu as usize) - .n_misses(self.result_screen.hit_miss as usize) - .calculate(); - - self.current_pp = attr.pp(); - } - - return; - } - - // TODO yep it definitely should be refactored - if self.state == GameState::SongSelect { - self.current_pp = self.ss_pp; - } - - if let Some(beatmap) = &self.current_beatmap { - let score_state = ScoreState { - max_combo: self.gameplay.max_combo as usize, - n_geki: self.gameplay.hit_geki as usize, - n_katu: self.gameplay.hit_katu as usize, - n300: self.gameplay.hit_300 as usize, - n100: self.gameplay.hit_100 as usize, - n50: self.gameplay.hit_50 as usize, - n_misses: self.gameplay.hit_miss as usize, - }; - - let passed_objects = self.gameplay.passed_objects; - let prev_passed_objects = self.prev_passed_objects; - let delta = passed_objects - prev_passed_objects; - - let gradual = ivalues - .gradual_performance_current - .get_or_insert_with(|| { - // TODO: required until we rework the struct - let static_beatmap = unsafe { - extend_lifetime(beatmap) - }; - GradualPerformance::new( - static_beatmap, - self.gameplay.mods - ) - }); - - // delta can't be 0 as processing 0 actually processes 1 object - if (delta > 0) && (self.delta_sum <= prev_passed_objects) { - self.delta_sum += delta; - let attributes_option = gradual.nth(score_state, delta - 1); - match attributes_option { - Some(attributes) => { - self.current_pp = attributes.pp(); - self.current_stars = attributes.stars(); - } - None => { println!("Failed to calculate current pp/sr") } - } - - } - } - } - - /// Depends on `GameplayValues` - pub fn update_fc_pp(&mut self, ivalues: &mut InnerValues) { - let _span = tracy_client::span!("get_fc_pp"); - if let Some(beatmap) = &self.current_beatmap { - if ivalues.current_beatmap_perf.is_some() { - if let Some(attributes) = - ivalues.current_beatmap_perf.clone() { - let fc_pp = AnyPP::new(beatmap) - .attributes(attributes.clone()) - .mode(self.gameplay.gamemode()) - .mods(self.gameplay.mods) - .n300(self.gameplay.hit_300 as usize) - .n100(self.gameplay.hit_100 as usize) - .n50(self.gameplay.hit_50 as usize) - .n_geki(self.gameplay.hit_geki as usize) - .n_katu(self.gameplay.hit_katu as usize) - .n_misses(0) - .calculate(); - self.fc_pp = fc_pp.pp(); - } - else { - self.fc_pp = 0.0 - } - } else { - let attr = AnyPP::new(beatmap) - .mods(self.gameplay.mods) - .mode(self.gameplay.gamemode()) - .calculate(); - - let ss_pp = attr.pp(); - self.ss_pp = ss_pp; - - ivalues.current_beatmap_perf = Some(attr); - - self.fc_pp = ss_pp; - } - } else { - self.fc_pp = 0.0 - } - } - - /// Adjust bpm based on current state and mods - /// `Playing` => using gameplay mods - /// `SongSelect` => using menu_mods - /// - /// Depends on `GameplayValues` - pub fn adjust_bpm(&mut self) { - let _span = tracy_client::span!("adjust bpm"); - match self.state { - GameState::Playing => { - if self.gameplay.mods & 64 > 0 { - self.gameplay.unstable_rate /= 1.5; - self.current_bpm *= 1.5; - self.beatmap.bpm *= 1.5; - self.beatmap.max_bpm *= 1.5; - self.beatmap.min_bpm *= 1.5; - } - else if self.gameplay.mods & 256 > 0 { - self.gameplay.unstable_rate *= 0.75; - self.current_bpm *= 0.75; - self.beatmap.bpm *= 0.75; - self.beatmap.max_bpm *= 0.75; - self.beatmap.min_bpm *= 0.75; - } else { - self.update_min_max_bpm(); - - if let Some(beatmap) = &self.current_beatmap { - self.beatmap.bpm = beatmap.bpm(); - } - } - }, - GameState::SongSelect => { - if self.menu_mods & 64 > 0 { - self.beatmap.bpm *= 1.5; - self.beatmap.max_bpm *= 1.5; - self.beatmap.min_bpm *= 1.5; - } - else if self.menu_mods & 256 > 0 { - self.beatmap.bpm *= 0.75; - self.beatmap.max_bpm *= 0.75; - self.beatmap.min_bpm *= 0.75; - } else { - self.update_min_max_bpm(); - - if let Some(beatmap) = &self.current_beatmap { - self.beatmap.bpm = beatmap.bpm(); - } - } - }, - _ => () - } - } - - /// Returns mods depending on current game state - pub fn get_current_mods(&self) -> u32 { - match self.state { - GameState::Playing => self.gameplay.mods, - GameState::SongSelect => self.menu_mods, - GameState::ResultScreen => self.result_screen.mods, - _ => self.menu_mods - } - } - - pub fn update_stars_and_ss_pp(&mut self) { - let _span = tracy_client::span!("update stars and ss_pp"); - - if let Some(beatmap) = &self.current_beatmap { - let mods = { - match self.state { - GameState::Playing => self.gameplay.mods, - GameState::SongSelect => self.menu_mods, - GameState::ResultScreen => self.result_screen.mods, - _ => self.menu_mods - } - }; - - let mode = { - match self.state { - GameState::Playing => self.gameplay.gamemode(), - GameState::SongSelect => self.menu_gamemode(), - GameState::ResultScreen => self.result_screen.gamemode(), - _ => self.menu_gamemode() - } - }; - - self.stars = beatmap - .stars() - .mode(mode) // Catch convertions is - .calculate() // broken so converting - .stars(); // manually, read #57 & #55 - - let attr = beatmap - .pp() - .mode(mode) // ^ - .mods(mods) - .calculate(); - - self.stars_mods = attr.stars(); - self.ss_pp = attr.pp(); - } - } - - pub fn update_readable_mods(&mut self) { - let _span = tracy_client::span!("get_readable_mods"); - - let mods_values = match self.state { - GameState::Playing => self.gameplay.mods, - GameState::SongSelect => self.menu_mods, - GameState::ResultScreen=> self.result_screen.mods, - _ => self.menu_mods, - }; - - self.mods_str.clear(); - - MODS.iter() - .for_each(|(idx, name)| { - if let Some(m) = (mods_values & idx > 0).then_some(*name) { - self.mods_str.push(m); - } - }); - - if self.mods_str.contains(&"NC") { - self.mods_str.retain(|x| x != &"DT"); - } - - if self.mods_str.contains(&"PF") { - self.mods_str.retain(|x| x != &"SD"); - } - } - - /// Depends on `BeatmapValues` and `BeatmapPathValues` - pub fn update_full_paths(&mut self) { - let _span = tracy_client::span!("update_full_paths"); - - // beatmap_full_path is expection because - // it depends on previous state - - self.beatmap.paths.background_path_full - = self.osu_path.join("Songs/"); - - self.beatmap.paths.background_path_full - .push(&self.beatmap.paths.beatmap_folder); - - self.beatmap.paths.background_path_full - .push(&self.beatmap.paths.background_file); - } -} - -unsafe fn extend_lifetime(value: &T) -> &'static T { - std::mem::transmute(value) -} - -#[cfg(test)] -mod test { - use super::*; - #[test] - fn test_mod_conversion() { - let mut values = OutputValues { - state: GameState::Playing, - gameplay: GameplayValues { - mods: 88, - ..Default::default() - }, - ..Default::default() - }; - - values.update_readable_mods(); - assert_eq!( - vec!["HD", "HR", "DT"], - values.mods_str - ); - - values.gameplay.mods = 584; - values.update_readable_mods(); - assert_eq!( - vec!["HD", "NC"], - values.mods_str - ); - - values.gameplay.mods = 1107561552; - values.update_readable_mods(); - assert_eq!( - vec!["HR","DT","FL","AU","K7","Coop","MR"], - values.mods_str - ); - } -} \ No newline at end of file diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index c4df109..5ec2963 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -13,8 +13,8 @@ "windows": [ { "title": "ezpplauncher", - "width": 550, - "height": 350, + "width": 1000, + "height": 700, "decorations": false, "resizable": false, "maximizable": false diff --git a/src/app.html b/src/app.html index eea7922..6313582 100644 --- a/src/app.html +++ b/src/app.html @@ -8,7 +8,7 @@ %sveltekit.head% - +
%sveltekit.body%
diff --git a/src/lib/api/ezpp.ts b/src/lib/api/ezpp.ts new file mode 100644 index 0000000..630332e --- /dev/null +++ b/src/lib/api/ezpp.ts @@ -0,0 +1,17 @@ +import ky from 'ky'; + +const BANCHO_ENDPOINT = 'https://c.ez-pp.farm/'; + +export const ezppfarm = { + ping: async (): Promise => { + try { + const start = Date.now(); + const request = await ky(BANCHO_ENDPOINT); + if (!request.ok) return undefined; + const ping = Date.now() - start; + return ping; + } catch { + return undefined; + } + }, +}; diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte new file mode 100644 index 0000000..95ccd3b --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte @@ -0,0 +1,13 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte new file mode 100644 index 0000000..7015a89 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte new file mode 100644 index 0000000..858b8bc --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte @@ -0,0 +1,26 @@ + + + + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte new file mode 100644 index 0000000..3e136da --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte new file mode 100644 index 0000000..91ecaba --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte new file mode 100644 index 0000000..44a7b08 --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte new file mode 100644 index 0000000..bb76e7a --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte b/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte new file mode 100644 index 0000000..c7811db --- /dev/null +++ b/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte @@ -0,0 +1,18 @@ + + + diff --git a/src/lib/components/ui/alert-dialog/index.ts b/src/lib/components/ui/alert-dialog/index.ts new file mode 100644 index 0000000..d06201d --- /dev/null +++ b/src/lib/components/ui/alert-dialog/index.ts @@ -0,0 +1,39 @@ +import { AlertDialog as AlertDialogPrimitive } from "bits-ui"; +import Title from "./alert-dialog-title.svelte"; +import Action from "./alert-dialog-action.svelte"; +import Cancel from "./alert-dialog-cancel.svelte"; +import Footer from "./alert-dialog-footer.svelte"; +import Header from "./alert-dialog-header.svelte"; +import Overlay from "./alert-dialog-overlay.svelte"; +import Content from "./alert-dialog-content.svelte"; +import Description from "./alert-dialog-description.svelte"; + +const Root = AlertDialogPrimitive.Root; +const Trigger = AlertDialogPrimitive.Trigger; +const Portal = AlertDialogPrimitive.Portal; + +export { + Root, + Title, + Action, + Cancel, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + // + Root as AlertDialog, + Title as AlertDialogTitle, + Action as AlertDialogAction, + Cancel as AlertDialogCancel, + Portal as AlertDialogPortal, + Footer as AlertDialogFooter, + Header as AlertDialogHeader, + Trigger as AlertDialogTrigger, + Overlay as AlertDialogOverlay, + Content as AlertDialogContent, + Description as AlertDialogDescription, +}; diff --git a/src/lib/components/ui/background/background.svelte b/src/lib/components/ui/background/background.svelte index a907f49..8875c44 100644 --- a/src/lib/components/ui/background/background.svelte +++ b/src/lib/components/ui/background/background.svelte @@ -8,5 +8,5 @@
--> + > diff --git a/src/lib/components/ui/logo/logo.svelte b/src/lib/components/ui/logo/logo.svelte index 3854ec6..e68dc07 100644 --- a/src/lib/components/ui/logo/logo.svelte +++ b/src/lib/components/ui/logo/logo.svelte @@ -131,10 +131,10 @@ @keyframes beat { 0%, 100% { - scale: 1.08; + scale: 1; } 90% { - scale: 1; + scale: 1.08; } } @keyframes beat-pulse { diff --git a/src/lib/components/ui/progress/index.ts b/src/lib/components/ui/progress/index.ts new file mode 100644 index 0000000..25eee61 --- /dev/null +++ b/src/lib/components/ui/progress/index.ts @@ -0,0 +1,7 @@ +import Root from "./progress.svelte"; + +export { + Root, + // + Root as Progress, +}; diff --git a/src/lib/components/ui/progress/progress.svelte b/src/lib/components/ui/progress/progress.svelte new file mode 100644 index 0000000..d543d82 --- /dev/null +++ b/src/lib/components/ui/progress/progress.svelte @@ -0,0 +1,44 @@ + + + +
+
+ + diff --git a/src/lib/components/ui/progressbar/progressbar.svelte b/src/lib/components/ui/progressbar/progressbar.svelte deleted file mode 100644 index 0b06413..0000000 --- a/src/lib/components/ui/progressbar/progressbar.svelte +++ /dev/null @@ -1,20 +0,0 @@ - - -
-
-

{loadingText}

-
diff --git a/src/lib/components/ui/select/index.ts b/src/lib/components/ui/select/index.ts new file mode 100644 index 0000000..f31b8ae --- /dev/null +++ b/src/lib/components/ui/select/index.ts @@ -0,0 +1,34 @@ +import { Select as SelectPrimitive } from "bits-ui"; + +import GroupHeading from "./select-group-heading.svelte"; +import Item from "./select-item.svelte"; +import Content from "./select-content.svelte"; +import Trigger from "./select-trigger.svelte"; +import Separator from "./select-separator.svelte"; +import ScrollDownButton from "./select-scroll-down-button.svelte"; +import ScrollUpButton from "./select-scroll-up-button.svelte"; + +const Root = SelectPrimitive.Root; +const Group = SelectPrimitive.Group; + +export { + Root, + Group, + GroupHeading, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + // + Root as Select, + Group as SelectGroup, + GroupHeading as SelectGroupHeading, + Item as SelectItem, + Content as SelectContent, + Trigger as SelectTrigger, + Separator as SelectSeparator, + ScrollDownButton as SelectScrollDownButton, + ScrollUpButton as SelectScrollUpButton, +}; diff --git a/src/lib/components/ui/select/select-content.svelte b/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 0000000..56916ef --- /dev/null +++ b/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,39 @@ + + + + + + + {@render children?.()} + + + + diff --git a/src/lib/components/ui/select/select-group-heading.svelte b/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 0000000..7984bef --- /dev/null +++ b/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/select/select-item.svelte b/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 0000000..2616090 --- /dev/null +++ b/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,37 @@ + + + + {#snippet children({ selected, highlighted })} + + {#if selected} + + {/if} + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + {/snippet} + diff --git a/src/lib/components/ui/select/select-scroll-down-button.svelte b/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 0000000..c17d5d1 --- /dev/null +++ b/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/ui/select/select-scroll-up-button.svelte b/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 0000000..8ba08c0 --- /dev/null +++ b/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,19 @@ + + + + + diff --git a/src/lib/components/ui/select/select-separator.svelte b/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 0000000..38a3ab0 --- /dev/null +++ b/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,13 @@ + + + diff --git a/src/lib/components/ui/select/select-trigger.svelte b/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 0000000..a8c0da2 --- /dev/null +++ b/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,24 @@ + + +span]:line-clamp-1", + className + )} + {...restProps} +> + {@render children?.()} + + diff --git a/src/lib/components/ui/separator/index.ts b/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..82442d2 --- /dev/null +++ b/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/src/lib/components/ui/separator/separator.svelte b/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..839494d --- /dev/null +++ b/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,22 @@ + + + diff --git a/src/lib/components/ui/titlebar/titlebar.svelte b/src/lib/components/ui/titlebar/titlebar.svelte index 529eaea..8518a31 100644 --- a/src/lib/components/ui/titlebar/titlebar.svelte +++ b/src/lib/components/ui/titlebar/titlebar.svelte @@ -1,6 +1,8 @@ -
- +
+
+ EZPP Launcher Logo + EZPPLauncher +
@@ -29,7 +34,7 @@