From f595acff64bdd69e4409c5001e70ced1c59ad5ca Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 3 Apr 2025 20:21:05 +0200 Subject: [PATCH] wip --- bun.lock | 307 ++++ drizzle.config.ts | 1 - matches.json | 1802 ++++++++++++++++++++++ messages/en.json | 5 + next.config.js | 9 +- package.json | 42 + scripts/parse-and-sort-data.ts | 11 + src/app/_components/user-stats.tsx | 10 +- src/app/layout.tsx | 11 +- src/app/page.tsx | 4 +- src/app/players/[id]/games.tsx | 97 ++ src/app/players/[id]/page.tsx | 29 + src/app/players/[id]/user.tsx | 358 +++++ src/env.js | 2 + src/i18n/request.ts | 13 + src/server/api/root.ts | 8 +- src/server/api/routers/discord.ts | 15 + src/server/api/routers/history.ts | 119 ++ src/server/api/routers/leaderboard.ts | 15 + src/server/api/routers/post.ts | 39 - src/server/db/schema.ts | 71 +- src/server/services/discord.service.ts | 39 + src/server/services/neatqueue.service.ts | 33 + src/styles/globals.css | 20 + 24 files changed, 2976 insertions(+), 84 deletions(-) create mode 100644 matches.json create mode 100644 messages/en.json create mode 100644 scripts/parse-and-sort-data.ts create mode 100644 src/app/players/[id]/games.tsx create mode 100644 src/app/players/[id]/page.tsx create mode 100644 src/app/players/[id]/user.tsx create mode 100644 src/i18n/request.ts create mode 100644 src/server/api/routers/discord.ts create mode 100644 src/server/api/routers/history.ts create mode 100644 src/server/api/routers/leaderboard.ts delete mode 100644 src/server/api/routers/post.ts create mode 100644 src/server/services/discord.service.ts create mode 100644 src/server/services/neatqueue.service.ts diff --git a/bun.lock b/bun.lock index 62e2edc..33b0a85 100644 --- a/bun.lock +++ b/bun.lock @@ -5,6 +5,33 @@ "name": "balatro-stats-next", "dependencies": { "@auth/drizzle-adapter": "^1.7.2", + "@hookform/resolvers": "^5.0.1", + "@radix-ui/react-accordion": "^1.2.3", + "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-hover-card": "^1.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", "@t3-oss/env-nextjs": "^0.12.0", "@tanstack/react-query": "^5.69.0", "@trpc/client": "^11.0.0", @@ -12,17 +39,31 @@ "@trpc/server": "^11.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", + "date-fns": "^4.1.0", "drizzle-orm": "^0.41.0", + "embla-carousel-react": "^8.5.2", + "input-otp": "^1.4.2", + "ky": "^1.8.0", "lucide-react": "^0.487.0", "next": "^15.2.3", "next-auth": "5.0.0-beta.25", + "next-intl": "^4.0.2", + "next-themes": "^0.4.6", "postgres": "^3.4.4", "react": "^19.0.0", + "react-day-picker": "8.10.1", "react-dom": "^19.0.0", + "react-hook-form": "^7.55.0", + "react-resizable-panels": "^2.1.7", + "recharts": "^2.15.2", + "remeda": "^2.21.2", "server-only": "^0.0.1", + "sonner": "^2.0.3", "superjson": "^2.2.1", "tailwind-merge": "^3.1.0", "tw-animate-css": "^1.2.5", + "vaul": "^1.1.2", "zod": "^3.24.2", }, "devDependencies": { @@ -45,6 +86,8 @@ "@auth/drizzle-adapter": ["@auth/drizzle-adapter@1.8.0", "", { "dependencies": { "@auth/core": "0.38.0" } }, "sha512-cxApE0h5WcyDsgGix9hzmWmCz0qxvmMJexAOQmI6R/YXYxrZ/mKBKu0BlfgQBR6z2XvNWl4wbEGchwSenSCksQ=="], + "@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], + "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="], @@ -117,6 +160,26 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="], + "@floating-ui/core": ["@floating-ui/core@1.6.9", "", { "dependencies": { "@floating-ui/utils": "^0.2.9" } }, "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw=="], + + "@floating-ui/dom": ["@floating-ui/dom@1.6.13", "", { "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.9" } }, "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w=="], + + "@floating-ui/react-dom": ["@floating-ui/react-dom@2.1.2", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", "react-dom": ">=16.8.0" } }, "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A=="], + + "@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="], + + "@formatjs/ecma402-abstract": ["@formatjs/ecma402-abstract@2.3.4", "", { "dependencies": { "@formatjs/fast-memoize": "2.2.7", "@formatjs/intl-localematcher": "0.6.1", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } }, "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA=="], + + "@formatjs/fast-memoize": ["@formatjs/fast-memoize@2.2.7", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ=="], + + "@formatjs/icu-messageformat-parser": ["@formatjs/icu-messageformat-parser@2.11.2", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.4", "@formatjs/icu-skeleton-parser": "1.8.14", "tslib": "^2.8.0" } }, "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA=="], + + "@formatjs/icu-skeleton-parser": ["@formatjs/icu-skeleton-parser@1.8.14", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.4", "tslib": "^2.8.0" } }, "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ=="], + + "@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.5.10", "", { "dependencies": { "tslib": "2" } }, "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q=="], + + "@hookform/resolvers": ["@hookform/resolvers@5.0.1", "", { "dependencies": { "@standard-schema/utils": "^0.3.0" }, "peerDependencies": { "react-hook-form": "^7.55.0" } }, "sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA=="], + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.4" }, "os": "darwin", "cpu": "x64" }, "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q=="], @@ -177,6 +240,114 @@ "@petamoriken/float16": ["@petamoriken/float16@3.9.2", "", {}, "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog=="], + "@radix-ui/number": ["@radix-ui/number@1.1.0", "", {}, "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ=="], + + "@radix-ui/primitive": ["@radix-ui/primitive@1.1.1", "", {}, "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA=="], + + "@radix-ui/react-accordion": ["@radix-ui/react-accordion@1.2.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collapsible": "1.1.3", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A=="], + + "@radix-ui/react-alert-dialog": ["@radix-ui/react-alert-dialog@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dialog": "1.1.6", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-p4XnPqgej8sZAAReCAKgz1REYZEBLR8hU9Pg27wFnCWIMc8g1ccCs0FjBcy05V15VTu8pAePw/VDYeOm/uZ6yQ=="], + + "@radix-ui/react-arrow": ["@radix-ui/react-arrow@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg=="], + + "@radix-ui/react-aspect-ratio": ["@radix-ui/react-aspect-ratio@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-TaJxYoCpxJ7vfEkv2PTNox/6zzmpKXT6ewvCuf2tTOIVN45/Jahhlld29Yw4pciOXS2Xq91/rSGEdmEnUWZCqA=="], + + "@radix-ui/react-avatar": ["@radix-ui/react-avatar@1.1.3", "", { "dependencies": { "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Paen00T4P8L8gd9bNsRMw7Cbaz85oxiv+hzomsRZgFm2byltPFDtfcoqlWJ8GyZlIBWgLssJlzLCnKU0G0302g=="], + + "@radix-ui/react-checkbox": ["@radix-ui/react-checkbox@1.1.4", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-wP0CPAHq+P5I4INKe3hJrIa1WoNqqrejzW+zoU0rOvo1b9gDEJJFl2rYfO1PYJUQCc2H1WZxIJmyv9BS8i5fLw=="], + + "@radix-ui/react-collapsible": ["@radix-ui/react-collapsible@1.1.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw=="], + + "@radix-ui/react-collection": ["@radix-ui/react-collection@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw=="], + + "@radix-ui/react-compose-refs": ["@radix-ui/react-compose-refs@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw=="], + + "@radix-ui/react-context": ["@radix-ui/react-context@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q=="], + + "@radix-ui/react-context-menu": ["@radix-ui/react-context-menu@2.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-menu": "2.1.6", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-aUP99QZ3VU84NPsHeaFt4cQUNgJqFsLLOt/RbbWXszZ6MP0DpDyjkFZORr4RpAEx3sUBk+Kc8h13yGtC5Qw8dg=="], + + "@radix-ui/react-dialog": ["@radix-ui/react-dialog@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw=="], + + "@radix-ui/react-direction": ["@radix-ui/react-direction@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg=="], + + "@radix-ui/react-dismissable-layer": ["@radix-ui/react-dismissable-layer@1.1.5", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-escape-keydown": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg=="], + + "@radix-ui/react-dropdown-menu": ["@radix-ui/react-dropdown-menu@2.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-menu": "2.1.6", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA=="], + + "@radix-ui/react-focus-guards": ["@radix-ui/react-focus-guards@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg=="], + + "@radix-ui/react-focus-scope": ["@radix-ui/react-focus-scope@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA=="], + + "@radix-ui/react-hover-card": ["@radix-ui/react-hover-card@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-popper": "1.2.2", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-E4ozl35jq0VRlrdc4dhHrNSV0JqBb4Jy73WAhBEK7JoYnQ83ED5r0Rb/XdVKw89ReAJN38N492BAPBZQ57VmqQ=="], + + "@radix-ui/react-id": ["@radix-ui/react-id@1.1.0", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA=="], + + "@radix-ui/react-label": ["@radix-ui/react-label@2.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw=="], + + "@radix-ui/react-menu": ["@radix-ui/react-menu@2.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-popper": "1.2.2", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-roving-focus": "1.1.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-callback-ref": "1.1.0", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg=="], + + "@radix-ui/react-menubar": ["@radix-ui/react-menubar@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-menu": "2.1.6", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-roving-focus": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-FHq7+3DlXwh/7FOM4i0G4bC4vPjiq89VEEvNF4VMLchGnaUuUbE5uKXMUCjdKaOghEEMeiKa5XCa2Pk4kteWmg=="], + + "@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.5", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-visually-hidden": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-myMHHQUZ3ZLTi8W381/Vu43Ia0NqakkQZ2vzynMmTUtQQ9kNkjzhOwkZC9TAM5R07OZUVIQyHC06f/9JZJpvvA=="], + + "@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-popper": "1.2.2", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg=="], + + "@radix-ui/react-popper": ["@radix-ui/react-popper@1.2.2", "", { "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-rect": "1.1.0", "@radix-ui/react-use-size": "1.1.0", "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA=="], + + "@radix-ui/react-portal": ["@radix-ui/react-portal@1.1.4", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA=="], + + "@radix-ui/react-presence": ["@radix-ui/react-presence@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg=="], + + "@radix-ui/react-primitive": ["@radix-ui/react-primitive@2.0.2", "", { "dependencies": { "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w=="], + + "@radix-ui/react-progress": ["@radix-ui/react-progress@1.1.2", "", { "dependencies": { "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-u1IgJFQ4zNAUTjGdDL5dcl/U8ntOR6jsnhxKb5RKp5Ozwl88xKR9EqRZOe/Mk8tnx0x5tNUe2F+MzsyjqMg0MA=="], + + "@radix-ui/react-radio-group": ["@radix-ui/react-radio-group@1.2.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-roving-focus": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-xtCsqt8Rp09FK50ItqEqTJ7Sxanz8EM8dnkVIhJrc/wkMMomSmXHvYbhv3E7Zx4oXh98aaLt9W679SUYXg4IDA=="], + + "@radix-ui/react-roving-focus": ["@radix-ui/react-roving-focus@1.1.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw=="], + + "@radix-ui/react-scroll-area": ["@radix-ui/react-scroll-area@1.2.3", "", { "dependencies": { "@radix-ui/number": "1.1.0", "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-l7+NNBfBYYJa9tNqVcP2AGvxdE3lmE6kFTBXdvHgUaZuy+4wGCL1Cl2AfaR7RKyimj7lZURGLwFO59k4eBnDJQ=="], + + "@radix-ui/react-select": ["@radix-ui/react-select@2.1.6", "", { "dependencies": { "@radix-ui/number": "1.1.0", "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-popper": "1.2.2", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-visually-hidden": "1.1.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg=="], + + "@radix-ui/react-separator": ["@radix-ui/react-separator@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ=="], + + "@radix-ui/react-slider": ["@radix-ui/react-slider@1.2.3", "", { "dependencies": { "@radix-ui/number": "1.1.0", "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.2", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-nNrLAWLjGESnhqBqcCNW4w2nn7LxudyMzeB6VgdyAnFLC6kfQgnAjSL2v6UkQTnDctJBlxrmxfplWS4iYjdUTw=="], + + "@radix-ui/react-slot": ["@radix-ui/react-slot@1.1.2", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ=="], + + "@radix-ui/react-switch": ["@radix-ui/react-switch@1.1.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-use-previous": "1.1.0", "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1nc+vjEOQkJVsJtWPSiISGT6OKm4SiOdjMo+/icLxo2G4vxz1GntC5MzfL4v8ey9OEfw787QCD1y3mUv0NiFEQ=="], + + "@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.3", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-roving-focus": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng=="], + + "@radix-ui/react-toggle": ["@radix-ui/react-toggle@1.1.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-lntKchNWx3aCHuWKiDY+8WudiegQvBpDRAYL8dKLRvKEH8VOpl0XX6SSU/bUBqIRJbcTy4+MW06Wv8vgp10rzQ=="], + + "@radix-ui/react-toggle-group": ["@radix-ui/react-toggle-group@1.1.2", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-roving-focus": "1.1.2", "@radix-ui/react-toggle": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-JBm6s6aVG/nwuY5eadhU2zDi/IwYS0sDM5ZWb4nymv/hn3hZdkw+gENn0LP4iY1yCd7+bgJaCwueMYJIU3vk4A=="], + + "@radix-ui/react-tooltip": ["@radix-ui/react-tooltip@1.1.8", "", { "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-id": "1.1.0", "@radix-ui/react-popper": "1.2.2", "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "@radix-ui/react-visually-hidden": "1.1.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YAA2cu48EkJZdAMHC0dqo9kialOcRStbtiY4nJPaht7Ptrhcvpo+eDChaM6BIs8kL6a8Z5l5poiqLnXcNduOkA=="], + + "@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="], + + "@radix-ui/react-use-controllable-state": ["@radix-ui/react-use-controllable-state@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw=="], + + "@radix-ui/react-use-escape-keydown": ["@radix-ui/react-use-escape-keydown@1.1.0", "", { "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw=="], + + "@radix-ui/react-use-layout-effect": ["@radix-ui/react-use-layout-effect@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="], + + "@radix-ui/react-use-previous": ["@radix-ui/react-use-previous@1.1.0", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og=="], + + "@radix-ui/react-use-rect": ["@radix-ui/react-use-rect@1.1.0", "", { "dependencies": { "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ=="], + + "@radix-ui/react-use-size": ["@radix-ui/react-use-size@1.1.0", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw=="], + + "@radix-ui/react-visually-hidden": ["@radix-ui/react-visually-hidden@1.1.2", "", { "dependencies": { "@radix-ui/react-primitive": "2.0.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q=="], + + "@radix-ui/rect": ["@radix-ui/rect@1.1.0", "", {}, "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="], + + "@schummar/icu-type-parser": ["@schummar/icu-type-parser@1.21.5", "", {}, "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw=="], + + "@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="], + "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], @@ -225,12 +396,32 @@ "@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="], + "@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="], + + "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="], + + "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="], + + "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="], + + "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="], + + "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="], + + "@types/d3-shape": ["@types/d3-shape@3.1.7", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg=="], + + "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="], + + "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="], + "@types/node": ["@types/node@20.17.30", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg=="], "@types/react": ["@types/react@19.1.0", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w=="], "@types/react-dom": ["@types/react-dom@19.1.1", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w=="], + "aria-hidden": ["aria-hidden@1.2.4", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A=="], + "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], "busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="], @@ -243,6 +434,8 @@ "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + "cmdk": ["cmdk@1.1.1", "", { "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", "@radix-ui/react-dialog": "^1.1.6", "@radix-ui/react-id": "^1.1.0", "@radix-ui/react-primitive": "^2.0.2" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "react-dom": "^18 || ^19 || ^19.0.0-rc" } }, "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg=="], + "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], @@ -257,14 +450,52 @@ "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="], + + "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="], + + "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="], + + "d3-format": ["d3-format@3.1.0", "", {}, "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA=="], + + "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="], + + "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="], + + "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="], + + "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="], + + "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="], + + "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="], + + "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="], + + "date-fns": ["date-fns@4.1.0", "", {}, "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg=="], + "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + "decimal.js": ["decimal.js@10.5.0", "", {}, "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw=="], + + "decimal.js-light": ["decimal.js-light@2.5.1", "", {}, "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg=="], + "detect-libc": ["detect-libc@2.0.3", "", {}, "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw=="], + "detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="], + + "dom-helpers": ["dom-helpers@5.2.1", "", { "dependencies": { "@babel/runtime": "^7.8.7", "csstype": "^3.0.2" } }, "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA=="], + "drizzle-kit": ["drizzle-kit@0.30.6", "", { "dependencies": { "@drizzle-team/brocli": "^0.10.2", "@esbuild-kit/esm-loader": "^2.5.5", "esbuild": "^0.19.7", "esbuild-register": "^3.5.0", "gel": "^2.0.0" }, "bin": { "drizzle-kit": "bin.cjs" } }, "sha512-U4wWit0fyZuGuP7iNmRleQyK2V8wCuv57vf5l3MnG4z4fzNTjY/U13M8owyQ5RavqvqxBifWORaR3wIUzlN64g=="], "drizzle-orm": ["drizzle-orm@0.41.0", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q=="], + "embla-carousel": ["embla-carousel@8.5.2", "", {}, "sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg=="], + + "embla-carousel-react": ["embla-carousel-react@8.5.2", "", { "dependencies": { "embla-carousel": "8.5.2", "embla-carousel-reactive-utils": "8.5.2" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA=="], + + "embla-carousel-reactive-utils": ["embla-carousel-reactive-utils@8.5.2", "", { "peerDependencies": { "embla-carousel": "8.5.2" } }, "sha512-QC8/hYSK/pEmqEdU1IO5O+XNc/Ptmmq7uCB44vKplgLKhB/l0+yvYx0+Cv0sF6Ena8Srld5vUErZkT+yTahtDg=="], + "enhanced-resolve": ["enhanced-resolve@5.18.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg=="], "env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="], @@ -273,12 +504,24 @@ "esbuild-register": ["esbuild-register@3.6.0", "", { "dependencies": { "debug": "^4.3.4" }, "peerDependencies": { "esbuild": ">=0.12 <1" } }, "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg=="], + "eventemitter3": ["eventemitter3@4.0.7", "", {}, "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="], + + "fast-equals": ["fast-equals@5.2.2", "", {}, "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw=="], + "gel": ["gel@2.0.1", "", { "dependencies": { "@petamoriken/float16": "^3.8.7", "debug": "^4.3.4", "env-paths": "^3.0.0", "semver": "^7.6.2", "shell-quote": "^1.8.1", "which": "^4.0.0" }, "bin": { "gel": "dist/cli.mjs" } }, "sha512-gfem3IGvqKqXwEq7XseBogyaRwGsQGuE7Cw/yQsjLGdgiyqX92G1xENPCE0ltunPGcsJIa6XBOTx/PK169mOqw=="], + "get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="], + "get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "input-otp": ["input-otp@1.4.2", "", { "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA=="], + + "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], + + "intl-messageformat": ["intl-messageformat@10.7.16", "", { "dependencies": { "@formatjs/ecma402-abstract": "2.3.4", "@formatjs/fast-memoize": "2.2.7", "@formatjs/icu-messageformat-parser": "2.11.2", "tslib": "^2.8.0" } }, "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug=="], + "is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="], "is-what": ["is-what@4.1.16", "", {}, "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A=="], @@ -289,6 +532,10 @@ "jose": ["jose@6.0.10", "", {}, "sha512-skIAxZqcMkOrSwjJvplIPYrlXGpxTPnro2/QWTDCxAdWQrSTV5/KqspMWmi5WAx5+ULswASJiZ0a+1B/Lxt9cw=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "ky": ["ky@1.8.0", "", {}, "sha512-DoKGmG27nT8t/1F9gV8vNzggJ3mLAyD49J8tTMWHeZvS8qLc7GlyTieicYtFzvDznMe/q2u38peOjkWc5/pjvw=="], + "lightningcss": ["lightningcss@1.29.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.29.2", "lightningcss-darwin-x64": "1.29.2", "lightningcss-freebsd-x64": "1.29.2", "lightningcss-linux-arm-gnueabihf": "1.29.2", "lightningcss-linux-arm64-gnu": "1.29.2", "lightningcss-linux-arm64-musl": "1.29.2", "lightningcss-linux-x64-gnu": "1.29.2", "lightningcss-linux-x64-musl": "1.29.2", "lightningcss-win32-arm64-msvc": "1.29.2", "lightningcss-win32-x64-msvc": "1.29.2" } }, "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA=="], "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.29.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA=="], @@ -311,18 +558,30 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.29.2", "", { "os": "win32", "cpu": "x64" }, "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA=="], + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + + "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], + "lucide-react": ["lucide-react@0.487.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + "negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + "next": ["next@15.2.4", "", { "dependencies": { "@next/env": "15.2.4", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.2.4", "@next/swc-darwin-x64": "15.2.4", "@next/swc-linux-arm64-gnu": "15.2.4", "@next/swc-linux-arm64-musl": "15.2.4", "@next/swc-linux-x64-gnu": "15.2.4", "@next/swc-linux-x64-musl": "15.2.4", "@next/swc-win32-arm64-msvc": "15.2.4", "@next/swc-win32-x64-msvc": "15.2.4", "sharp": "^0.33.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ=="], "next-auth": ["next-auth@5.0.0-beta.25", "", { "dependencies": { "@auth/core": "0.37.2" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "next": "^14.0.0-0 || ^15.0.0-0", "nodemailer": "^6.6.5", "react": "^18.2.0 || ^19.0.0-0" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-2dJJw1sHQl2qxCrRk+KTQbeH+izFbGFPuJj5eGgBZFYyiYYtvlrBeUw1E/OJJxTRjuxbSYGnCTkUIRsIIW0bog=="], + "next-intl": ["next-intl@4.0.2", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.5.4", "negotiator": "^1.0.0", "use-intl": "^4.0.2" }, "peerDependencies": { "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0", "typescript": "^5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-3cKVflwdrqxCOvAL+DtGN68qR802i0PEj0dttkAD5IK5XxOjugQs4yU8aSakvPMbkOrhEJ+89z5lG2EAqi7Gkw=="], + + "next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="], + "oauth4webapi": ["oauth4webapi@3.3.2", "", {}, "sha512-hCJgDQayOLpBxdDpzShK/SI3C1PVnkj4CcKLOGyQm23Lk5V+qYPH+LtQlu8YO29MswBry/FBVlwWBnWgQvaFdA=="], + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "postcss": ["postcss@8.5.3", "", { "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A=="], @@ -335,10 +594,38 @@ "pretty-format": ["pretty-format@3.8.0", "", {}, "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="], + "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + "react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="], + "react-day-picker": ["react-day-picker@8.10.1", "", { "peerDependencies": { "date-fns": "^2.28.0 || ^3.0.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA=="], + "react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="], + "react-hook-form": ["react-hook-form@7.55.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog=="], + + "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="], + + "react-remove-scroll": ["react-remove-scroll@2.6.3", "", { "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ=="], + + "react-remove-scroll-bar": ["react-remove-scroll-bar@2.3.8", "", { "dependencies": { "react-style-singleton": "^2.2.2", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q=="], + + "react-resizable-panels": ["react-resizable-panels@2.1.7", "", { "peerDependencies": { "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-JtT6gI+nURzhMYQYsx8DKkx6bSoOGFp7A3CwMrOb8y5jFHFyqwo9m68UhmXRw57fRVJksFn1TSlm3ywEQ9vMgA=="], + + "react-smooth": ["react-smooth@4.0.4", "", { "dependencies": { "fast-equals": "^5.0.1", "prop-types": "^15.8.1", "react-transition-group": "^4.4.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q=="], + + "react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="], + + "react-transition-group": ["react-transition-group@4.4.5", "", { "dependencies": { "@babel/runtime": "^7.5.5", "dom-helpers": "^5.0.1", "loose-envify": "^1.4.0", "prop-types": "^15.6.2" }, "peerDependencies": { "react": ">=16.6.0", "react-dom": ">=16.6.0" } }, "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g=="], + + "recharts": ["recharts@2.15.2", "", { "dependencies": { "clsx": "^2.0.0", "eventemitter3": "^4.0.1", "lodash": "^4.17.21", "react-is": "^18.3.1", "react-smooth": "^4.0.4", "recharts-scale": "^0.4.4", "tiny-invariant": "^1.3.1", "victory-vendor": "^36.6.8" }, "peerDependencies": { "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-xv9lVztv3ingk7V3Jf05wfAZbM9Q2umJzu5t/cfnAK7LUslNrGT7LPBr74G+ok8kSCeFMaePmWMg0rcYOnczTw=="], + + "recharts-scale": ["recharts-scale@0.4.5", "", { "dependencies": { "decimal.js-light": "^2.4.1" } }, "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w=="], + + "regenerator-runtime": ["regenerator-runtime@0.14.1", "", {}, "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="], + + "remeda": ["remeda@2.21.2", "", { "dependencies": { "type-fest": "^4.37.0" } }, "sha512-wdhkMDou8HRpD7RnxKJ/FHJWEGXRH7jV/pb0NsdLLSoBo+G9RjtxcY41hVhogLfEMkThk6aySKjs+Yd6PnpzBA=="], + "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], @@ -353,6 +640,8 @@ "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], + "sonner": ["sonner@2.0.3", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA=="], + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], @@ -371,24 +660,42 @@ "tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="], + "tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tw-animate-css": ["tw-animate-css@1.2.5", "", {}, "sha512-ABzjfgVo+fDbhRREGL4KQZUqqdPgvc5zVrLyeW9/6mVqvaDepXc7EvedA+pYmMnIOsUAQMwcWzNvom26J2qYvQ=="], + "type-fest": ["type-fest@4.39.1", "", {}, "sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w=="], + "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], "undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + "use-callback-ref": ["use-callback-ref@1.3.3", "", { "dependencies": { "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg=="], + + "use-intl": ["use-intl@4.0.2", "", { "dependencies": { "@formatjs/fast-memoize": "^2.2.0", "@schummar/icu-type-parser": "1.21.5", "intl-messageformat": "^10.5.14" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0" } }, "sha512-6RAP/5KJMRzLMLS25/BVh2u09cRK8S6HRGc1RnZvqR547qAKZCpjYylOqMPU9eNIirAiKoGmsoUPa7JrlaA/yg=="], + + "use-sidecar": ["use-sidecar@1.1.3", "", { "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ=="], + + "vaul": ["vaul@1.1.2", "", { "dependencies": { "@radix-ui/react-dialog": "^1.1.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc" } }, "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA=="], + + "victory-vendor": ["victory-vendor@36.9.2", "", { "dependencies": { "@types/d3-array": "^3.0.3", "@types/d3-ease": "^3.0.0", "@types/d3-interpolate": "^3.0.1", "@types/d3-scale": "^4.0.2", "@types/d3-shape": "^3.1.0", "@types/d3-time": "^3.0.0", "@types/d3-timer": "^3.0.0", "d3-array": "^3.1.6", "d3-ease": "^3.0.1", "d3-interpolate": "^3.0.1", "d3-scale": "^4.0.2", "d3-shape": "^3.1.0", "d3-time": "^3.0.0", "d3-timer": "^3.0.1" } }, "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ=="], + "which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="], "zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="], "@esbuild-kit/core-utils/esbuild": ["esbuild@0.18.20", "", { "optionalDependencies": { "@esbuild/android-arm": "0.18.20", "@esbuild/android-arm64": "0.18.20", "@esbuild/android-x64": "0.18.20", "@esbuild/darwin-arm64": "0.18.20", "@esbuild/darwin-x64": "0.18.20", "@esbuild/freebsd-arm64": "0.18.20", "@esbuild/freebsd-x64": "0.18.20", "@esbuild/linux-arm": "0.18.20", "@esbuild/linux-arm64": "0.18.20", "@esbuild/linux-ia32": "0.18.20", "@esbuild/linux-loong64": "0.18.20", "@esbuild/linux-mips64el": "0.18.20", "@esbuild/linux-ppc64": "0.18.20", "@esbuild/linux-riscv64": "0.18.20", "@esbuild/linux-s390x": "0.18.20", "@esbuild/linux-x64": "0.18.20", "@esbuild/netbsd-x64": "0.18.20", "@esbuild/openbsd-x64": "0.18.20", "@esbuild/sunos-x64": "0.18.20", "@esbuild/win32-arm64": "0.18.20", "@esbuild/win32-ia32": "0.18.20", "@esbuild/win32-x64": "0.18.20" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA=="], + "@formatjs/ecma402-abstract/@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.6.1", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg=="], + "next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], "next-auth/@auth/core": ["@auth/core@0.37.2", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "@types/cookie": "0.6.0", "cookie": "0.7.1", "jose": "^5.9.3", "oauth4webapi": "^3.0.0", "preact": "10.11.3", "preact-render-to-string": "5.2.3" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^6.8.0" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-kUvzyvkcd6h1vpeMAojK2y7+PAV5H+0Cc9+ZlKYDFhDY31AlvsB+GW5vNO4qE3Y07KeQgvNO9U0QUx/fN62kBw=="], + "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="], "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.18.20", "", { "os": "android", "cpu": "arm64" }, "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ=="], diff --git a/drizzle.config.ts b/drizzle.config.ts index 61b7476..9249fe5 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -8,5 +8,4 @@ export default { dbCredentials: { url: env.DATABASE_URL, }, - tablesFilter: ['balatro-stats-next_*'], } satisfies Config diff --git a/matches.json b/matches.json new file mode 100644 index 0000000..030f16f --- /dev/null +++ b/matches.json @@ -0,0 +1,1802 @@ +{ + "25666": { + "players": [ + { + "name": "Zvede", + "id": "131131434114088961", + "mmr": 1000, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:15:17.582181", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Grimbley largo", + "id": "565156413060415488", + "mmr": 1000, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:12:15.047982", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "Zvede", + "id": "131131434114088961", + "mmr": 1000, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:15:17.582181", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Grimbley largo", + "id": "565156413060415488", + "mmr": 1000, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:12:15.047982", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357327600443330590", + "queue_channel_id": "1339055812567629904" + }, + "25691": { + "players": [ + { + "name": "StatsGPT", + "id": "195215928189911040", + "mmr": 232.0526776174761, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:56:31.102508", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Shadow", + "id": "1345838914467921971", + "mmr": 328.0205187924963, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:58:15.354621", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "StatsGPT", + "id": "195215928189911040", + "mmr": 232.0526776174761, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:56:31.102508", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Shadow", + "id": "1345838914467921971", + "mmr": 328.0205187924963, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:58:15.354621", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357338538479456256", + "queue_channel_id": "1352157545547960350" + }, + "25699": { + "players": [ + { + "name": "semi.", + "id": "210985350015877122", + "mmr": 225.39749216873767, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:07:28.107651", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Hiroto", + "id": "631897395730317313", + "mmr": 287.15343524182344, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:07:30.609788", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "semi.", + "id": "210985350015877122", + "mmr": 225.39749216873767, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:07:28.107651", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Hiroto", + "id": "631897395730317313", + "mmr": 287.15343524182344, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:07:30.609788", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357333166653702346", + "queue_channel_id": "1352157545547960350" + }, + "25700": { + "players": [ + { + "name": "kyle\\_and\\_error", + "id": "271875156383760384", + "mmr": 205.55958562135348, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:08:23.708228", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Napstabl0ok", + "id": "202246718752948224", + "mmr": 200, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:08:09.146623", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "kyle\\_and\\_error", + "id": "271875156383760384", + "mmr": 205.55958562135348, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:08:23.708228", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Napstabl0ok", + "id": "202246718752948224", + "mmr": 200, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:08:09.146623", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357330436639948893", + "queue_channel_id": "1352157545547960350" + }, + "25703": { + "players": [ + { + "name": "Joemoe Dice Addict", + "id": "274600237249724419", + "mmr": 447.3199896652319, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:15:35.240588", + "pulled_from": "1357309658280366230", + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "piton322", + "id": "252137283606675456", + "mmr": 377.37256518148445, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:14:43.239128", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "Joemoe Dice Addict", + "id": "274600237249724419", + "mmr": 447.3199896652319, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:15:35.240588", + "pulled_from": "1357309658280366230", + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "piton322", + "id": "252137283606675456", + "mmr": 377.37256518148445, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:14:43.239128", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357333436511162408", + "queue_channel_id": "1352157545547960350" + }, + "25705": { + "players": [ + { + "name": "The Rock", + "id": "682705449539076116", + "mmr": 93.05323025545073, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:59:56.434821", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "The Music Man", + "id": "620136730208632835", + "mmr": 198.046878105182, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:59:49.520768", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "The Rock", + "id": "682705449539076116", + "mmr": 93.05323025545073, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:59:56.434821", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "The Music Man", + "id": "620136730208632835", + "mmr": 198.046878105182, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T12:59:49.520768", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357334246859083797", + "queue_channel_id": "1352157545547960350" + }, + "25706": { + "players": [ + { + "name": "Hermanito", + "id": "795429609033302036", + "mmr": 423.65995334036893, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:22:21.906888", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "dark", + "id": "1101728594641834004", + "mmr": 456.4415250614959, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:18:19.882943", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "Hermanito", + "id": "795429609033302036", + "mmr": 423.65995334036893, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:22:21.906888", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "dark", + "id": "1101728594641834004", + "mmr": 456.4415250614959, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:18:19.882943", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357334809424167127", + "queue_channel_id": "1352157545547960350" + }, + "25707": { + "players": [ + { + "name": "NinXD", + "id": "658103347173392414", + "mmr": 134.18671879824566, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:20:59.252052", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Vono", + "id": "212024542946656256", + "mmr": 134.8250796402249, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:22:18.607778", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "NinXD", + "id": "658103347173392414", + "mmr": 134.18671879824566, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:20:59.252052", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Vono", + "id": "212024542946656256", + "mmr": 134.8250796402249, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:22:18.607778", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357328718799962247", + "queue_channel_id": "1352157545547960350" + }, + "25708": { + "players": [ + { + "name": "jazzclub", + "id": "430347220429176832", + "mmr": 187.2725685693113, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:24:49.736146", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "seacow", + "id": "345112013887897601", + "mmr": 88.38675308307712, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:23:03.433574", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "jazzclub", + "id": "430347220429176832", + "mmr": 187.2725685693113, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:24:49.736146", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "seacow", + "id": "345112013887897601", + "mmr": 88.38675308307712, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:23:03.433574", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357345226334933102", + "queue_channel_id": "1352157545547960350" + }, + "25709": { + "players": [ + { + "name": "0xVairocana", + "id": "1153201331625005066", + "mmr": 100.31700123025418, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:26:56.339915", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Stebob", + "id": "400399918512209921", + "mmr": 167.98922875733427, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:26:53.151678", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "0xVairocana", + "id": "1153201331625005066", + "mmr": 100.31700123025418, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:26:56.339915", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Stebob", + "id": "400399918512209921", + "mmr": 167.98922875733427, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:26:53.151678", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357345659530907798", + "queue_channel_id": "1352157545547960350" + }, + "25710": { + "players": [ + { + "name": "TheIvyX", + "id": "116960382572036100", + "mmr": 231.12465018783135, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:08.600246", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Monkey 🐒", + "id": "824871557381488671", + "mmr": 426.33254091931985, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:26:03.177750", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "TheIvyX", + "id": "116960382572036100", + "mmr": 231.12465018783135, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:08.600246", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Monkey 🐒", + "id": "824871557381488671", + "mmr": 426.33254091931985, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:26:03.177750", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357345724844736522", + "queue_channel_id": "1352157545547960350" + }, + "25711": { + "players": [ + { + "name": "Leny!", + "id": "607183041332510731", + "mmr": 165.7701551180979, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:25:18.024152", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "janiesomplayer", + "id": "1092007966753955850", + "mmr": 200, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:28.725128", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "Leny!", + "id": "607183041332510731", + "mmr": 165.7701551180979, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:25:18.024152", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "janiesomplayer", + "id": "1092007966753955850", + "mmr": 200, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:28.725128", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357345767890616340", + "queue_channel_id": "1352157545547960350" + }, + "25712": { + "players": [ + { + "name": "boofmoreket", + "id": "756386498005434379", + "mmr": 178.15578921965687, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:54.481749", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "BalatroVietNam", + "id": "1301833903463596123", + "mmr": 200, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:43.271620", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "boofmoreket", + "id": "756386498005434379", + "mmr": 178.15578921965687, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:54.481749", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "BalatroVietNam", + "id": "1301833903463596123", + "mmr": 200, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:27:43.271620", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357345875159941151", + "queue_channel_id": "1352157545547960350" + }, + "25713": { + "players": [ + { + "name": "senuzulmeyeter14", + "id": "1266176215333732478", + "mmr": 199.64549939665304, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:28:54.140900", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Mango\\_blade11", + "id": "608819366762643467", + "mmr": 264.9419902155505, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:28:56.556070", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "senuzulmeyeter14", + "id": "1266176215333732478", + "mmr": 199.64549939665304, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:28:54.140900", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Mango\\_blade11", + "id": "608819366762643467", + "mmr": 264.9419902155505, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:28:56.556070", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357346198066827460", + "queue_channel_id": "1352157545547960350" + }, + "25714": { + "players": [ + { + "name": "Undercover FBI", + "id": "355655291196669952", + "mmr": 207.7299291022093, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:07.838893", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Sir Sammy Snickerdoodle VII", + "id": "1135414909555966092", + "mmr": 223.02768019466862, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:00.054301", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "Undercover FBI", + "id": "355655291196669952", + "mmr": 207.7299291022093, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:07.838893", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Sir Sammy Snickerdoodle VII", + "id": "1135414909555966092", + "mmr": 223.02768019466862, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:00.054301", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357346202043154604", + "queue_channel_id": "1352157545547960350" + }, + "25715": { + "players": [ + { + "name": "jr212", + "id": "708129488722067466", + "mmr": 244.69667040184837, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:30:02.672932", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "FlashX", + "id": "380405580722077708", + "mmr": 263.40028073822, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:58.392873", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "jr212", + "id": "708129488722067466", + "mmr": 244.69667040184837, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:30:02.672932", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "FlashX", + "id": "380405580722077708", + "mmr": 263.40028073822, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:58.392873", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357346457342054462", + "queue_channel_id": "1352157545547960350" + }, + "25716": { + "players": [ + { + "name": "Hardtomatoes", + "id": "362824921325240330", + "mmr": 282.2224093864399, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:30:19.807680", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "Olaf", + "id": "539991423223857164", + "mmr": 374.1758602103126, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:40.069162", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "Hardtomatoes", + "id": "362824921325240330", + "mmr": 282.2224093864399, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:30:19.807680", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "Olaf", + "id": "539991423223857164", + "mmr": 374.1758602103126, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:29:40.069162", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357346610077765693", + "queue_channel_id": "1352157545547960350" + }, + "25717": { + "players": [ + { + "name": "EDG ZmjjBB", + "id": "895906953535049728", + "mmr": 156.90215686353167, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:33:40.189182", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + }, + { + "name": "roki", + "id": "297783945842393089", + "mmr": 236.9377666175967, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:33:53.106761", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + "teams": [ + [ + { + "name": "EDG ZmjjBB", + "id": "895906953535049728", + "mmr": 156.90215686353167, + "role": null, + "team_num": 0, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:33:40.189182", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ], + [ + { + "name": "roki", + "id": "297783945842393089", + "mmr": 236.9377666175967, + "role": null, + "team_num": 1, + "top_role_index": 0, + "ign": null, + "timestamp": "2025-04-03T13:33:53.106761", + "pulled_from": null, + "team_name": null, + "party_leader": null, + "captain": null, + "picked": false, + "mmr_change": 0, + "priority": 0, + "guild_id": "1226193436521267223", + "mmr_multiplier": 1, + "points_multiplier": 1, + "tournament_team_id": null, + "queue_entry_survey": {} + } + ] + ], + "channel_id": "1357347442361630790", + "queue_channel_id": "1352157545547960350" + } +} diff --git a/messages/en.json b/messages/en.json new file mode 100644 index 0000000..8a71bae --- /dev/null +++ b/messages/en.json @@ -0,0 +1,5 @@ +{ + "HomePage": { + "title": "Hello world!" + } +} diff --git a/next.config.js b/next.config.js index 818f024..b8b0d98 100644 --- a/next.config.js +++ b/next.config.js @@ -3,8 +3,11 @@ * for Docker builds. */ import './src/env.js' +import createNextIntlPlugin from 'next-intl/plugin' /** @type {import("next").NextConfig} */ -const config = {} - -export default config +const config = { + output: 'standalone', +} +const withNextIntl = createNextIntlPlugin() +export default withNextIntl(config) diff --git a/package.json b/package.json index df211f6..8f0b933 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "balatro-stats-next", "version": "0.1.0", "private": true, + "license": "AGPL-3.0-only", "type": "module", "scripts": { "build": "next build", @@ -19,6 +20,33 @@ }, "dependencies": { "@auth/drizzle-adapter": "^1.7.2", + "@hookform/resolvers": "^5.0.1", + "@radix-ui/react-accordion": "^1.2.3", + "@radix-ui/react-alert-dialog": "^1.1.6", + "@radix-ui/react-aspect-ratio": "^1.1.2", + "@radix-ui/react-avatar": "^1.1.3", + "@radix-ui/react-checkbox": "^1.1.4", + "@radix-ui/react-collapsible": "^1.1.3", + "@radix-ui/react-context-menu": "^2.2.6", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-hover-card": "^1.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-menubar": "^1.1.6", + "@radix-ui/react-navigation-menu": "^1.2.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-progress": "^1.1.2", + "@radix-ui/react-radio-group": "^1.2.3", + "@radix-ui/react-scroll-area": "^1.2.3", + "@radix-ui/react-select": "^2.1.6", + "@radix-ui/react-separator": "^1.1.2", + "@radix-ui/react-slider": "^1.2.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.3", + "@radix-ui/react-tabs": "^1.1.3", + "@radix-ui/react-toggle": "^1.1.2", + "@radix-ui/react-toggle-group": "^1.1.2", + "@radix-ui/react-tooltip": "^1.1.8", "@t3-oss/env-nextjs": "^0.12.0", "@tanstack/react-query": "^5.69.0", "@trpc/client": "^11.0.0", @@ -26,17 +54,31 @@ "@trpc/server": "^11.0.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "cmdk": "^1.1.1", + "date-fns": "^4.1.0", "drizzle-orm": "^0.41.0", + "embla-carousel-react": "^8.5.2", + "input-otp": "^1.4.2", + "ky": "^1.8.0", "lucide-react": "^0.487.0", "next": "^15.2.3", "next-auth": "5.0.0-beta.25", + "next-intl": "^4.0.2", + "next-themes": "^0.4.6", "postgres": "^3.4.4", "react": "^19.0.0", + "react-day-picker": "8.10.1", "react-dom": "^19.0.0", + "react-hook-form": "^7.55.0", + "react-resizable-panels": "^2.1.7", + "recharts": "^2.15.2", + "remeda": "^2.21.2", "server-only": "^0.0.1", + "sonner": "^2.0.3", "superjson": "^2.2.1", "tailwind-merge": "^3.1.0", "tw-animate-css": "^1.2.5", + "vaul": "^1.1.2", "zod": "^3.24.2" }, "devDependencies": { diff --git a/scripts/parse-and-sort-data.ts b/scripts/parse-and-sort-data.ts new file mode 100644 index 0000000..15ce66d --- /dev/null +++ b/scripts/parse-and-sort-data.ts @@ -0,0 +1,11 @@ +// @ts-nocheck + +const data = await fetch( + 'https://api.neatqueue.com/api/history/1226193436521267223' +).then((res) => res.json()) + +const parsed_and_sorted = data.data.toSorted((a, b) => { + return a.game_num - b.game_num +}) + +await Bun.write('./src/data.json', JSON.stringify(parsed_and_sorted, null, 2)) diff --git a/src/app/_components/user-stats.tsx b/src/app/_components/user-stats.tsx index 2711ada..9090985 100644 --- a/src/app/_components/user-stats.tsx +++ b/src/app/_components/user-stats.tsx @@ -1,7 +1,15 @@ +'use client' + +import { api } from '@/trpc/react' + export function UserStats() { + const sync_mutation = api.history.sync.useMutation() return (
+

User stats

) -} \ No newline at end of file +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8b73ce4..332e493 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,6 +4,8 @@ import type { Metadata } from 'next' import { Geist } from 'next/font/google' import { TRPCReactProvider } from '@/trpc/react' +import { NextIntlClientProvider } from 'next-intl' +import { getLocale } from 'next-intl/server' export const metadata: Metadata = { title: 'Create T3 App', @@ -16,13 +18,16 @@ const geist = Geist({ variable: '--font-geist-sans', }) -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode }>) { + const locale = await getLocale() return ( - + - {children} + + {children} + ) diff --git a/src/app/page.tsx b/src/app/page.tsx index e38817c..0a66e04 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,11 +3,11 @@ import { auth } from '@/server/auth' import { HydrateClient, api } from '@/trpc/server' export default async function Home() { - const hello = await api.post.hello({ text: 'from tRPC' }) const session = await auth() if (session?.user) { - void api.post.getLatest.prefetch() + console.log('user', session.user) + // void api.post.getLatest.prefetch() } return ( diff --git a/src/app/players/[id]/games.tsx b/src/app/players/[id]/games.tsx new file mode 100644 index 0000000..a1f65f9 --- /dev/null +++ b/src/app/players/[id]/games.tsx @@ -0,0 +1,97 @@ +'use client' + +import { + Table, + TableBody, + TableCaption, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' +import { cn } from '@/lib/utils' +import { api } from '@/trpc/react' +import { useFormatter } from 'next-intl' +import { useParams } from 'next/navigation' + +export function PlayerGames() { + const { id } = useParams() + if (!id || typeof id !== 'string') { + return null + } + const [games] = api.history.user_games.useSuspenseQuery({ user_id: id }) + + const format = useFormatter() + + return ( + + User's latest games + + + Game type + Opponent + Opponent MMR + MMR + Result + Date + Time + + + + {games.map((game) => { + return ( + + {game.gameType} + {game.opponentName} + + {Math.trunc(game.opponentMmr)} + + + {Math.trunc(game.playerMmr)} + + + + + + + {format.dateTime(game.gameTime, { + hour: '2-digit', + minute: '2-digit', + })} + + + ) + })} + +
+ ) +} + +const numberFormatter = new Intl.NumberFormat('en-US', { + signDisplay: 'exceptZero', +}) + +function GameResultCell({ + result, + mmrChange, +}: { result: string; mmrChange: number }) { + return ( + + {numberFormatter.format(Math.trunc(mmrChange))} + + ) +} diff --git a/src/app/players/[id]/page.tsx b/src/app/players/[id]/page.tsx new file mode 100644 index 0000000..1c7df5f --- /dev/null +++ b/src/app/players/[id]/page.tsx @@ -0,0 +1,29 @@ +import { PlayerGames } from '@/app/players/[id]/games' +import { UserInfo } from '@/app/players/[id]/user' +import { auth } from '@/server/auth' +import { HydrateClient, api } from '@/trpc/server' +import { Suspense } from 'react' + +export default async function PlayerPage({ + params, +}: { + params: Promise<{ id: string }> +}) { + const session = await auth() + const { id } = await params + if (id) { + await api.history.user_games.prefetch({ + user_id: id, + }) + await api.discord.get_user_by_id.prefetch({ + user_id: id, + }) + } + return ( + + + + + + ) +} diff --git a/src/app/players/[id]/user.tsx b/src/app/players/[id]/user.tsx new file mode 100644 index 0000000..9aae6e8 --- /dev/null +++ b/src/app/players/[id]/user.tsx @@ -0,0 +1,358 @@ +'use client' + +import type React from 'react' +import { useState } from 'react' + +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' +import { Badge } from '@/components/ui/badge' +import { Card, CardContent, CardHeader } from '@/components/ui/card' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { cn } from '@/lib/utils' +import { api } from '@/trpc/react' +import { + ArrowDownCircle, + ArrowUpCircle, + BarChart3, + Calendar, + ChevronDown, + ChevronUp, + Clock, + Filter, + Medal, + MinusCircle, + Users, +} from 'lucide-react' +import { useFormatter } from 'next-intl' +import { useParams } from 'next/navigation' + +const numberFormatter = new Intl.NumberFormat('en-US', { + signDisplay: 'exceptZero', +}) +const dateFormatter = new Intl.DateTimeFormat('en-US', { + dateStyle: 'long', +}) +export function UserInfo() { + const format = useFormatter() + + const [filter, setFilter] = useState('all') + const { id } = useParams() + if (!id || typeof id !== 'string') return null + + const [games] = api.history.user_games.useSuspenseQuery({ user_id: id }) + const [discord_user] = api.discord.get_user_by_id.useSuspenseQuery({ + user_id: id, + }) + const games_played = games.length + let wins = 0 + let losses = 0 + let ties = 0 + for (const game of games) { + if (game.result === 'win') { + wins++ + } else if (game.result === 'loss') { + losses++ + } else if (game.result === 'tie') { + ties++ + } + } + const profileData = { + username: discord_user.username, + avatar: discord_user.avatar_url, + games: games_played, + wins, + losses, + ties, + winRate: Math.round((wins / games_played) * 100), + rank: 1, + } + + const lastGame = games.at(0) + const firstGame = games.at(-1) + console.log(lastGame) + return ( +
+
+ + +
+
+ + + + {profileData.username.slice(0, 2).toUpperCase()} + + +
+ +
+

+ {profileData.username} +

+

+ {firstGame ? ( + <>First game: {dateFormatter.format(firstGame.gameTime)} + ) : ( + <>No games played yet + )} +

+
+ + + Rank #342 + + + + Gold + +
+
+ +
+
+
Current MMR
+
+ {Math.trunc( + lastGame ? lastGame.playerMmr + lastGame.mmrChange : 200 + )} +
+
+ {!!lastGame && + (lastGame.mmrChange > 0 ? ( + + + {numberFormatter.format( + Math.trunc(lastGame.mmrChange) + )}{' '} + last match + + ) : ( + + + {numberFormatter.format( + Math.trunc(lastGame.mmrChange) + )}{' '} + last match + + ))} +
+
+
+
+
+ + +
+ } + description='Total matches' + /> + } + description={`${profileData.winRate}% win rate`} + accentColor='text-emerald-500' + /> + } + description={`${Math.round((profileData.losses / profileData.games) * 100)}% loss rate`} + accentColor='text-rose-500' + /> + } + description={`${Math.round((profileData.ties / profileData.games) * 100)}% tie rate`} + accentColor='text-amber-500' + /> +
+ + +
+ + Match History + Statistics + Achievements + + +
+ + +
+
+ + +
+
+ + + + Game Type + Opponent + + Opponent MMR + + Your MMR + Result + + + Date + + + + + Time + + + + + + {games.map((game) => ( + + + + {game.gameType} + + + + {game.opponentName} + + + {Math.trunc(game.opponentMmr)} + + + {Math.trunc(game.playerMmr)} + + + {game.mmrChange > 0 ? ( + + + {numberFormatter.format( + Math.trunc(game.mmrChange) + )} + + ) : ( + + + {numberFormatter.format( + Math.trunc(game.mmrChange) + )} + + )} + + + {format.dateTime(game.gameTime, { + year: 'numeric', + month: '2-digit', + day: '2-digit', + })} + + + {format.dateTime(game.gameTime, { + hour: '2-digit', + minute: '2-digit', + })} + + + ))} + +
+
+
+
+ + +
+

+ Statistics coming soon +

+
+
+ + +
+

+ Achievements coming soon +

+
+
+
+
+
+
+
+ ) +} + +interface StatsCardProps { + title: string + value: number + icon: React.ReactNode + description: string + accentColor?: string +} + +function StatsCard({ + title, + value, + icon, + description, + accentColor = 'text-violet-500', +}: StatsCardProps) { + return ( +
+
{icon}
+

+ {title} +

+

{value}

+

+ {description} +

+
+ ) +} diff --git a/src/env.js b/src/env.js index e6c4bb8..aedfa1a 100644 --- a/src/env.js +++ b/src/env.js @@ -13,6 +13,7 @@ export const env = createEnv({ : z.string().optional(), AUTH_DISCORD_ID: z.string(), AUTH_DISCORD_SECRET: z.string(), + DISCORD_BOT_TOKEN: z.string(), DATABASE_URL: z.string().url(), NODE_ENV: z .enum(['development', 'test', 'production']) @@ -37,6 +38,7 @@ export const env = createEnv({ AUTH_DISCORD_ID: process.env.AUTH_DISCORD_ID, AUTH_DISCORD_SECRET: process.env.AUTH_DISCORD_SECRET, DATABASE_URL: process.env.DATABASE_URL, + DISCORD_BOT_TOKEN: process.env.DISCORD_BOT_TOKEN, NODE_ENV: process.env.NODE_ENV, }, /** diff --git a/src/i18n/request.ts b/src/i18n/request.ts new file mode 100644 index 0000000..ec049ed --- /dev/null +++ b/src/i18n/request.ts @@ -0,0 +1,13 @@ +import { getRequestConfig } from 'next-intl/server' +import { headers } from 'next/headers' + +export default getRequestConfig(async () => { + // Provide a static locale, fetch a user setting, + // read from `cookies()`, `headers()`, etc. + const locale = (await headers()).get('accept-language')?.split(',')[0] ?? 'en' + + return { + locale, + messages: (await import('../../messages/en.json')).default, + } +}) diff --git a/src/server/api/root.ts b/src/server/api/root.ts index c5c71ed..41765fb 100644 --- a/src/server/api/root.ts +++ b/src/server/api/root.ts @@ -1,4 +1,6 @@ -import { postRouter } from '@/server/api/routers/post' +import { discord_router } from '@/server/api/routers/discord' +import { history_router } from '@/server/api/routers/history' +import { leaderboard_router } from '@/server/api/routers/leaderboard' import { createCallerFactory, createTRPCRouter } from '@/server/api/trpc' /** @@ -7,7 +9,9 @@ import { createCallerFactory, createTRPCRouter } from '@/server/api/trpc' * All routers added in /api/routers should be manually added here. */ export const appRouter = createTRPCRouter({ - post: postRouter, + history: history_router, + discord: discord_router, + leaderboard: leaderboard_router, }) // export type definition of API diff --git a/src/server/api/routers/discord.ts b/src/server/api/routers/discord.ts new file mode 100644 index 0000000..c154781 --- /dev/null +++ b/src/server/api/routers/discord.ts @@ -0,0 +1,15 @@ +import { createTRPCRouter, publicProcedure } from '@/server/api/trpc' +import { discord_service } from '@/server/services/discord.service' +import { z } from 'zod' + +export const discord_router = createTRPCRouter({ + get_user_by_id: publicProcedure + .input( + z.object({ + user_id: z.string(), + }) + ) + .query(async ({ ctx, input }) => { + return await discord_service.get_user_by_id(input.user_id) + }), +}) diff --git a/src/server/api/routers/history.ts b/src/server/api/routers/history.ts new file mode 100644 index 0000000..cdbaa2f --- /dev/null +++ b/src/server/api/routers/history.ts @@ -0,0 +1,119 @@ +import { + createTRPCRouter, + protectedProcedure, + publicProcedure, +} from '@/server/api/trpc' +import { db } from '@/server/db' +import { player_games, raw_history } from '@/server/db/schema' +import { desc, eq } from 'drizzle-orm' +import { chunk } from 'remeda' +import { z } from 'zod' + +export const history_router = createTRPCRouter({ + user_games: publicProcedure + .input( + z.object({ + user_id: z.string(), + }) + ) + .query(async ({ ctx, input }) => { + const entries = await ctx.db + .select() + .from(player_games) + .where(eq(player_games.playerId, input.user_id)) + .orderBy(desc(player_games.gameNum)) + return entries + }), + sync: publicProcedure.mutation(async () => { + await db.delete(raw_history).execute() + await db.delete(player_games).execute() + // const chunkedData = chunk(data, 100) + // for (const chunk of chunkedData) { + // await insertGameHistory(chunk).catch((e) => { + // console.error(e) + // }) + // } + // return data + }), +}) + +function processGameEntry(gameId: number, game_num: number, entry: any) { + const parsedEntry = typeof entry === 'string' ? JSON.parse(entry) : entry + if (parsedEntry.game === '1v1-attrition') { + return [] + } + if (!parsedEntry.teams?.[0]?.[0] || !parsedEntry.teams?.[1]?.[0]) { + console.log('skipping game', parsedEntry) + return [] + } + + if (parsedEntry.winner === -2) { + console.log('skipping ongoing game', parsedEntry) + return [] + } + const player0 = parsedEntry.teams[0][0] + const player1 = parsedEntry.teams[1][0] + let p0result = null + let p1result = null + + if (parsedEntry.winner === 2) { + p0result = 'tie' + p1result = 'tie' + } else if (parsedEntry.winner === 0) { + p0result = 'win' + p1result = 'loss' + } else if (parsedEntry.winner === 1) { + p0result = 'loss' + p1result = 'win' + } else { + p0result = 'unknown' + p1result = 'unknown' + } + return [ + { + gameId, + gameNum: game_num, + gameTime: new Date(parsedEntry.time), + gameType: parsedEntry.game, + mmrChange: Number.parseFloat(player0.mmr_change), + opponentId: player1.id, + opponentMmr: Number.parseFloat(player1.mmr), + opponentName: player1.name, + playerId: player0.id, + playerMmr: Number.parseFloat(player0.mmr), + playerName: player0.name, + result: p0result, + won: parsedEntry.winner === 0, + }, + { + gameId, + gameNum: game_num, + gameTime: new Date(parsedEntry.time), + gameType: parsedEntry.game, + mmrChange: Number.parseFloat(player1.mmr_change), + opponentId: player0.id, + opponentMmr: Number.parseFloat(player0.mmr), + opponentName: player0.name, + playerId: player1.id, + playerMmr: Number.parseFloat(player1.mmr), + playerName: player1.name, + result: p1result, + won: parsedEntry.winner === 1, + }, + ] +} +export async function insertGameHistory(entries: any[]) { + const rawResults = await db + .insert(raw_history) + .values(entries.map((entry) => ({ entry, game_num: entry.game_num }))) + .returning() + + const playerGameRows = rawResults.flatMap(({ entry, id, game_num }) => { + return processGameEntry(id, game_num, entry) + }) + + await db.insert(player_games).values(playerGameRows).onConflictDoUpdate({ + target: player_games.gameNum, + set: {}, + }) +} diff --git a/src/server/api/routers/leaderboard.ts b/src/server/api/routers/leaderboard.ts new file mode 100644 index 0000000..2eea9dd --- /dev/null +++ b/src/server/api/routers/leaderboard.ts @@ -0,0 +1,15 @@ +import { createTRPCRouter, publicProcedure } from '@/server/api/trpc' +import { neatqueue_service } from '@/server/services/neatqueue.service' +import { z } from 'zod' + +export const leaderboard_router = createTRPCRouter({ + get_leaderboard: publicProcedure + .input( + z.object({ + channel_id: z.string(), + }) + ) + .query(async ({ input }) => { + return await neatqueue_service.get_leaderboard(input.channel_id) + }), +}) diff --git a/src/server/api/routers/post.ts b/src/server/api/routers/post.ts deleted file mode 100644 index 9c8fc8a..0000000 --- a/src/server/api/routers/post.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { z } from 'zod' - -import { - createTRPCRouter, - protectedProcedure, - publicProcedure, -} from '@/server/api/trpc' -import { posts } from '@/server/db/schema' - -export const postRouter = createTRPCRouter({ - hello: publicProcedure - .input(z.object({ text: z.string() })) - .query(({ input }) => { - return { - greeting: `Hello ${input.text}`, - } - }), - - create: protectedProcedure - .input(z.object({ name: z.string().min(1) })) - .mutation(async ({ ctx, input }) => { - await ctx.db.insert(posts).values({ - name: input.name, - createdById: ctx.session.user.id, - }) - }), - - getLatest: protectedProcedure.query(async ({ ctx }) => { - const post = await ctx.db.query.posts.findFirst({ - orderBy: (posts, { desc }) => [desc(posts.createdAt)], - }) - - return post ?? null - }), - - getSecretMessage: protectedProcedure.query(() => { - return 'you can now see this secret message!' - }), -}) diff --git a/src/server/db/schema.ts b/src/server/db/schema.ts index c908791..6eb4218 100644 --- a/src/server/db/schema.ts +++ b/src/server/db/schema.ts @@ -1,39 +1,44 @@ import { relations, sql } from 'drizzle-orm' -import { index, pgTableCreator, primaryKey } from 'drizzle-orm/pg-core' +import { + boolean, + index, + integer, + json, + pgTable, + primaryKey, + real, + text, + timestamp, + uniqueIndex, +} from 'drizzle-orm/pg-core' import type { AdapterAccount } from 'next-auth/adapters' -/** - * This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same - * database instance for multiple projects. - * - * @see https://orm.drizzle.team/docs/goodies#multi-project-schema - */ -export const createTable = pgTableCreator( - (name) => `balatro-stats-next_${name}` +export const raw_history = pgTable( + 'raw_history', + { + id: integer('id').primaryKey().generatedByDefaultAsIdentity(), + game_num: integer('game_num').notNull(), + entry: json(), + }, + (t) => [uniqueIndex('game_num_unique_idx').on(t.game_num)] ) -export const posts = createTable( - 'post', - (d) => ({ - id: d.integer().primaryKey().generatedByDefaultAsIdentity(), - name: d.varchar({ length: 256 }), - createdById: d - .varchar({ length: 255 }) - .notNull() - .references(() => users.id), - createdAt: d - .timestamp({ withTimezone: true }) - .default(sql`CURRENT_TIMESTAMP`) - .notNull(), - updatedAt: d.timestamp({ withTimezone: true }).$onUpdate(() => new Date()), - }), - (t) => [ - index('created_by_idx').on(t.createdById), - index('name_idx').on(t.name), - ] -) +export const player_games = pgTable('player_games', { + playerId: text('player_id').notNull(), + playerName: text('player_name').notNull(), + gameId: integer('game_id').notNull(), + gameTime: timestamp('game_time').notNull(), + gameType: text('game_type').notNull(), + gameNum: integer('game_num').notNull(), + playerMmr: real('player_mmr').notNull(), + mmrChange: real('mmr_change').notNull(), + opponentId: text('opponent_id').notNull(), + opponentName: text('opponent_name').notNull(), + opponentMmr: real('opponent_mmr').notNull(), + result: text('result').notNull(), +}) -export const users = createTable('user', (d) => ({ +export const users = pgTable('user', (d) => ({ id: d .varchar({ length: 255 }) .notNull() @@ -54,7 +59,7 @@ export const usersRelations = relations(users, ({ many }) => ({ accounts: many(accounts), })) -export const accounts = createTable( +export const accounts = pgTable( 'account', (d) => ({ userId: d @@ -82,7 +87,7 @@ export const accountsRelations = relations(accounts, ({ one }) => ({ user: one(users, { fields: [accounts.userId], references: [users.id] }), })) -export const sessions = createTable( +export const sessions = pgTable( 'session', (d) => ({ sessionToken: d.varchar({ length: 255 }).notNull().primaryKey(), @@ -99,7 +104,7 @@ export const sessionsRelations = relations(sessions, ({ one }) => ({ user: one(users, { fields: [sessions.userId], references: [users.id] }), })) -export const verificationTokens = createTable( +export const verificationTokens = pgTable( 'verification_token', (d) => ({ identifier: d.varchar({ length: 255 }).notNull(), diff --git a/src/server/services/discord.service.ts b/src/server/services/discord.service.ts new file mode 100644 index 0000000..21d34bf --- /dev/null +++ b/src/server/services/discord.service.ts @@ -0,0 +1,39 @@ +import { env } from '@/env' +import ky from 'ky' + +const DISCORD_URL = 'https://discord.com/api/v10' +const instance = ky.create({ + prefixUrl: DISCORD_URL, + headers: { + Authorization: `Bot ${env.DISCORD_BOT_TOKEN}`, + }, + timeout: 10000, +}) + +export const discord_service = { + get_user_by_id: async (user_id: string) => { + const res = await instance.get(`users/${user_id}`) + const res_json = await res.json() + + return { + ...res_json, + avatar_url: `https://cdn.discordapp.com/avatars/${user_id}/${res_json.avatar}.png`, + } + }, +} +export type DiscordUser = { + id: string + username: string + avatar: string + discriminator: string + public_flags: number + flags: number + banner?: unknown + accent_color?: unknown + global_name: string + avatar_decoration_data?: unknown + collectibles?: unknown + banner_color?: unknown + clan?: unknown + primary_guild?: unknown +} diff --git a/src/server/services/neatqueue.service.ts b/src/server/services/neatqueue.service.ts new file mode 100644 index 0000000..aa88ad0 --- /dev/null +++ b/src/server/services/neatqueue.service.ts @@ -0,0 +1,33 @@ +import ky from 'ky' + +const NEATQUEUE_URL = 'https://api.neatqueue.com/api' + +const instance = ky.create({ + prefixUrl: NEATQUEUE_URL, + timeout: 10000, +}) + +const BMM_SERVER_ID = '1352157545547960350' + +export const neatqueue_service = { + get_leaderboard: async (channel_id: string) => { + const response = await instance.get( + `leaderboard/${BMM_SERVER_ID}/${channel_id}` + ) + + return response.json() + }, + get_history: async ( + player_ids: string[], + server_id: string = BMM_SERVER_ID + ) => { + const response = await instance + .get(`history/${server_id}`, { + searchParams: { + server_id, + }, + }) + .json() + return response + }, +} diff --git a/src/styles/globals.css b/src/styles/globals.css index 960b82e..792dae0 100644 --- a/src/styles/globals.css +++ b/src/styles/globals.css @@ -113,6 +113,26 @@ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); + --animate-accordion-down: accordion-down 0.2s ease-out; + --animate-accordion-up: accordion-up 0.2s ease-out; + + @keyframes accordion-down { + from { + height: 0; + } + to { + height: var(--radix-accordion-content-height); + } + } + + @keyframes accordion-up { + from { + height: var(--radix-accordion-content-height); + } + to { + height: 0; + } + } } @layer base {