diff --git a/.oxfmtrc.json b/.oxfmtrc.json index 4e8caa7b..59848e48 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -6,6 +6,7 @@ // Automatically generated code "src/routeTree.gen.ts", + "src/hooks/use-mobile.ts", // Shadcn/ui components "src/components/ui", diff --git a/.oxlintrc.json b/.oxlintrc.json index 7ca8cbe8..c4e896ab 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -16,6 +16,7 @@ // Automatically generated code "src/routeTree.gen.ts", + "src/hooks/use-mobile.ts", // Shadcn/ui components "src/components/ui", diff --git a/eslint.config.js b/eslint.config.js index ee467eef..6811e10b 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -12,6 +12,7 @@ export default defineConfig([ // Automatically generated code "src/routeTree.gen.ts", + "src/hooks/use-mobile.ts", // Shadcn/ui components "src/components/ui", diff --git a/mise.toml b/mise.toml index 27d30ad6..75c61585 100644 --- a/mise.toml +++ b/mise.toml @@ -1,6 +1,6 @@ [tools] node = "24.17.0" -pnpm = "11.8.0" +pnpm = "11.9.0" [settings] diff --git a/package.json b/package.json index 534cc74a..0fb9fe8c 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,11 @@ "@fontsource-variable/raleway": "^5.2.8", "@icons-pack/react-simple-icons": "^13.13.0", "@schedule-x/calendar": "^4.6.0", + "@schedule-x/calendar-controls": "^4.6.0", "@schedule-x/react": "^4.1.0", "@schedule-x/scroll-controller": "^4.6.0", "@schedule-x/theme-shadcn": "^4.6.0", + "@tanstack/react-form": "^1.33.0", "@tanstack/react-query": "^5.101.0", "@tanstack/react-router": "^1.170.15", "axios": "^1.18.0", @@ -28,7 +30,8 @@ "react-dom": "^19.2.7", "sonner": "^2.0.7", "tailwind-merge": "^3.6.0", - "temporal-polyfill": "^1.0.0" + "temporal-polyfill": "^1.0.0", + "zod": "^4.4.3" }, "devDependencies": { "@rolldown/plugin-babel": "^0.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 894fbe9f..be04081b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,25 +19,31 @@ importers: version: 13.13.0(react@19.2.7) '@schedule-x/calendar': specifier: ^4.6.0 - version: 4.6.0(@preact/signals@2.9.2(preact@10.29.2))(preact@10.29.2)(temporal-polyfill@1.0.1) + version: 4.6.0(@preact/signals@2.9.2(preact@10.29.3))(preact@10.29.3)(temporal-polyfill@1.0.1) + '@schedule-x/calendar-controls': + specifier: ^4.6.0 + version: 4.6.0 '@schedule-x/react': specifier: ^4.1.0 - version: 4.1.0(@schedule-x/calendar@4.6.0(@preact/signals@2.9.2(preact@10.29.2))(preact@10.29.2)(temporal-polyfill@1.0.1))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + version: 4.1.0(@schedule-x/calendar@4.6.0(@preact/signals@2.9.2(preact@10.29.3))(preact@10.29.3)(temporal-polyfill@1.0.1))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@schedule-x/scroll-controller': specifier: ^4.6.0 - version: 4.6.0(@preact/signals@2.9.2(preact@10.29.2)) + version: 4.6.0(@preact/signals@2.9.2(preact@10.29.3)) '@schedule-x/theme-shadcn': specifier: ^4.6.0 version: 4.6.0 + '@tanstack/react-form': + specifier: ^1.33.0 + version: 1.33.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/react-query': specifier: ^5.101.0 - version: 5.101.0(react@19.2.7) + version: 5.101.1(react@19.2.7) '@tanstack/react-router': specifier: ^1.170.15 version: 1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7) axios: specifier: ^1.18.0 - version: 1.18.0 + version: 1.18.1 class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -68,22 +74,25 @@ importers: temporal-polyfill: specifier: ^1.0.0 version: 1.0.1 + zod: + specifier: ^4.4.3 + version: 4.4.3 devDependencies: '@rolldown/plugin-babel': specifier: ^0.2.3 - version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) '@tailwindcss/vite': specifier: ^4.3.0 - version: 4.3.1(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + version: 4.3.1(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) '@tanstack/eslint-plugin-query': specifier: ^5.101.0 - version: 5.101.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 5.101.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) '@tanstack/eslint-plugin-router': specifier: ^1.162.0 version: 1.162.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) '@tanstack/router-plugin': specifier: ^1.168.18 - version: 1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + version: 1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) '@types/babel__core': specifier: ^7.20.5 version: 7.20.5 @@ -98,7 +107,7 @@ importers: version: 19.2.3(@types/react@19.2.17) '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.0.2(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + version: 6.0.3(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 @@ -107,46 +116,46 @@ importers: version: 10.5.0(jiti@2.7.0) eslint-plugin-better-tailwindcss: specifier: ^4.6.0 - version: 4.6.0(eslint@10.5.0(jiti@2.7.0))(oxlint@1.70.0(oxlint-tsgolint@0.23.0))(tailwindcss@4.3.1)(typescript@6.0.3) + version: 4.6.0(eslint@10.5.0(jiti@2.7.0))(oxlint@1.71.0(oxlint-tsgolint@0.23.0))(tailwindcss@4.3.1)(typescript@6.0.3) eslint-plugin-oxlint: specifier: ^1.70.0 - version: 1.70.0(oxlint@1.70.0(oxlint-tsgolint@0.23.0)) + version: 1.71.0(oxlint@1.71.0(oxlint-tsgolint@0.23.0)) eslint-plugin-perfectionist: specifier: ^5.9.1 version: 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-react-dom: specifier: ^5.9.0 - version: 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-react-hooks: specifier: ^7.1.1 version: 7.1.1(eslint@10.5.0(jiti@2.7.0)) eslint-plugin-react-jsx: specifier: ^5.9.0 - version: 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-react-naming-convention: specifier: ^5.9.0 - version: 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-react-x: specifier: ^5.9.0 - version: 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) globals: specifier: ^17.6.0 - version: 17.6.0 + version: 17.7.0 oxfmt: specifier: ^0.55.0 version: 0.55.0 oxlint: specifier: ^1.70.0 - version: 1.70.0(oxlint-tsgolint@0.23.0) + version: 1.71.0(oxlint-tsgolint@0.23.0) oxlint-tsgolint: specifier: ^0.23.0 version: 0.23.0 react-scan: specifier: ^0.5.7 - version: 0.5.7(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + version: 0.5.7(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) shadcn: specifier: ^4.11.0 - version: 4.11.0(typescript@6.0.3) + version: 4.11.1(typescript@6.0.3) tailwindcss: specifier: ^4.3.0 version: 4.3.1 @@ -158,10 +167,10 @@ importers: version: 6.0.3 typescript-eslint: specifier: ^8.61.1 - version: 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) vite: specifier: ^8.0.16 - version: 8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) + version: 8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) packages: @@ -349,12 +358,18 @@ packages: '@emnapi/core@1.11.0': resolution: {integrity: sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==} + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} '@emnapi/runtime@1.11.0': resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -371,43 +386,43 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint-react/ast@5.9.1': - resolution: {integrity: sha512-PEBHBKxuKGrseO828u5/HFo89TdOa946q5veEjdDR+BjxlMuxhZxIqHkPyoS93dh6E+9mkZkcDerSGY5nCsm8Q==} + '@eslint-react/ast@5.9.3': + resolution: {integrity: sha512-je5lXEnIjs454kTs3x5Jw/7GCbJbccIqjhECZqH3myo3m/zckhYQCsdzmMITGd6zzP25A+jw3jw6w/9st9BOTg==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - '@eslint-react/core@5.9.1': - resolution: {integrity: sha512-CQ7ZQCRoqaHSBxld2zzfvjPBWuH0R6Op9FvCq+Nfennv/k6gbecA7IV47SlaXC7TKVB7zxiiwD3kD8ftaL8+xA==} + '@eslint-react/core@5.9.3': + resolution: {integrity: sha512-vv1sXIhPcq5wSXttw4WoE6EufaA3w2ey1i9vroKwc9SxnoxpJBH0ReaC9AZ+sTmGwIz8msqWQU4hAl0vtmI+4A==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - '@eslint-react/eslint@5.9.1': - resolution: {integrity: sha512-YJVfj1Z0+uaYI+KmdNDQpLT8KceLRjf8UH3gd/fJJ+Ye3jBuS5sXDxBBoG74OF61/mtTugrc9aBCes4hlouwBg==} + '@eslint-react/eslint@5.9.3': + resolution: {integrity: sha512-x/29XHfW4XtntFEOinsxCJsoa4LTWmYLGQtzEvH7WAgbMRabaaAgbOP4u5uWQdgCNOx3Yq0cgu+cE9G7KWCaIA==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - '@eslint-react/jsx@5.9.1': - resolution: {integrity: sha512-rZVIWotHLOYdbsmBEMJCQlu2gUeHcU8dYa7EkhWPwuh3p1q1ydV+Jfn4whJwHVb/mTI8zy4957RnFbGGWVLa6g==} + '@eslint-react/jsx@5.9.3': + resolution: {integrity: sha512-caY0YnLjXcFYCBQ1T2XkjuOh7rAPcXbgn6oJ/bNYFRDAt6juRjxmGZcwc+3j/YOSClHuyO6wOrFdsO1O/Vfq+Q==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - '@eslint-react/shared@5.9.1': - resolution: {integrity: sha512-6VBZo5KTlyUrn27aW6u6nqVvX9igWxzQX0vVNCv/ObnCA6ElOn1TBC9ENwRoK73FJ86PcT25PWyz1LJRgwnefw==} + '@eslint-react/shared@5.9.3': + resolution: {integrity: sha512-Ydu7Jw4FQXWSRIiC0MbnmiSKjLaFURNDQ6VA9aj/spmOFpg+CZOFOCQKj8OsxFmwXn4ja16c9d78Ro/ffAxNVA==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - '@eslint-react/var@5.9.1': - resolution: {integrity: sha512-s+hb4H+6CzFsL2E6Yw6/c3bzSFfNc2XNOP2Q60k4G05VCbUew30Aqcf0Ehiac5wgGmpDZ9/9wkJiNanW2M1viA==} + '@eslint-react/var@5.9.3': + resolution: {integrity: sha512-4SLx2Ql2F8cFFRK2Dj9jPGx5Mx91WVoUkTGbPlDB4UXnEuokkeciiVu6QPezig8ffm0FPkgDSgKdQgAJlDvz7Q==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' @@ -516,8 +531,8 @@ packages: '@cfworker/json-schema': optional: true - '@napi-rs/wasm-runtime@1.1.5': - resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 @@ -827,12 +842,12 @@ packages: '@oxc-project/types@0.132.0': resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} - '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} - '@oxc-project/types@0.135.0': resolution: {integrity: sha512-wR+xRdFkUBMvcAjBJ2q2kcZM6d+DKu2NgoOyxZgYwZdLhmiv6+rnO8PZ/P68kMiZtIKm+pW7zyEJ4kSOs0vo+Q==} + '@oxc-project/types@0.137.0': + resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} + '@oxc-resolver/binding-android-arm-eabi@11.21.3': resolution: {integrity: sha512-eNU11A2WNizh04v3uyaJCootrHIaS0B9aHYXvAvVnPNk4xYSjMUjHnhQ6dewPN2MRYDskV85d1N0Aw0WNWhcyg==} cpu: [arm] @@ -1094,8 +1109,8 @@ packages: cpu: [arm] os: [android] - '@oxlint/binding-android-arm-eabi@1.70.0': - resolution: {integrity: sha512-zFh0P4cswmRvw6nkyb89dr18rRanuaCPAsEXsFDoQY8WdaquI8Pt4NWFjaMJg6L23cy5NeN8J9cBnREbWzZhaw==} + '@oxlint/binding-android-arm-eabi@1.71.0': + resolution: {integrity: sha512-ImGmd1njEg4FEJH03jhRnveEegtO3czCtfptvaHivKAZQIYATbVFBrrzbaYMYv0oJioTnxZAZVSyV+oL7W8S2g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] @@ -1106,8 +1121,8 @@ packages: cpu: [arm64] os: [android] - '@oxlint/binding-android-arm64@1.70.0': - resolution: {integrity: sha512-qI8o4HZjeGiBrWv+pJv4lH0Yi2Gl/JSp/EumBUApezJprIKa5PS4nU0lQsQngtky8k+SplQIOjv6hwu0SSxeyg==} + '@oxlint/binding-android-arm64@1.71.0': + resolution: {integrity: sha512-4A5BEexBrwY1YFF8Kiq/lp/wQPRG79G3BWIE1FuWaM5MvmpYSd+7ZySVcKkHdwo0UDzdQGddp6pD9mpctMqLnw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -1118,8 +1133,8 @@ packages: cpu: [arm64] os: [darwin] - '@oxlint/binding-darwin-arm64@1.70.0': - resolution: {integrity: sha512-8KjgVVHI5F9nVwHCRwwA78Ty7zNKP4Wd9OeN5PSv3iu/F/u1RVXoOCgLhWqust6HmwQG6xc8c+RCyaWENy24+w==} + '@oxlint/binding-darwin-arm64@1.71.0': + resolution: {integrity: sha512-9wJA9GJulLwS2usU3CEisI/ESDO1n1z9eyTCvApMDrAkbJ1ve0mORgTMjcWWsKxkzkeZ2N/Gpra5IQE7x8tYgQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -1130,8 +1145,8 @@ packages: cpu: [x64] os: [darwin] - '@oxlint/binding-darwin-x64@1.70.0': - resolution: {integrity: sha512-WVydssv5PSUBXFJTdNBWlmGkbNmvPGaFt/2SUT/EZRB6bq6bEOHmMlbnupZD5jmlEvi9+mZJHi8TCw15lyfSfQ==} + '@oxlint/binding-darwin-x64@1.71.0': + resolution: {integrity: sha512-PlLCjS06V0PeJMAJwzjrExw1sYNW9Gch3JtNlcwwZDXGlTYDuwHNN89zYH8LTXFfgkVtsYvs2nv0FqrzyuFDzg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -1142,8 +1157,8 @@ packages: cpu: [x64] os: [freebsd] - '@oxlint/binding-freebsd-x64@1.70.0': - resolution: {integrity: sha512-hJucmUf8OlinHNb1R7fI4Fw6WsAstOz7i8nmkWQfiHoZXtbufNm+MxiDTIMk1ggh2Ro4vLzgQ+bKvRY54MZoRA==} + '@oxlint/binding-freebsd-x64@1.71.0': + resolution: {integrity: sha512-Lhil7bWre0ncxbUoDoxfS0JzpTz17BRQKW7iwoAUY8GJ66+WwJEfYPCFJ1P0WgVZR5/O/b3Q2pENlHOjeXLOGQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -1154,8 +1169,8 @@ packages: cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-gnueabihf@1.70.0': - resolution: {integrity: sha512-1BnS7wbCYDSXwWzJJ+mc3NURoha6m6m6RT5c6vgAY3oz7C3OVXP+S0awo2mRq97arrJkVvO3qRQfyAHL+76xtQ==} + '@oxlint/binding-linux-arm-gnueabihf@1.71.0': + resolution: {integrity: sha512-Oo9/L58PYD3RC0x05d2upAPLllHytTjHQGsnC06P6Ynn7jKkp5mdImQxXdJ3+FnBaKspNpGogzgVsi6g872LiA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -1166,8 +1181,8 @@ packages: cpu: [arm] os: [linux] - '@oxlint/binding-linux-arm-musleabihf@1.70.0': - resolution: {integrity: sha512-yKy/UdbR55+M2yEcuiV5DCNC/gdQAjr/GioUy50QwBzSrKm8ueWADqyRLS9Xk+qjNeCYGg6A8FvUBds56ttfqg==} + '@oxlint/binding-linux-arm-musleabihf@1.71.0': + resolution: {integrity: sha512-mSHfyfgJrEbyIR29ejaeS50BdPk+GoNPlC1dckpDiUZbJAIel68sjSMdOt4WY0/gva+ECC7FNITQkxMJU+vSBw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -1179,8 +1194,8 @@ packages: os: [linux] libc: [glibc] - '@oxlint/binding-linux-arm64-gnu@1.70.0': - resolution: {integrity: sha512-0A5XJ4alvmqFUFP/4oYSyaO+qLto/HrKEWTSaegiVl+HOufFngK2BjYw9x4RbwBt/du5QG6l5q1zeWiJYYG5yg==} + '@oxlint/binding-linux-arm64-gnu@1.71.0': + resolution: {integrity: sha512-n9yY4M2tiy3aij4AqtlnspzpfdpeT5JQfK2/w2d8oyp5W0FRwOb1dIeX99nORNcxGr08iD9bH8N5XFz3I2iy8w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -1193,8 +1208,8 @@ packages: os: [linux] libc: [musl] - '@oxlint/binding-linux-arm64-musl@1.70.0': - resolution: {integrity: sha512-JiylyurlB0CLSedNtx1gzv3FvfWPF1h/2Y3BJszPLNt5XQFlBsH5ke0Jle3iJb3uqu5m2e7A/DwzpuCAHdiU+A==} + '@oxlint/binding-linux-arm64-musl@1.71.0': + resolution: {integrity: sha512-fJZrs5sDZtTaPIOiemRQQmo82Ezy+vOGXemPc4Ok7iVVsYsFa7SlW6Z5XN819VfsqBHRm3NJ3rTdnR8+bJYJdQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -1207,8 +1222,8 @@ packages: os: [linux] libc: [glibc] - '@oxlint/binding-linux-ppc64-gnu@1.70.0': - resolution: {integrity: sha512-J8VPG7I3/HmgaU4u8pNU2kFx2+0U+vPLS1dXFxXOaR/2TQ0f8AC7DRz0SRGRI1bfphnX2hVYTTtLuhL4nYKL+Q==} + '@oxlint/binding-linux-ppc64-gnu@1.71.0': + resolution: {integrity: sha512-cwl7VKGERIy9p+G+AvZdfy/06q0aHXaTt/mMRReC751iuNYJgqKjB7NydXSS30nBT9vtr2tunciOtrR4fD6FUA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] @@ -1221,8 +1236,8 @@ packages: os: [linux] libc: [glibc] - '@oxlint/binding-linux-riscv64-gnu@1.70.0': - resolution: {integrity: sha512-N2+4lV2KLN+oXTIIIwmWDhwkrnvqf5oX7Hw0zPjk+RuIVgiBQSOlJWF7uQoFx2siEYX0ZQ5cfSbEAHm+J3t7Wg==} + '@oxlint/binding-linux-riscv64-gnu@1.71.0': + resolution: {integrity: sha512-eZ8ieVXvzGi8jr7+ybQGPK2STw3mldfxZlgA2738iflfB/rzA69sE6m5rDRpQaxC7dpm745Enlh1Tod0QAk9Gg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] @@ -1235,8 +1250,8 @@ packages: os: [linux] libc: [musl] - '@oxlint/binding-linux-riscv64-musl@1.70.0': - resolution: {integrity: sha512-1e2L7cFCvx9QDzq6NPP+0tABKb5z6nWHyddWTNKprEsjO9xNrAtPowuCGpjNXxkTdsMiZ4jc8YQ5SstZd4XK6g==} + '@oxlint/binding-linux-riscv64-musl@1.71.0': + resolution: {integrity: sha512-puMDbQYe6+NXwfMusojoA7CXGn2b3utukmd23PQqc1E3XhVCwyZ+FueSMzDYeNgDV2dUfIVXAAKZBcFDeCL6sA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] @@ -1249,8 +1264,8 @@ packages: os: [linux] libc: [glibc] - '@oxlint/binding-linux-s390x-gnu@1.70.0': - resolution: {integrity: sha512-Kwu/l/8GcYibCWA9m9N5pRXMIKVSsL/YbgpLzYkqDhWTiqdRfnNJ/+nqIKRKQiFbHWsdlHEhzMwruJK+qcEruA==} + '@oxlint/binding-linux-s390x-gnu@1.71.0': + resolution: {integrity: sha512-4NJLxBs1ujISCt3L/1FcywLs73PWtJuw+piD6feK2V6h6OS6P7xu9/sWt1DTRLibe6QCzmfZzmM/2HPORoV/Lg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] @@ -1263,8 +1278,8 @@ packages: os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-gnu@1.70.0': - resolution: {integrity: sha512-tap04CsHYOl0nSAQJfPNIuBxqEPB2HnhQqwaOXLg1jnp2XfRo8Fa814dA4QC4zpvTWXCjAAaCY1W5LOORkEQuQ==} + '@oxlint/binding-linux-x64-gnu@1.71.0': + resolution: {integrity: sha512-cFDaiR8L3430qp88tfZnvFlt3KotFhR/DlbIL0nHOMMYiG/9Wy4l+6f7t8G8pTa9bd8Lt8+M0y/qjRQ/xcB74g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -1277,8 +1292,8 @@ packages: os: [linux] libc: [musl] - '@oxlint/binding-linux-x64-musl@1.70.0': - resolution: {integrity: sha512-hzJa/WgvtJpbBD9rgfy0qe+MjbxOXNUT0bfR1S6EQQzfTtBFA9xg5q8KSwRrQ2QfSS+TaP4j+4mVPQrfNc6UNg==} + '@oxlint/binding-linux-x64-musl@1.71.0': + resolution: {integrity: sha512-orfixdt76KlpNly9z0PkWBBNfwjKz+JFVLP/7wnVchlKNU9Dpt9InU/ZggeSej6fC7qwHmHNOGlhLnQXcYoGuA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -1290,8 +1305,8 @@ packages: cpu: [arm64] os: [openharmony] - '@oxlint/binding-openharmony-arm64@1.70.0': - resolution: {integrity: sha512-xbsaNSNzVSnaJACCUYr1HQMyY/Q/Q1LkePmHG3UvZPvGCYGNxrsZp9OmtA6ick8xH47ltRRbRrPCM1YXYcyC+A==} + '@oxlint/binding-openharmony-arm64@1.71.0': + resolution: {integrity: sha512-9emQu2lAp6yhPB3XuI+++vR+l/o6JR1X+EpxwcumPdQXBWXEPAsquPGL7l158EqU8SebQMXTUa/S5zN98juyHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -1302,8 +1317,8 @@ packages: cpu: [arm64] os: [win32] - '@oxlint/binding-win32-arm64-msvc@1.70.0': - resolution: {integrity: sha512-icAEsUI7JbW1TMRdEXV83mVAInhRVQYuuAlPpxdGwJ95chNdnCzjloRW8GglT0WvzOEZSio6fnYSk2DJ2Hv7LQ==} + '@oxlint/binding-win32-arm64-msvc@1.71.0': + resolution: {integrity: sha512-bd5kI8spYwTm3BILDtGhi73zoup5dw8MlPQNT8YB3BD5UIsjNe3K9/4ctrzQMX4SZMoK5HgzVLkLJzacEXB7fA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -1314,8 +1329,8 @@ packages: cpu: [ia32] os: [win32] - '@oxlint/binding-win32-ia32-msvc@1.70.0': - resolution: {integrity: sha512-FHMSWbVsPVs/f+Jcl04ws4JJ2wUnauyTzlpxWRG/lSO/8GpX08Fo2gQZqdA6CrRFI+zvkxl+N/KwJGWfUwYVZA==} + '@oxlint/binding-win32-ia32-msvc@1.71.0': + resolution: {integrity: sha512-W4HvOHGzVLHcrmFu+bMrJlho+/yrlX5ZNdJZqGe8MEldkQG+RHYhxxad9P4jvWAYFmIqUA5i9DQ8QsJqSU9GIw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] @@ -1326,8 +1341,8 @@ packages: cpu: [x64] os: [win32] - '@oxlint/binding-win32-x64-msvc@1.70.0': - resolution: {integrity: sha512-ptOlKwCz7n4AKs5VweMqG6DAg677FmKOK+vBkkL9DMNgFATIQ+upqUYBTOEwRQyRAx1ncGlPlXleV2hIcm3z4g==} + '@oxlint/binding-win32-x64-msvc@1.71.0': + resolution: {integrity: sha512-D2kyEIPHk/G/wiZLnwTVC/sVst+T/lKldVOjAFpgTIBUAOlry72e5OiapDbDBF4LfJLkN5ypJb/8Eu6yJzkveQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1348,97 +1363,97 @@ packages: resolution: {integrity: sha512-Cc7d8mSwvoV8gpeTQbE8dMPdeXIyO6w+yIhzgi3jY06i03WLNhb/6jIxNBNF1cVRI7ujnFQXZA66BbnBNTpBSw==} hasBin: true - '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + '@rolldown/binding-android-arm64@1.1.3': + resolution: {integrity: sha512-DT6Z3PhvioeHMvxo+xHc3KtqggrI7CCTXCmC2h/5zUlp5jVitv7XEy+9q5/7v8IolhlioawpMo8Kg0EEBy7J0g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + '@rolldown/binding-darwin-arm64@1.1.3': + resolution: {integrity: sha512-0NwgwsjM7LrsuVnXMK3koTpagBNOhloc/BNjKqZjv4V5zI5r13qx69uVhRx+o5Z0yy4Hzq+lpy7TAgUG/ocvrw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + '@rolldown/binding-darwin-x64@1.1.3': + resolution: {integrity: sha512-YtiBp4disu6V560loT6PjMdiRaWmVvDNrUunAalbiFx2ggeJwxdAsgZMcoGP17uyAsTwAj5V1niksxlHnVQ1Sw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + '@rolldown/binding-freebsd-x64@1.1.3': + resolution: {integrity: sha512-yD3EkEdXk2LypPxnf/kSZHirarsI8gcPzc62SukhR9VJTyvV+F9Q/GxWNuCojc7sXyuVC4DxRGhdDK4X8VSsbw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.3': + resolution: {integrity: sha512-c+8vieQbsD7HNAHKIA34w0GJ9FedFFuJGD+7E6vz7Q3uqAIugL5p45fhlsj4UaAsHpcmlqugBWMhA0/j7o0sIg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + '@rolldown/binding-linux-arm64-gnu@1.1.3': + resolution: {integrity: sha512-50jD0uUwLvur7Zz9LHz17kaAdTPjn5wN93hEgjvmYFRZwiR7ZJYovTd5ipyWJDAnXKvZ+wgc+/Ika6dwSF5OcA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + '@rolldown/binding-linux-arm64-musl@1.1.3': + resolution: {integrity: sha512-BO9+oPL8K9poZJBfYPsXNtYjPE5uM3qeehT3aFcW4LITOl+iSqhp0abzjR2nWBUNjIZeKXjAEWBZ64WjNoHd6w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + '@rolldown/binding-linux-ppc64-gnu@1.1.3': + resolution: {integrity: sha512-f3VpLB1vQ0Eo6ecr/6cekLnvYMFF4YBFoVGkfkvPLq1bAkbAwHYQPZKoAmG6OJyTcxxoC+AvezGx/S1obNC0Mw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + '@rolldown/binding-linux-s390x-gnu@1.1.3': + resolution: {integrity: sha512-AmurZ26Pqx/RI9N1gzEOCklkKXl927yjfXWUUS0O7Puh8ARM/Ob8qfrD3qnWksScdw6cSrW5PSHE9DyLu7+PtA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + '@rolldown/binding-linux-x64-gnu@1.1.3': + resolution: {integrity: sha512-JJpqs8bRGITDOdbkNKnlojzBabbOHrqjSvDr0IVsZObE1lBcPjxItUEY9eWIDbxaJ3cGrXPWGfGkIxFijg/URg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + '@rolldown/binding-linux-x64-musl@1.1.3': + resolution: {integrity: sha512-rSJcdjPxzA/by/6/rYs+v+bXU7UjvnbUWz8MJb6kh6+knqB1dCrtHg0uu7C/4haqJvqdkYHQ5IGn+tCH9GLW/g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + '@rolldown/binding-openharmony-arm64@1.1.3': + resolution: {integrity: sha512-hQ3/PYkDJICgevvyNcVrihVeqq7k1Pp3VZ9lY+dauAYUJKO+auqApvANhvR1An9BhmqYKvW2Mu1F9u4DXSMLxQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + '@rolldown/binding-wasm32-wasi@1.1.3': + resolution: {integrity: sha512-Elcv/BtML9lXrV6JuKITc/grN2kYV9gjsQpW8Jfw4ioK0TOkjBjye0nnyqQNy9STNaI20lXNaQBRrD5gSgR0Yg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + '@rolldown/binding-win32-arm64-msvc@1.1.3': + resolution: {integrity: sha512-2DrEfhluH9yhiaFApmsjsjwrSYbNcY1oFTzYSP1a535jDbV98zCFanA/96TBUd0iDFcxGmw9QRExwGCXz3U+/g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + '@rolldown/binding-win32-x64-msvc@1.1.3': + resolution: {integrity: sha512-OL4OMk7UPXOeVGGd3qo5zJyPIljf4AFgk5QAkPPS+OoLuOOozhuaQGC18MxVTnw/06q93gShAJzlwnSCY9YtqA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1472,6 +1487,9 @@ packages: rollup: optional: true + '@schedule-x/calendar-controls@4.6.0': + resolution: {integrity: sha512-+VVmJ4AhZkAqTsz/U6L6mftuohBXSdJ10/HFWoMrO5coaoj0K5MExCdcG7UkFK3ZmoPz03koO0RnqRt5FKyXsg==} + '@schedule-x/calendar@4.6.0': resolution: {integrity: sha512-8Rf5bUf0DVphJB2BaudtG4IHkw21wgMJiiuk5o+7SIOq6YH4hkVJo+Kk12pWSfp2KTZ9mnnUuLV+szBVhiEPlg==} peerDependencies: @@ -1501,12 +1519,12 @@ packages: resolution: {integrity: sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==} engines: {node: '>=14'} - '@sentry/core@10.59.0': - resolution: {integrity: sha512-QeG7XZL5j6CkToYCE7OwCerb/r742Tjj9p1BBohBKcypYTPRuqfD+A3FeUj7pk5CGO6Vj1/gOAmdbuuNbR51dQ==} + '@sentry/core@10.61.0': + resolution: {integrity: sha512-Edg8t2w45qEKiFnjeA6zRmU47R6la5FEMG+maZEOB2oTyJ+ujmh8LGaZ3G8aC0VdkKn8CXhHtDesze6oDc1oTA==} engines: {node: '>=18'} - '@sentry/node-core@10.59.0': - resolution: {integrity: sha512-qFbepzntYhDleNG9ZCZWCSoAJK0Nsx+UJxsuiygaaAf1rJMj95RVckLyslhY86pyDLVATNMmWm2elm6etgKaJw==} + '@sentry/node-core@10.61.0': + resolution: {integrity: sha512-aVSnYqaq5FXv9hX6lVGbg4gB+mVrb6QDoNE/IBq8OBR90TR9I/KU6KlWAcfB9H7I6CHnedldOpljkMAJ5eZ3qA==} engines: {node: '>=18'} peerDependencies: '@opentelemetry/api': ^1.9.0 @@ -1526,26 +1544,21 @@ packages: '@opentelemetry/sdk-trace-base': optional: true - '@sentry/node@10.59.0': - resolution: {integrity: sha512-qzqbP6OVoMijlDBUxWtbvVF5j73+vyzGFi+yFIslhVvzBj97TFkIeP3TpBLsmu/0L5ZvxpQCCEmzJ677tFkq/g==} + '@sentry/node@10.61.0': + resolution: {integrity: sha512-nct3VqOIuPBnsvqHHWkPG6Ta7QwJftxWXQzHt0+soNcWBoh5WU8hEzIPVEXzxTThJ9AOkF/df3ApWUX4i6ylqQ==} engines: {node: '>=18'} - '@sentry/opentelemetry@10.59.0': - resolution: {integrity: sha512-wV9/HR9btrNhSkJC2S0urqsD9pE4K0f6AmdfTK3qhH505mLoyV4ekTG66hdDR9xD2zOYCm58CNzaK+336zu3Gg==} + '@sentry/opentelemetry@10.61.0': + resolution: {integrity: sha512-wg8bY1sWPyFOVh59ThiFDeuyheD7DdQliqWmrCCa5q+PSRLij+zpmsGqjlzGU74lzj1Kvpkicw5LsO6U49b2xA==} engines: {node: '>=18'} peerDependencies: '@opentelemetry/api': ^1.9.0 '@opentelemetry/core': ^1.30.1 || ^2.1.0 '@opentelemetry/sdk-trace-base': ^1.30.1 || ^2.1.0 - '@sentry/server-utils@10.59.0': - resolution: {integrity: sha512-mR3fWaU7uGxIstRba6YO+/6V3qIa7432F7/U8EWHry+dY4C9DWAVG90E2GCzeD2MwLSP0tB25i8p1TWTGiQgVg==} + '@sentry/server-utils@10.61.0': + resolution: {integrity: sha512-IrOyMzlOyBkWtnVYb54sALf2f8WVqyyp7woRfHw8c3IMwUr5AskGOi7k2rjmUXO3Q0UkfHNVarexiEfo8ZqTsg==} engines: {node: '>=18'} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - vite: - optional: true '@sindresorhus/merge-streams@4.0.0': resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} @@ -1645,8 +1658,13 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 - '@tanstack/eslint-plugin-query@5.101.0': - resolution: {integrity: sha512-wsfg821y4yw21J7nKI2oM5yyGSz3vASXqgWbmWCXZpnyY9ObLrBCcXivwZKj4YHF2fUWiqoOIRX2pbE79cf6gQ==} + '@tanstack/devtools-event-client@0.4.4': + resolution: {integrity: sha512-6T5Yop/793YI+H+5J8Hsyj4kCih9sl4t3ElLgKioW5hk3ocn+ZdSJ94tT7vL7uabxSugWYBZlOTMPzEw2puvQw==} + engines: {node: '>=18'} + hasBin: true + + '@tanstack/eslint-plugin-query@5.101.1': + resolution: {integrity: sha512-gssErdsLIoeiJI6mbU1YTNlNxktj/Dt8r8QSXNxz8P4gBTnKl9xAPix84orbkIbd133ewAbqieRMZUQmxL+34w==} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: ^5.4.0 || ^6.0.0 @@ -1659,15 +1677,31 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + '@tanstack/form-core@1.33.0': + resolution: {integrity: sha512-AV4Pw9Dk4orFsuPBcDssfWMJFs+yMYBae7zZ4oTqrCf4ftNGQKxvrQRZeqKHG6A4TkiLeSvf2kzIjcVkrW7E6w==} + '@tanstack/history@1.162.0': resolution: {integrity: sha512-79pf/RkhteYZTRgcR4F9kbk84P2N8rugQJswxfIqovlbRiT3yI7eBE+5QorIrZaOKktsgzRlXh1l/du/xpl4iA==} engines: {node: '>=20.19'} - '@tanstack/query-core@5.101.0': - resolution: {integrity: sha512-cQetA74EB+seWySv1TTKr828TnP0u39m6LykwDXIo84SNortpDkp30TMEjkqtYCNP9c40uT/iwl6MLiufEt0Ow==} + '@tanstack/pacer-lite@0.1.1': + resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==} + engines: {node: '>=18'} + + '@tanstack/query-core@5.101.1': + resolution: {integrity: sha512-Y6Y92dkXtNqx67m2pMSxUsA3zOCwv862JexZRP8/EPwvKXMPu9m8rv43spiXWzOUIggQ3SQApttALStzhA8B4g==} - '@tanstack/react-query@5.101.0': - resolution: {integrity: sha512-rLlJXSpkqfizLWgkR5+eLeIk0MvTx/meEIR7LRjxic+qxiQP8zVjq7BqQkiCMNLQBlLfuOLqqr6KO5GtrDlmSg==} + '@tanstack/react-form@1.33.0': + resolution: {integrity: sha512-unaee+VS4MvKo+s1dmgGUXI4902VeAhuaUbKsQbhFe3MceOpB3JpAUGCDpyzjQPXVFkFY0COKfLrUNX2XZYW4g==} + peerDependencies: + '@tanstack/react-start': '*' + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@tanstack/react-start': + optional: true + + '@tanstack/react-query@5.101.1': + resolution: {integrity: sha512-ZnONUuQKJe1bJMStXUL1s5uKN9FcfC28j5cK+iDZcdSHtUv1wtin1cGc/Oewhf2Oc4eKY7lggtpvT/AbMmhHew==} peerDependencies: react: ^18 || ^19 @@ -1678,6 +1712,12 @@ packages: react: '>=18.0.0 || >=19.0.0' react-dom: '>=18.0.0 || >=19.0.0' + '@tanstack/react-store@0.11.0': + resolution: {integrity: sha512-tX4YXh3PDkmpvGQWkWqKpzs/MSqbtuwY9dWdWhtV9Q50PmO+jOkUKIWIX4G85dwt7lxdHLXsiaEKPdKmC8F41w==} + 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 + '@tanstack/react-store@0.9.3': resolution: {integrity: sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==} peerDependencies: @@ -1717,6 +1757,9 @@ packages: resolution: {integrity: sha512-hTWqJtqIFFdvuCl8WXNyrodp2L9zo2G37xKRrcVmVRWpAB2h+U1LuRAfS4tsFTiWOIoE/B+WDVFB8JpoEdw6jQ==} engines: {node: '>=20.19'} + '@tanstack/store@0.11.0': + resolution: {integrity: sha512-WlzzCt3xi0G6pCAJu1U+2jiECwabETDpQDi3hfkFZvJii9AuZqEKbOiVarX1/bWhTNjU486yQtJCCasi/0q+Cw==} + '@tanstack/store@0.9.3': resolution: {integrity: sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==} @@ -1727,8 +1770,8 @@ packages: '@ts-morph/common@0.27.0': resolution: {integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==} - '@tybys/wasm-util@0.10.2': - resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1765,63 +1808,63 @@ packages: '@types/validate-npm-package-name@4.0.2': resolution: {integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==} - '@typescript-eslint/eslint-plugin@8.61.1': - resolution: {integrity: sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==} + '@typescript-eslint/eslint-plugin@8.62.0': + resolution: {integrity: sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.61.1 + '@typescript-eslint/parser': ^8.62.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.61.1': - resolution: {integrity: sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==} + '@typescript-eslint/parser@8.62.0': + resolution: {integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.61.1': - resolution: {integrity: sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==} + '@typescript-eslint/project-service@8.62.0': + resolution: {integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.61.1': - resolution: {integrity: sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==} + '@typescript-eslint/scope-manager@8.62.0': + resolution: {integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.61.1': - resolution: {integrity: sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==} + '@typescript-eslint/tsconfig-utils@8.62.0': + resolution: {integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.61.1': - resolution: {integrity: sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==} + '@typescript-eslint/type-utils@8.62.0': + resolution: {integrity: sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.61.1': - resolution: {integrity: sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==} + '@typescript-eslint/types@8.62.0': + resolution: {integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.61.1': - resolution: {integrity: sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==} + '@typescript-eslint/typescript-estree@8.62.0': + resolution: {integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.61.1': - resolution: {integrity: sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==} + '@typescript-eslint/utils@8.62.0': + resolution: {integrity: sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.61.1': - resolution: {integrity: sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==} + '@typescript-eslint/visitor-keys@8.62.0': + resolution: {integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@valibot/to-json-schema@1.7.1': @@ -1829,8 +1872,8 @@ packages: peerDependencies: valibot: ^1.4.0 - '@vitejs/plugin-react@6.0.2': - resolution: {integrity: sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==} + '@vitejs/plugin-react@6.0.3': + resolution: {integrity: sha512-vmFvco5/QuC2f9Oj+wTk0+9XeDFkHxSamwZKYc7MxYwKICfvUvlMhqKI0VuICPltGqh1neqBKDvO4kes1ya8vg==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 @@ -1865,10 +1908,6 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} - agent-install@0.0.5: resolution: {integrity: sha512-nHlms9BkP8ZiY79HrwCGiA2DcNaXrAaJrCM/BEqQ7MEsSKyCk+2A76xPGylIfASZSZE0SaU3T0bNSg4rBPIJAQ==} hasBin: true @@ -1940,8 +1979,8 @@ packages: atomically@2.1.1: resolution: {integrity: sha512-P4w9o2dqARji6P7MHprklbfiArZAWvo07yW7qs3pdljb3BWr12FIB7W+p0zJiuiVsUpRO0iZn1kFFcpPegg0tQ==} - axios@1.18.0: - resolution: {integrity: sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw==} + axios@1.18.1: + resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} babel-dead-code-elimination@1.0.12: resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} @@ -1953,13 +1992,13 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - baseline-browser-mapping@2.10.38: - resolution: {integrity: sha512-31/02mVB4yuQU6adKk5SlY6m+mxDwUq5KZkyYgnLrrKl7TEm1+3PyDtDBz2kOv/wxZz41GHsvV1A/u6RmiyBvw==} + baseline-browser-mapping@2.10.40: + resolution: {integrity: sha512-BSSLZ9/Cjjv7Gtj5B68ZzXcXUg8iOf3fme+FCuh8rC/Go+Kmh8cox7M3A8dolou16s64QjLPOSdngh7GxXvkSw==} engines: {node: '>=6.0.0'} hasBin: true - bippy@0.5.41: - resolution: {integrity: sha512-jCP2pXXLhXqPrAN+iSEFZmLI4uUM4fjSqajh0K+TmM062VehfDT3ZJNkrTGyN701Z5XMejs9qAudSqkMGhSMKg==} + bippy@0.5.42: + resolution: {integrity: sha512-K3tpfO9uGQB2k/Vi5P6jgfrnXvO/FAQNUE2tqKjQmT0a93fJCysMGLgJmRKzYYfybAoOtwWwmKm0vw/uXE0hMw==} peerDependencies: react: '>=17.0.1' @@ -1975,8 +2014,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + browserslist@4.28.4: + resolution: {integrity: sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2124,10 +2163,6 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} - data-uri-to-buffer@4.0.1: - resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} - engines: {node: '>= 12'} - debounce-fn@4.0.0: resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} engines: {node: '>=10'} @@ -2214,8 +2249,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.376: - resolution: {integrity: sha512-cUVA7/RvbFTEuw/i3obUwDTRIXojaxkResf+ibByPFxjc6XK3VNtcQXV0NSbAlJ0FMjcJGgftVVB4Qo184EXvA==} + electron-to-chromium@1.5.379: + resolution: {integrity: sha512-v/qV5aV5EUA2pGilzUCq5/eyOloZAqDZBu9UMBIzgPpLlprjSR6zswsWBTv0KpqxLGUAZEwhO95ZCt7srymNVA==} embla-carousel-react@8.6.0: resolution: {integrity: sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==} @@ -2241,8 +2276,8 @@ packages: resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} - enhanced-resolve@5.24.0: - resolution: {integrity: sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==} + enhanced-resolve@5.24.1: + resolution: {integrity: sha512-7DdUaTjmNwMcH2gLr1qycesKII3BK4RLy/mdAb7x10Lq7bR4aNKHt1BR1ZALSv0rPM/hF5wYF0PhGop/rJm8vw==} engines: {node: '>=10.13.0'} enquirer@2.4.1: @@ -2303,10 +2338,10 @@ packages: oxlint: optional: true - eslint-plugin-oxlint@1.70.0: - resolution: {integrity: sha512-SmpX0KdQptEzGm98wEEUR2BFAQTCTyXVdxlMkTOetxRak4NWb6GsYtHvU+Xh9AvnOKBzmO0ikPjxEG30pkmNUg==} + eslint-plugin-oxlint@1.71.0: + resolution: {integrity: sha512-940aSzHoks+uIlVEoUGIXdtHmrs9ewoeN+r0CrSN4UnkoYIfy4lUPNp21JuwfzNrZ5NCBH3CBmG+ugS+2CXtsw==} peerDependencies: - oxlint: ~1.70.0 + oxlint: ~1.71.0 eslint-plugin-perfectionist@5.9.1: resolution: {integrity: sha512-30mHLNfEhzwaq5cquyWgnzrNXvT8AzwIwyeH5aj4U5ajhHSF2uiO6i09xpMDLv7koaZVTjLsvYF4m3gK/15tyA==} @@ -2314,8 +2349,8 @@ packages: peerDependencies: eslint: ^8.45.0 || ^9.0.0 || ^10.0.0 - eslint-plugin-react-dom@5.9.1: - resolution: {integrity: sha512-e0NpfKZOOvdTkYQEDJT7qLKoTX4jAjH8/qcCuOrp8zqX1LMKPrKgPe8DXGyXG5T+Bt4b81/ZQ/s3S2zkJLFuNg==} + eslint-plugin-react-dom@5.9.3: + resolution: {integrity: sha512-3+hPO6BkN47AbyEJbXaVS5B4aa9jJ8TGOL95mPYbCUfGhgRFqn5zkgvML4McOqI62WtldeqoE6MNLyOoCZSC2Q==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' @@ -2327,22 +2362,22 @@ packages: peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 - eslint-plugin-react-jsx@5.9.1: - resolution: {integrity: sha512-zzhCRbuXFiGMhvCrjpcwKsob0Gos8o7d28EnhGw28YapHXx1KYt0fzUDuWDoRZ2bhYhlDHzeU+l+jEgemPpaaw==} + eslint-plugin-react-jsx@5.9.3: + resolution: {integrity: sha512-4enKdwMXRp7jp3doa9yvPakgVHCSpyZZTF6UlzJIg78cpi6afYKArhOnJTthkMO6i6K2W7fDRfpKh9zknUhgaA==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - eslint-plugin-react-naming-convention@5.9.1: - resolution: {integrity: sha512-Ce1oAL4Et3RB+3akTSiFIZIYCexyG+oYrGYGKps0dky5iaRy8MUskh4EXcq4yI109IkBCVt52gtybmR3Te0lrQ==} + eslint-plugin-react-naming-convention@5.9.3: + resolution: {integrity: sha512-mCRlWRQm3kDzzKTPHQ2e/fLm021VKfGw0HQo953BIkkV146+cmGf2VERxunQH9qDzmuq4tf2KeVJggGYS3LXdA==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' typescript: '*' - eslint-plugin-react-x@5.9.1: - resolution: {integrity: sha512-0GwMpLdYx3HWMbDd1vqNr9VImkq34x/lQaLch2qDQmPOmi1DULL3yndl347wFhH4SbE6OUoJV2z0KCA72qnv5g==} + eslint-plugin-react-x@5.9.3: + resolution: {integrity: sha512-Dq29dj3Xbu/td2BX1oNtQy3vZsOkS4VJavFlvywTl0Mm1K5bF0FI6k+cIz5mSG95v6l0Biq55B5dr6bLqWcpMw==} engines: {node: '>=22.0.0'} peerDependencies: eslint: '*' @@ -2456,10 +2491,6 @@ packages: picomatch: optional: true - fetch-blob@3.2.0: - resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} - engines: {node: ^12.20 || >= 14.13} - figures@6.1.0: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} @@ -2504,10 +2535,6 @@ packages: resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} - formdata-polyfill@4.0.10: - resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} - engines: {node: '>=12.20.0'} - forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -2567,8 +2594,8 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - globals@17.6.0: - resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} + globals@17.7.0: + resolution: {integrity: sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==} engines: {node: '>=18'} gopd@1.2.0: @@ -2600,8 +2627,8 @@ packages: hermes-parser@0.25.1: resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} - hono@4.12.26: - resolution: {integrity: sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==} + hono@4.12.27: + resolution: {integrity: sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==} engines: {node: '>=16.9.0'} http-errors@2.0.1: @@ -2612,10 +2639,6 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} - human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -2640,8 +2663,8 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-in-the-middle@3.1.0: - resolution: {integrity: sha512-c0AeAV8VcwZzfYE7euTZY3H+VXUPMVugiovdosq80lqEXJmOekg3zGUAYg6KImHMaMuBoTUfTv7xNpUFdy0hJA==} + import-in-the-middle@3.2.0: + resolution: {integrity: sha512-vR2B6HKIhaBjcZr2bLpFiJ1VbzOlRQ7aby4/gw5WPIzToLjqpfWw3VJ4sk1uDchoOODEirvO2jyrSPtUSL5CrQ==} engines: {node: '>=18'} imurmurhash@0.1.4: @@ -2740,8 +2763,8 @@ packages: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} - isbot@5.1.43: - resolution: {integrity: sha512-drJhFmibra4LO6Wd7D3Oi6UICRK9244vSZkmxzhlZP0TTdwCA2ueK4PEkUkzPYeuqug9+cqqdWPgihjk5+83Cg==} + isbot@5.1.44: + resolution: {integrity: sha512-PGEHtwMnKbZpeSEXW2Utx+/JWed7dp6DiH0WWg33vGSDA7RUvpUeJSVlLrVkQ1RCpvDOUc/eH9ql7VsdbBZ8pA==} engines: {node: '>=18'} isexe@2.0.0: @@ -2995,8 +3018,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.14: - resolution: {integrity: sha512-U9kYi5bpVMEI31yC8iw4bJJp0avcHXA0W8/wNfLfnvJYzihQo2ZRPYPvpAAd570HAcCBjCTN7vnr+v4StKl1IQ==} + nanoid@3.3.15: + resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -3017,17 +3040,8 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - node-domexception@1.0.0: - resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} - engines: {node: '>=10.5.0'} - deprecated: Use your platform's native DOMException instead - - node-fetch@3.3.2: - resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - node-releases@2.0.48: - resolution: {integrity: sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==} + node-releases@2.0.50: + resolution: {integrity: sha512-J6l92tKHX6w8Jy5nO1Vuc01NoIiRGi/d6qBKVxh+IQ8Cr3b6HbVNfKiF8ZpFKufTwpwxMmce2W3iQZ861ZRyTg==} engines: {node: '>=18'} npm-run-path@4.0.1: @@ -3081,8 +3095,8 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} - ora@9.4.0: - resolution: {integrity: sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==} + ora@9.4.1: + resolution: {integrity: sha512-6VlU9MLXbjVQD04AZCMX28hVtA5bUoadvUqO76MUCVA0ilwJbMiHsITRPfyVm6p/BC0Av/BXMujx39WCe1LEqw==} engines: {node: '>=20'} oxc-parser@0.132.0: @@ -3127,8 +3141,8 @@ packages: oxlint-tsgolint: optional: true - oxlint@1.70.0: - resolution: {integrity: sha512-D6JgHtzkhRwvEC+A0Nw5AEc5bk8x5i1pHzvZIEf/a0C4hOzmAACNGtkDGPyFaxxX3ZVGxCPeig3P3rMM8XU3/g==} + oxlint@1.71.0: + resolution: {integrity: sha512-U1m1X+C0vDj7DC1e13IoZULzEcPczE7UOMTs8VlZGHUEIUaSTZKo5qkPsQEfzpgnQ29Pea/w3Xntk62UCecxZw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3235,8 +3249,8 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} - preact@10.29.2: - resolution: {integrity: sha512-7tNmwg/7mzzAoB/8kSg6Hl37JraAZw3Z3A0JSY7VXlZwo82Xn0G7wKbNNs2qoF4ZEEsQGTwDAroNdqKs1ofJxQ==} + preact@10.29.3: + resolution: {integrity: sha512-D9NL1GAnJZhc3RndVs4gDdxEeU9TcHgywMrhhOsnpdlvFjdbx0gAsLUnH6JEhlJH5giL7Tx5biWPUSEXE/HPzw==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -3267,15 +3281,15 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.15.2: - resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + qs@6.15.3: + resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} engines: {node: '>=0.6'} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} engines: {node: '>= 0.6'} raw-body@3.0.2: @@ -3347,8 +3361,8 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + rolldown@1.1.3: + resolution: {integrity: sha512-1F1eEtUBtFvcGm1HQ9TiUIUHPQG7mSAODrhIzjxoUEFuo8OcbrGLiVLkevNgj84TE4lnHvnumwFjhJO5Eu135g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -3402,8 +3416,9 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shadcn@4.11.0: - resolution: {integrity: sha512-UV0cchFea9hO7poV1CuEP0wvmYjpAqcxCKdy23bndl2Du2ARtDs8A4xdzfhUjDBeOW1nNpJ6lXmsEpsply2SfQ==} + shadcn@4.11.1: + resolution: {integrity: sha512-r3P4EWKQ+XDiwBGi7BdHKri3aGUK6mE1rdoSWS7ARU0wqsfzJNW2KBB+NEfg/LIpzThb+AoeQD2T01wORADXVQ==} + engines: {node: '>=20.18.1'} hasBin: true shebang-command@2.0.0: @@ -3515,8 +3530,8 @@ packages: resolution: {integrity: sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==} engines: {node: ^14.18.0 || >=16.0.0} - systeminformation@5.31.7: - resolution: {integrity: sha512-/8NC53e5nP9nmhn42/ncdOkyJnOoue/Vy+tJOyUGd1Yv66G069wK4rrziwhrqDETgk78CudTQupw5z19S5uoZw==} + systeminformation@5.31.11: + resolution: {integrity: sha512-I6O7iaUj23AXRgCPDDnvi3xHvdOLp4+1YMbF+X194lJwY1NeWojgHJPhslVKcmTtrLTguRk3QJK+xEdTiI3P0w==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true @@ -3614,8 +3629,8 @@ packages: resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} engines: {node: '>= 18'} - typescript-eslint@8.61.1: - resolution: {integrity: sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==} + typescript-eslint@8.62.0: + resolution: {integrity: sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3649,9 +3664,38 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unplugin@3.0.0: - resolution: {integrity: sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==} + unplugin@3.2.0: + resolution: {integrity: sha512-6nGlT7EHsS+tTcTdAkYFqXIUwDrMJyJvHFNYGSr4x2/2ySIcV4f5e1RAJUeDyfOJPR8TF0auE8l+82PLhKjqsA==} engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@farmfe/core': '*' + '@rspack/core': '*' + bun-types-no-globals: '*' + esbuild: '*' + rolldown: '*' + rollup: '*' + unloader: '*' + vite: '*' + webpack: '*' + peerDependenciesMeta: + '@farmfe/core': + optional: true + '@rspack/core': + optional: true + bun-types-no-globals: + optional: true + esbuild: + optional: true + rolldown: + optional: true + rollup: + optional: true + unloader: + optional: true + vite: + optional: true + webpack: + optional: true update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} @@ -3686,13 +3730,13 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - vite@8.0.16: - resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + vite@8.1.0: + resolution: {integrity: sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 + '@vitejs/devtools': ^0.3.0 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -3749,10 +3793,6 @@ packages: vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - web-streams-polyfill@3.3.3: - resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} - engines: {node: '>= 8'} - webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -3887,7 +3927,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.2 + browserslist: 4.28.4 lru-cache: 5.1.1 semver: 6.3.1 @@ -4068,7 +4108,7 @@ snapshots: object-treeify: 1.1.33 open: 8.4.2 picomatch: 4.0.4 - systeminformation: 5.31.7 + systeminformation: 5.31.11 undici: 7.28.0 which: 4.0.0 yocto-spinner: 1.2.0 @@ -4087,6 +4127,12 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.8.1 + optional: true + '@emnapi/runtime@1.10.0': dependencies: tslib: 2.8.1 @@ -4097,6 +4143,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 @@ -4114,59 +4165,59 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} - '@eslint-react/ast@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@eslint-react/ast@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) string-ts: 2.3.1 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@eslint-react/core@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@eslint-react/core@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/jsx': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/shared': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/var': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) ts-pattern: 5.9.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@eslint-react/eslint@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@eslint-react/eslint@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@eslint-react/jsx@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@eslint-react/jsx@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/shared': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/var': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) ts-pattern: 5.9.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@eslint-react/shared@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@eslint-react/shared@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) ts-pattern: 5.9.0 typescript: 6.0.3 @@ -4174,13 +4225,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint-react/var@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@eslint-react/var@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) ts-pattern: 5.9.0 typescript: 6.0.3 @@ -4234,9 +4285,9 @@ snapshots: '@fontsource-variable/raleway@5.2.8': {} - '@hono/node-server@1.19.14(hono@4.12.26)': + '@hono/node-server@1.19.14(hono@4.12.27)': dependencies: - hono: 4.12.26 + hono: 4.12.27 '@humanfs/core@0.19.2': dependencies: @@ -4281,7 +4332,7 @@ snapshots: '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)': dependencies: - '@hono/node-server': 1.19.14(hono@4.12.26) + '@hono/node-server': 1.19.14(hono@4.12.27) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) content-type: 1.0.5 @@ -4291,7 +4342,7 @@ snapshots: eventsource-parser: 3.1.0 express: 5.2.1 express-rate-limit: 8.5.2(express@5.2.1) - hono: 4.12.26 + hono: 4.12.27 jose: 6.2.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 @@ -4301,18 +4352,25 @@ snapshots: transitivePeerDependencies: - supports-color - '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 + '@tybys/wasm-util': 0.10.3 optional: true - '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)': + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)': dependencies: '@emnapi/core': 1.11.0 '@emnapi/runtime': 1.11.0 - '@tybys/wasm-util': 0.10.2 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.3 optional: true '@nodelib/fs.scandir@2.1.5': @@ -4342,7 +4400,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/api-logs': 0.214.0 - import-in-the-middle: 3.1.0 + import-in-the-middle: 3.2.0 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color @@ -4462,14 +4520,14 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@oxc-parser/binding-wasm32-wasi@0.135.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true '@oxc-parser/binding-win32-arm64-msvc@0.132.0': @@ -4492,10 +4550,10 @@ snapshots: '@oxc-project/types@0.132.0': {} - '@oxc-project/types@0.133.0': {} - '@oxc-project/types@0.135.0': {} + '@oxc-project/types@0.137.0': {} + '@oxc-resolver/binding-android-arm-eabi@11.21.3': optional: true @@ -4548,7 +4606,7 @@ snapshots: dependencies: '@emnapi/core': 1.11.0 '@emnapi/runtime': 1.11.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) optional: true '@oxc-resolver/binding-win32-arm64-msvc@11.21.3': @@ -4635,194 +4693,194 @@ snapshots: '@oxlint/binding-android-arm-eabi@1.66.0': optional: true - '@oxlint/binding-android-arm-eabi@1.70.0': + '@oxlint/binding-android-arm-eabi@1.71.0': optional: true '@oxlint/binding-android-arm64@1.66.0': optional: true - '@oxlint/binding-android-arm64@1.70.0': + '@oxlint/binding-android-arm64@1.71.0': optional: true '@oxlint/binding-darwin-arm64@1.66.0': optional: true - '@oxlint/binding-darwin-arm64@1.70.0': + '@oxlint/binding-darwin-arm64@1.71.0': optional: true '@oxlint/binding-darwin-x64@1.66.0': optional: true - '@oxlint/binding-darwin-x64@1.70.0': + '@oxlint/binding-darwin-x64@1.71.0': optional: true '@oxlint/binding-freebsd-x64@1.66.0': optional: true - '@oxlint/binding-freebsd-x64@1.70.0': + '@oxlint/binding-freebsd-x64@1.71.0': optional: true '@oxlint/binding-linux-arm-gnueabihf@1.66.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.70.0': + '@oxlint/binding-linux-arm-gnueabihf@1.71.0': optional: true '@oxlint/binding-linux-arm-musleabihf@1.66.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.70.0': + '@oxlint/binding-linux-arm-musleabihf@1.71.0': optional: true '@oxlint/binding-linux-arm64-gnu@1.66.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.70.0': + '@oxlint/binding-linux-arm64-gnu@1.71.0': optional: true '@oxlint/binding-linux-arm64-musl@1.66.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.70.0': + '@oxlint/binding-linux-arm64-musl@1.71.0': optional: true '@oxlint/binding-linux-ppc64-gnu@1.66.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.70.0': + '@oxlint/binding-linux-ppc64-gnu@1.71.0': optional: true '@oxlint/binding-linux-riscv64-gnu@1.66.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.70.0': + '@oxlint/binding-linux-riscv64-gnu@1.71.0': optional: true '@oxlint/binding-linux-riscv64-musl@1.66.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.70.0': + '@oxlint/binding-linux-riscv64-musl@1.71.0': optional: true '@oxlint/binding-linux-s390x-gnu@1.66.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.70.0': + '@oxlint/binding-linux-s390x-gnu@1.71.0': optional: true '@oxlint/binding-linux-x64-gnu@1.66.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.70.0': + '@oxlint/binding-linux-x64-gnu@1.71.0': optional: true '@oxlint/binding-linux-x64-musl@1.66.0': optional: true - '@oxlint/binding-linux-x64-musl@1.70.0': + '@oxlint/binding-linux-x64-musl@1.71.0': optional: true '@oxlint/binding-openharmony-arm64@1.66.0': optional: true - '@oxlint/binding-openharmony-arm64@1.70.0': + '@oxlint/binding-openharmony-arm64@1.71.0': optional: true '@oxlint/binding-win32-arm64-msvc@1.66.0': optional: true - '@oxlint/binding-win32-arm64-msvc@1.70.0': + '@oxlint/binding-win32-arm64-msvc@1.71.0': optional: true '@oxlint/binding-win32-ia32-msvc@1.66.0': optional: true - '@oxlint/binding-win32-ia32-msvc@1.70.0': + '@oxlint/binding-win32-ia32-msvc@1.71.0': optional: true '@oxlint/binding-win32-x64-msvc@1.66.0': optional: true - '@oxlint/binding-win32-x64-msvc@1.70.0': + '@oxlint/binding-win32-x64-msvc@1.71.0': optional: true '@pkgr/core@0.3.6': {} '@preact/signals-core@1.14.3': {} - '@preact/signals@2.9.2(preact@10.29.2)': + '@preact/signals@2.9.2(preact@10.29.3)': dependencies: '@preact/signals-core': 1.14.3 - preact: 10.29.2 + preact: 10.29.3 '@react-grab/cli@0.1.47': dependencies: agent-install: 0.0.6 commander: 14.0.3 ignore: 7.0.5 - ora: 9.4.0 + ora: 9.4.1 package-manager-detector: 1.6.0 picocolors: 1.1.1 prompts: 2.4.2 tinyexec: 1.2.4 - '@rolldown/binding-android-arm64@1.0.3': + '@rolldown/binding-android-arm64@1.1.3': optional: true - '@rolldown/binding-darwin-arm64@1.0.3': + '@rolldown/binding-darwin-arm64@1.1.3': optional: true - '@rolldown/binding-darwin-x64@1.0.3': + '@rolldown/binding-darwin-x64@1.1.3': optional: true - '@rolldown/binding-freebsd-x64@1.0.3': + '@rolldown/binding-freebsd-x64@1.1.3': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + '@rolldown/binding-linux-arm-gnueabihf@1.1.3': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.3': + '@rolldown/binding-linux-arm64-gnu@1.1.3': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.3': + '@rolldown/binding-linux-arm64-musl@1.1.3': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.3': + '@rolldown/binding-linux-ppc64-gnu@1.1.3': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.3': + '@rolldown/binding-linux-s390x-gnu@1.1.3': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.3': + '@rolldown/binding-linux-x64-gnu@1.1.3': optional: true - '@rolldown/binding-linux-x64-musl@1.0.3': + '@rolldown/binding-linux-x64-musl@1.1.3': optional: true - '@rolldown/binding-openharmony-arm64@1.0.3': + '@rolldown/binding-openharmony-arm64@1.1.3': optional: true - '@rolldown/binding-wasm32-wasi@1.0.3': + '@rolldown/binding-wasm32-wasi@1.1.3': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.3': + '@rolldown/binding-win32-arm64-msvc@1.1.3': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.3': + '@rolldown/binding-win32-x64-msvc@1.1.3': optional: true - '@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': + '@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 picomatch: 4.0.4 - rolldown: 1.0.3 + rolldown: 1.1.3 optionalDependencies: '@babel/runtime': 7.29.7 - vite: 8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) '@rolldown/pluginutils@1.0.1': {} @@ -4832,21 +4890,23 @@ snapshots: estree-walker: 2.0.2 picomatch: 4.0.4 - '@schedule-x/calendar@4.6.0(@preact/signals@2.9.2(preact@10.29.2))(preact@10.29.2)(temporal-polyfill@1.0.1)': + '@schedule-x/calendar-controls@4.6.0': {} + + '@schedule-x/calendar@4.6.0(@preact/signals@2.9.2(preact@10.29.3))(preact@10.29.3)(temporal-polyfill@1.0.1)': dependencies: - '@preact/signals': 2.9.2(preact@10.29.2) - preact: 10.29.2 + '@preact/signals': 2.9.2(preact@10.29.3) + preact: 10.29.3 temporal-polyfill: 1.0.1 - '@schedule-x/react@4.1.0(@schedule-x/calendar@4.6.0(@preact/signals@2.9.2(preact@10.29.2))(preact@10.29.2)(temporal-polyfill@1.0.1))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + '@schedule-x/react@4.1.0(@schedule-x/calendar@4.6.0(@preact/signals@2.9.2(preact@10.29.3))(preact@10.29.3)(temporal-polyfill@1.0.1))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@schedule-x/calendar': 4.6.0(@preact/signals@2.9.2(preact@10.29.2))(preact@10.29.2)(temporal-polyfill@1.0.1) + '@schedule-x/calendar': 4.6.0(@preact/signals@2.9.2(preact@10.29.3))(preact@10.29.3)(temporal-polyfill@1.0.1) react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - '@schedule-x/scroll-controller@4.6.0(@preact/signals@2.9.2(preact@10.29.2))': + '@schedule-x/scroll-controller@4.6.0(@preact/signals@2.9.2(preact@10.29.3))': dependencies: - '@preact/signals': 2.9.2(preact@10.29.2) + '@preact/signals': 2.9.2(preact@10.29.3) '@schedule-x/theme-shadcn@4.6.0': {} @@ -4854,55 +4914,52 @@ snapshots: '@sentry/conventions@0.12.0': {} - '@sentry/core@10.59.0': {} + '@sentry/core@10.61.0': {} - '@sentry/node-core@10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))': + '@sentry/node-core@10.61.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))': dependencies: '@sentry/conventions': 0.12.0 - '@sentry/core': 10.59.0 - '@sentry/opentelemetry': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1)) - import-in-the-middle: 3.1.0 + '@sentry/core': 10.61.0 + '@sentry/opentelemetry': 10.61.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1)) + import-in-the-middle: 3.2.0 optionalDependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.8.0(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.8.0(@opentelemetry/api@1.9.1) - '@sentry/node@10.59.0(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': + '@sentry/node@10.61.0(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core': 2.8.0(@opentelemetry/api@1.9.1) '@opentelemetry/instrumentation': 0.214.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.8.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': 1.41.1 - '@sentry/core': 10.59.0 - '@sentry/node-core': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1)) - '@sentry/opentelemetry': 10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1)) - '@sentry/server-utils': 10.59.0(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) - import-in-the-middle: 3.1.0 + '@sentry/core': 10.61.0 + '@sentry/node-core': 10.61.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/instrumentation@0.214.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1)) + '@sentry/opentelemetry': 10.61.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1)) + '@sentry/server-utils': 10.61.0 + import-in-the-middle: 3.2.0 transitivePeerDependencies: + - '@opentelemetry/core' - '@opentelemetry/exporter-trace-otlp-http' - supports-color - - vite - '@sentry/opentelemetry@10.59.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))': + '@sentry/opentelemetry@10.61.0(@opentelemetry/api@1.9.1)(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(@opentelemetry/sdk-trace-base@2.8.0(@opentelemetry/api@1.9.1))': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/core': 2.8.0(@opentelemetry/api@1.9.1) '@opentelemetry/sdk-trace-base': 2.8.0(@opentelemetry/api@1.9.1) '@sentry/conventions': 0.12.0 - '@sentry/core': 10.59.0 + '@sentry/core': 10.61.0 - '@sentry/server-utils@10.59.0(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': + '@sentry/server-utils@10.61.0': dependencies: '@apm-js-collab/code-transformer': 0.15.0 '@apm-js-collab/code-transformer-bundler-plugins': 0.5.0 '@apm-js-collab/tracing-hooks': 0.10.0 '@sentry/conventions': 0.12.0 - '@sentry/core': 10.59.0 + '@sentry/core': 10.61.0 magic-string: 0.30.21 - optionalDependencies: - vite: 8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) transitivePeerDependencies: - supports-color @@ -4969,16 +5026,18 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.1 '@tailwindcss/oxide-win32-x64-msvc': 4.3.1 - '@tailwindcss/vite@4.3.1(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': + '@tailwindcss/vite@4.3.1(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.3.1 '@tailwindcss/oxide': 4.3.1 tailwindcss: 4.3.1 - vite: 8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) - '@tanstack/eslint-plugin-query@5.101.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@tanstack/devtools-event-client@0.4.4': {} + + '@tanstack/eslint-plugin-query@5.101.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) optionalDependencies: typescript: 6.0.3 @@ -4987,19 +5046,35 @@ snapshots: '@tanstack/eslint-plugin-router@1.162.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) transitivePeerDependencies: - supports-color - typescript + '@tanstack/form-core@1.33.0': + dependencies: + '@tanstack/devtools-event-client': 0.4.4 + '@tanstack/pacer-lite': 0.1.1 + '@tanstack/store': 0.11.0 + '@tanstack/history@1.162.0': {} - '@tanstack/query-core@5.101.0': {} + '@tanstack/pacer-lite@0.1.1': {} + + '@tanstack/query-core@5.101.1': {} - '@tanstack/react-query@5.101.0(react@19.2.7)': + '@tanstack/react-form@1.33.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@tanstack/query-core': 5.101.0 + '@tanstack/form-core': 1.33.0 + '@tanstack/react-store': 0.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 + transitivePeerDependencies: + - react-dom + + '@tanstack/react-query@5.101.1(react@19.2.7)': + dependencies: + '@tanstack/query-core': 5.101.1 react: 19.2.7 '@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': @@ -5007,10 +5082,17 @@ snapshots: '@tanstack/history': 1.162.0 '@tanstack/react-store': 0.9.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@tanstack/router-core': 1.171.13 - isbot: 5.1.43 + isbot: 5.1.44 react: 19.2.7 react-dom: 19.2.7(react@19.2.7) + '@tanstack/react-store@0.11.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': + dependencies: + '@tanstack/store': 0.11.0 + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + use-sync-external-store: 1.6.0(react@19.2.7) + '@tanstack/react-store@0.9.3(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@tanstack/store': 0.9.3 @@ -5038,7 +5120,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': + '@tanstack/router-plugin@1.168.18(@tanstack/react-router@1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 '@babel/template': 7.29.7 @@ -5047,13 +5129,20 @@ snapshots: '@tanstack/router-generator': 1.167.17 '@tanstack/router-utils': 1.162.2 chokidar: 5.0.0 - unplugin: 3.0.0 + unplugin: 3.2.0(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) zod: 4.4.3 optionalDependencies: '@tanstack/react-router': 1.170.16(react-dom@19.2.7(react@19.2.7))(react@19.2.7) - vite: 8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) transitivePeerDependencies: + - '@farmfe/core' + - '@rspack/core' + - bun-types-no-globals + - esbuild + - rolldown + - rollup - supports-color + - unloader '@tanstack/router-utils@1.162.2': dependencies: @@ -5068,6 +5157,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@tanstack/store@0.11.0': {} + '@tanstack/store@0.9.3': {} '@tanstack/virtual-file-routes@1.162.0': {} @@ -5078,7 +5169,7 @@ snapshots: minimatch: 10.2.5 path-browserify: 1.0.1 - '@tybys/wasm-util@0.10.2': + '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 optional: true @@ -5124,14 +5215,14 @@ snapshots: '@types/validate-npm-package-name@4.0.2': {} - '@typescript-eslint/eslint-plugin@8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/type-utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/parser': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/type-utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.62.0 eslint: 10.5.0(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 @@ -5140,41 +5231,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.62.0 debug: 4.4.3 eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.61.1(typescript@6.0.3)': + '@typescript-eslint/project-service@8.62.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.61.1': + '@typescript-eslint/scope-manager@8.62.0': dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/visitor-keys': 8.62.0 - '@typescript-eslint/tsconfig-utils@8.61.1(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.62.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3 eslint: 10.5.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) @@ -5182,14 +5273,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.61.1': {} + '@typescript-eslint/types@8.62.0': {} - '@typescript-eslint/typescript-estree@8.61.1(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.62.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.61.1(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.61.1(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/visitor-keys': 8.61.1 + '@typescript-eslint/project-service': 8.62.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/visitor-keys': 8.62.0 debug: 4.4.3 minimatch: 10.2.5 semver: 7.8.5 @@ -5199,32 +5290,32 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.61.1': + '@typescript-eslint/visitor-keys@8.62.0': dependencies: - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/types': 8.62.0 eslint-visitor-keys: 5.0.1 '@valibot/to-json-schema@1.7.1(valibot@1.4.1(typescript@6.0.3))': dependencies: valibot: 1.4.1(typescript@6.0.3) - '@vitejs/plugin-react@6.0.2(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': + '@vitejs/plugin-react@6.0.3(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) optionalDependencies: - '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.0.3)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) babel-plugin-react-compiler: 1.0.0 accepts@2.0.0: @@ -5248,8 +5339,6 @@ snapshots: transitivePeerDependencies: - supports-color - agent-base@7.1.4: {} - agent-install@0.0.5: dependencies: '@iarna/toml': 2.2.5 @@ -5319,7 +5408,7 @@ snapshots: stubborn-fs: 2.0.0 when-exit: 2.1.5 - axios@1.18.0: + axios@1.18.1: dependencies: follow-redirects: 1.16.0 form-data: 4.0.6 @@ -5344,9 +5433,9 @@ snapshots: balanced-match@4.0.4: {} - baseline-browser-mapping@2.10.38: {} + baseline-browser-mapping@2.10.40: {} - bippy@0.5.41(react@19.2.7): + bippy@0.5.42(react@19.2.7): dependencies: react: 19.2.7 @@ -5358,7 +5447,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.15.2 + qs: 6.15.3 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -5372,13 +5461,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.2: + browserslist@4.28.4: dependencies: - baseline-browser-mapping: 2.10.38 + baseline-browser-mapping: 2.10.40 caniuse-lite: 1.0.30001799 - electron-to-chromium: 1.5.376 - node-releases: 2.0.48 - update-browserslist-db: 1.2.3(browserslist@4.28.2) + electron-to-chromium: 1.5.379 + node-releases: 2.0.50 + update-browserslist-db: 1.2.3(browserslist@4.28.4) bundle-name@4.1.0: dependencies: @@ -5510,8 +5599,6 @@ snapshots: csstype@3.2.3: {} - data-uri-to-buffer@4.0.1: {} - debounce-fn@4.0.0: dependencies: mimic-fn: 3.1.0 @@ -5576,7 +5663,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.376: {} + electron-to-chromium@1.5.379: {} embla-carousel-react@8.6.0(react@19.2.7): dependencies: @@ -5599,7 +5686,7 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.3 - enhanced-resolve@5.24.0: + enhanced-resolve@5.24.1: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -5640,11 +5727,11 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-plugin-better-tailwindcss@4.6.0(eslint@10.5.0(jiti@2.7.0))(oxlint@1.70.0(oxlint-tsgolint@0.23.0))(tailwindcss@4.3.1)(typescript@6.0.3): + eslint-plugin-better-tailwindcss@4.6.0(eslint@10.5.0(jiti@2.7.0))(oxlint@1.71.0(oxlint-tsgolint@0.23.0))(tailwindcss@4.3.1)(typescript@6.0.3): dependencies: '@eslint/css-tree': 4.0.4 '@valibot/to-json-schema': 1.7.1(valibot@1.4.1(typescript@6.0.3)) - enhanced-resolve: 5.24.0 + enhanced-resolve: 5.24.1 jiti: 2.7.0 synckit: 0.11.13 tailwind-csstree: 0.3.3 @@ -5653,33 +5740,33 @@ snapshots: valibot: 1.4.1(typescript@6.0.3) optionalDependencies: eslint: 10.5.0(jiti@2.7.0) - oxlint: 1.70.0(oxlint-tsgolint@0.23.0) + oxlint: 1.71.0(oxlint-tsgolint@0.23.0) transitivePeerDependencies: - '@eslint/css' - typescript - eslint-plugin-oxlint@1.70.0(oxlint@1.70.0(oxlint-tsgolint@0.23.0)): + eslint-plugin-oxlint@1.71.0(oxlint@1.71.0(oxlint-tsgolint@0.23.0)): dependencies: jsonc-parser: 3.3.1 - oxlint: 1.70.0(oxlint-tsgolint@0.23.0) + oxlint: 1.71.0(oxlint-tsgolint@0.23.0) eslint-plugin-perfectionist@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) natural-orderby: 5.0.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-react-dom@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + eslint-plugin-react-dom@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/jsx': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/shared': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) compare-versions: 6.1.1 eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 @@ -5697,47 +5784,47 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-jsx@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + eslint-plugin-react-jsx@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/core': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/jsx': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/shared': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/core': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - eslint-plugin-react-naming-convention@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + eslint-plugin-react-naming-convention@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/core': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/var': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/core': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) ts-pattern: 5.9.0 typescript: 6.0.3 transitivePeerDependencies: - supports-color - eslint-plugin-react-x@5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): - dependencies: - '@eslint-react/ast': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/core': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/eslint': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/jsx': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/shared': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@eslint-react/var': 5.9.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.61.1 - '@typescript-eslint/type-utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/types': 8.61.1 - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + eslint-plugin-react-x@5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + dependencies: + '@eslint-react/ast': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/core': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.3(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.62.0 + '@typescript-eslint/type-utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.62.0 + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) compare-versions: 6.1.1 eslint: 10.5.0(jiti@2.7.0) string-ts: 2.3.1 @@ -5879,8 +5966,8 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.2 - range-parser: 1.2.1 + qs: 6.15.3 + range-parser: 1.3.0 router: 2.2.0 send: 1.2.1 serve-static: 2.2.1 @@ -5914,11 +6001,6 @@ snapshots: optionalDependencies: picomatch: 4.0.4 - fetch-blob@3.2.0: - dependencies: - node-domexception: 1.0.0 - web-streams-polyfill: 3.3.3 - figures@6.1.0: dependencies: is-unicode-supported: 2.1.0 @@ -5968,10 +6050,6 @@ snapshots: hasown: 2.0.4 mime-types: 2.1.35 - formdata-polyfill@4.0.10: - dependencies: - fetch-blob: 3.2.0 - forwarded@0.2.0: {} fresh@2.0.0: {} @@ -6028,7 +6106,7 @@ snapshots: dependencies: is-glob: 4.0.3 - globals@17.6.0: {} + globals@17.7.0: {} gopd@1.2.0: {} @@ -6052,7 +6130,7 @@ snapshots: dependencies: hermes-estree: 0.25.1 - hono@4.12.26: {} + hono@4.12.27: {} http-errors@2.0.1: dependencies: @@ -6069,13 +6147,6 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.6: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - human-signals@2.1.0: {} human-signals@8.0.1: {} @@ -6093,7 +6164,7 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-in-the-middle@3.1.0: + import-in-the-middle@3.2.0: dependencies: acorn: 8.17.0 acorn-import-attributes: 1.9.5(acorn@8.17.0) @@ -6156,7 +6227,7 @@ snapshots: dependencies: is-inside-container: 1.0.0 - isbot@5.1.43: {} + isbot@5.1.44: {} isexe@2.0.0: {} @@ -6346,7 +6417,7 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.14: {} + nanoid@3.3.15: {} natural-compare@1.4.0: {} @@ -6359,15 +6430,7 @@ snapshots: react: 19.2.7 react-dom: 19.2.7(react@19.2.7) - node-domexception@1.0.0: {} - - node-fetch@3.3.2: - dependencies: - data-uri-to-buffer: 4.0.1 - fetch-blob: 3.2.0 - formdata-polyfill: 4.0.10 - - node-releases@2.0.48: {} + node-releases@2.0.50: {} npm-run-path@4.0.1: dependencies: @@ -6436,7 +6499,7 @@ snapshots: string-width: 7.2.0 strip-ansi: 7.2.0 - ora@9.4.0: + ora@9.4.1: dependencies: chalk: 5.6.2 cli-cursor: 5.0.0 @@ -6545,7 +6608,7 @@ snapshots: oxlint-plugin-react-doctor@0.5.8: dependencies: - '@typescript-eslint/types': 8.61.1 + '@typescript-eslint/types': 8.62.0 eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 oxc-parser: 0.135.0 @@ -6582,27 +6645,27 @@ snapshots: '@oxlint/binding-win32-x64-msvc': 1.66.0 oxlint-tsgolint: 0.23.0 - oxlint@1.70.0(oxlint-tsgolint@0.23.0): + oxlint@1.71.0(oxlint-tsgolint@0.23.0): optionalDependencies: - '@oxlint/binding-android-arm-eabi': 1.70.0 - '@oxlint/binding-android-arm64': 1.70.0 - '@oxlint/binding-darwin-arm64': 1.70.0 - '@oxlint/binding-darwin-x64': 1.70.0 - '@oxlint/binding-freebsd-x64': 1.70.0 - '@oxlint/binding-linux-arm-gnueabihf': 1.70.0 - '@oxlint/binding-linux-arm-musleabihf': 1.70.0 - '@oxlint/binding-linux-arm64-gnu': 1.70.0 - '@oxlint/binding-linux-arm64-musl': 1.70.0 - '@oxlint/binding-linux-ppc64-gnu': 1.70.0 - '@oxlint/binding-linux-riscv64-gnu': 1.70.0 - '@oxlint/binding-linux-riscv64-musl': 1.70.0 - '@oxlint/binding-linux-s390x-gnu': 1.70.0 - '@oxlint/binding-linux-x64-gnu': 1.70.0 - '@oxlint/binding-linux-x64-musl': 1.70.0 - '@oxlint/binding-openharmony-arm64': 1.70.0 - '@oxlint/binding-win32-arm64-msvc': 1.70.0 - '@oxlint/binding-win32-ia32-msvc': 1.70.0 - '@oxlint/binding-win32-x64-msvc': 1.70.0 + '@oxlint/binding-android-arm-eabi': 1.71.0 + '@oxlint/binding-android-arm64': 1.71.0 + '@oxlint/binding-darwin-arm64': 1.71.0 + '@oxlint/binding-darwin-x64': 1.71.0 + '@oxlint/binding-freebsd-x64': 1.71.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.71.0 + '@oxlint/binding-linux-arm-musleabihf': 1.71.0 + '@oxlint/binding-linux-arm64-gnu': 1.71.0 + '@oxlint/binding-linux-arm64-musl': 1.71.0 + '@oxlint/binding-linux-ppc64-gnu': 1.71.0 + '@oxlint/binding-linux-riscv64-gnu': 1.71.0 + '@oxlint/binding-linux-riscv64-musl': 1.71.0 + '@oxlint/binding-linux-s390x-gnu': 1.71.0 + '@oxlint/binding-linux-x64-gnu': 1.71.0 + '@oxlint/binding-linux-x64-musl': 1.71.0 + '@oxlint/binding-openharmony-arm64': 1.71.0 + '@oxlint/binding-win32-arm64-msvc': 1.71.0 + '@oxlint/binding-win32-ia32-msvc': 1.71.0 + '@oxlint/binding-win32-x64-msvc': 1.71.0 oxlint-tsgolint: 0.23.0 p-limit@2.3.0: @@ -6673,13 +6736,13 @@ snapshots: postcss@8.5.15: dependencies: - nanoid: 3.3.14 + nanoid: 3.3.15 picocolors: 1.1.1 source-map-js: 1.2.1 powershell-utils@0.1.0: {} - preact@10.29.2: {} + preact@10.29.3: {} prelude-ls@1.2.1: {} @@ -6703,13 +6766,14 @@ snapshots: punycode@2.3.1: {} - qs@6.15.2: + qs@6.15.3: dependencies: + es-define-property: 1.0.1 side-channel: 1.1.1 queue-microtask@1.2.3: {} - range-parser@1.2.1: {} + range-parser@1.3.0: {} raw-body@3.0.2: dependencies: @@ -6718,10 +6782,10 @@ snapshots: iconv-lite: 0.7.2 unpipe: 1.0.0 - react-doctor@0.5.8(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)): + react-doctor@0.5.8(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0): dependencies: '@babel/code-frame': 7.29.7 - '@sentry/node': 10.59.0(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + '@sentry/node': 10.61.0(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1)) agent-install: 0.0.5 conf: 15.1.0 confbox: 0.2.4 @@ -6737,11 +6801,11 @@ snapshots: vscode-languageserver-textdocument: 1.0.12 vscode-uri: 3.1.0 transitivePeerDependencies: + - '@opentelemetry/core' - '@opentelemetry/exporter-trace-otlp-http' - eslint - oxlint-tsgolint - supports-color - - vite react-dom@19.2.7(react@19.2.7): dependencies: @@ -6751,34 +6815,41 @@ snapshots: react-grab@0.1.47(react@19.2.7): dependencies: '@react-grab/cli': 0.1.47 - bippy: 0.5.41(react@19.2.7) + bippy: 0.5.42(react@19.2.7) optionalDependencies: react: 19.2.7 - react-scan@0.5.7(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)): + react-scan@0.5.7(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)): dependencies: '@babel/core': 7.29.7 '@babel/types': 7.29.7 - '@preact/signals': 2.9.2(preact@10.29.2) + '@preact/signals': 2.9.2(preact@10.29.3) '@rollup/pluginutils': 5.4.0 - bippy: 0.5.41(react@19.2.7) + bippy: 0.5.42(react@19.2.7) commander: 14.0.3 picocolors: 1.1.1 - preact: 10.29.2 + preact: 10.29.3 prompts: 2.4.2 react: 19.2.7 - react-doctor: 0.5.8(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0)(vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) + react-doctor: 0.5.8(@opentelemetry/core@2.8.0(@opentelemetry/api@1.9.1))(eslint@10.5.0(jiti@2.7.0))(oxlint-tsgolint@0.23.0) react-dom: 19.2.7(react@19.2.7) react-grab: 0.1.47(react@19.2.7) optionalDependencies: - unplugin: 3.0.0 + unplugin: 3.2.0(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)) transitivePeerDependencies: + - '@farmfe/core' + - '@opentelemetry/core' - '@opentelemetry/exporter-trace-otlp-http' + - '@rspack/core' + - bun-types-no-globals - eslint - oxlint-tsgolint + - rolldown - rollup - supports-color + - unloader - vite + - webpack react@19.2.7: {} @@ -6812,26 +6883,26 @@ snapshots: reusify@1.1.0: {} - rolldown@1.0.3: + rolldown@1.1.3: dependencies: - '@oxc-project/types': 0.133.0 + '@oxc-project/types': 0.137.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 + '@rolldown/binding-android-arm64': 1.1.3 + '@rolldown/binding-darwin-arm64': 1.1.3 + '@rolldown/binding-darwin-x64': 1.1.3 + '@rolldown/binding-freebsd-x64': 1.1.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.3 + '@rolldown/binding-linux-arm64-gnu': 1.1.3 + '@rolldown/binding-linux-arm64-musl': 1.1.3 + '@rolldown/binding-linux-ppc64-gnu': 1.1.3 + '@rolldown/binding-linux-s390x-gnu': 1.1.3 + '@rolldown/binding-linux-x64-gnu': 1.1.3 + '@rolldown/binding-linux-x64-musl': 1.1.3 + '@rolldown/binding-openharmony-arm64': 1.1.3 + '@rolldown/binding-wasm32-wasi': 1.1.3 + '@rolldown/binding-win32-arm64-msvc': 1.1.3 + '@rolldown/binding-win32-x64-msvc': 1.1.3 router@2.2.0: dependencies: @@ -6870,7 +6941,7 @@ snapshots: mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 - range-parser: 1.2.1 + range-parser: 1.3.0 statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -6892,7 +6963,7 @@ snapshots: setprototypeof@1.2.0: {} - shadcn@4.11.0(typescript@6.0.3): + shadcn@4.11.1(typescript@6.0.3): dependencies: '@babel/core': 7.29.7 '@babel/parser': 7.29.7 @@ -6901,7 +6972,7 @@ snapshots: '@dotenvx/dotenvx': 1.75.1 '@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76) '@types/validate-npm-package-name': 4.0.2 - browserslist: 4.28.2 + browserslist: 4.28.4 commander: 14.0.3 cosmiconfig: 9.0.2(typescript@6.0.3) dedent: 1.7.2 @@ -6911,9 +6982,7 @@ snapshots: fast-glob: 3.3.3 fs-extra: 11.3.5 fuzzysort: 3.1.0 - https-proxy-agent: 7.0.6 kleur: 4.1.5 - node-fetch: 3.3.2 open: 11.0.0 ora: 8.2.0 postcss: 8.5.15 @@ -6924,6 +6993,7 @@ snapshots: tailwind-merge: 3.6.0 ts-morph: 26.0.0 tsconfig-paths: 4.2.0 + undici: 7.28.0 validate-npm-package-name: 7.0.2 zod: 3.25.76 zod-to-json-schema: 3.25.2(zod@3.25.76) @@ -7035,7 +7105,7 @@ snapshots: dependencies: '@pkgr/core': 0.3.6 - systeminformation@5.31.7: {} + systeminformation@5.31.11: {} tagged-tag@1.0.0: {} @@ -7087,7 +7157,7 @@ snapshots: tsconfig-paths-webpack-plugin@4.2.0: dependencies: chalk: 4.1.2 - enhanced-resolve: 5.24.0 + enhanced-resolve: 5.24.1 tapable: 2.3.3 tsconfig-paths: 4.2.0 @@ -7115,12 +7185,12 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 - typescript-eslint@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): + typescript-eslint@8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.61.1(@typescript-eslint/parser@8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/parser': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.61.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.1(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/eslint-plugin': 8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.62.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: @@ -7140,15 +7210,18 @@ snapshots: unpipe@1.0.0: {} - unplugin@3.0.0: + unplugin@3.2.0(rolldown@1.1.3)(vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0)): dependencies: '@jridgewell/remapping': 2.3.5 picomatch: 4.0.4 webpack-virtual-modules: 0.6.2 + optionalDependencies: + rolldown: 1.1.3 + vite: 8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0) - update-browserslist-db@1.2.3(browserslist@4.28.2): + update-browserslist-db@1.2.3(browserslist@4.28.4): dependencies: - browserslist: 4.28.2 + browserslist: 4.28.4 escalade: 3.2.0 picocolors: 1.1.1 @@ -7170,12 +7243,12 @@ snapshots: vary@1.1.2: {} - vite@8.0.16(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0): + vite@8.1.0(@types/node@25.9.4)(jiti@2.7.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 postcss: 8.5.15 - rolldown: 1.0.3 + rolldown: 1.1.3 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 25.9.4 @@ -7200,8 +7273,6 @@ snapshots: vscode-uri@3.1.0: {} - web-streams-polyfill@3.3.3: {} - webpack-virtual-modules@0.6.2: {} when-exit@2.1.5: {} diff --git a/src/components/app/check-in-dialog.tsx b/src/components/app/check-in-dialog.tsx new file mode 100644 index 00000000..dd6fa13a --- /dev/null +++ b/src/components/app/check-in-dialog.tsx @@ -0,0 +1,214 @@ +import { useForm } from "@tanstack/react-form"; +import { useMutation } from "@tanstack/react-query"; +import axios from "axios"; +import { type LucideIcon, Check, Clock, Lock, QrCode } from "lucide-react"; +import { type ChangeEvent, type SyntheticEvent, useCallback } from "react"; +import { toast } from "sonner"; +import { z } from "zod"; + +import { EmptyState, PILL_CLASS } from "@/components/app/dashboard-events"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { type CheckInState, determineCheckIn, type DashboardEvent } from "@/lib/dashboard-events"; +import { cn } from "@/lib/utils"; + +/// Constants + +const API_BASE_URL = + (import.meta.env.VITE_API_URL as string | undefined) || "http://localhost:8000"; + +const STATUS_GREEN = "text-[#15a66e] bg-[#15a66e]/15 dark:text-[#3fd68c] dark:bg-[#3fd68c]/15"; +const STATUS_MUTED = "text-muted-foreground bg-muted"; + +const CHECKIN_WINDOW = { + too_early: { label: "Opens 1 hour before start", className: STATUS_MUTED, icon: Clock }, + open: { label: "Check-in open", className: STATUS_GREEN, icon: Clock }, + ended: { label: "Check-in closed", className: STATUS_MUTED, icon: Lock }, +} satisfies Record; + +const CHECKIN_EMPTY = { + too_early: { + icon: Clock, + title: "Check-in hasn't opened yet", + sub: "Check-in opens one hour before the event starts.", + }, + ended: { + icon: Lock, + title: "Check-in has closed", + sub: "The window runs until the event ends.", + }, +} satisfies Partial>; + +const checkInSchema = z.object({ + code: z + .string() + .regex(/^[A-Z0-9]*$/, "Letters and numbers only") + .length(8, "Enter all 8 characters"), +}); + +/// Component + +interface CheckInDialogProps { + event: DashboardEvent; + now: Date; + open: boolean; + onOpenChange: (open: boolean) => void; + onVerified?: () => unknown; +} + +export function CheckInDialog({ + event, + now, + open, + onOpenChange, + onVerified, +}: Readonly) { + const { mutate, reset, isError, isPending, isSuccess } = useMutation({ + mutationFn: async (code: string) => { + const { data } = await axios.post<{ message: string }>( + `${API_BASE_URL}/events/${event.id}/verify`, + { code }, + ); + return data; + }, + onSuccess: () => { + toast.success(`You're checked in to ${event.name}.`); + return onVerified?.(); + }, + }); + + const form = useForm({ + defaultValues: { code: "" }, + validators: { onChange: checkInSchema }, + onSubmit: ({ value }) => { + mutate(value.code); + }, + }); + + const handleOpenChange = useCallback( + (next: boolean) => { + if (!next) { + form.reset(); + reset(); + } + onOpenChange(next); + }, + [form, onOpenChange, reset], + ); + const handleSubmit = useCallback( + (event: SyntheticEvent) => { + event.preventDefault(); + void form.handleSubmit(); + }, + [form], + ); + const handleCodeChange = useCallback( + (event: ChangeEvent) => { + const code = event.target.value + .replaceAll(/[^a-z0-9]/gi, "") + .toUpperCase() + .slice(0, 8); + form.setFieldValue("code", code); + }, + [form], + ); + + const state = determineCheckIn(event, now); + const succeeded = event.attended || isSuccess; + const status = CHECKIN_WINDOW[state]; + + const StatusIcon = status.icon; + + return ( + + + + Check in + {event.name} + + +
+ + + {status.label} + +
+ + {succeeded && ( +
+
+ +
+
You're checked in!
+

+ Marked as attended for {event.name}. Re-submitting is safe — verify is idempotent. +

+
+ )} + + {!succeeded && state !== "open" && } + + {!succeeded && state === "open" && ( +
+
+ +

+ Scan the organizer's QR, or type the 8-character code they're showing. +

+
+ + {(field) => ( + + )} + + {isError && ( +
+ Code not recognized — check and try again. +
+ )} + + {(formState) => ( + + )} + +
+ )} + + +
+
+ ); +} diff --git a/src/components/app/dashboard-events.tsx b/src/components/app/dashboard-events.tsx new file mode 100644 index 00000000..58f0726f --- /dev/null +++ b/src/components/app/dashboard-events.tsx @@ -0,0 +1,858 @@ +import { + type LucideIcon, + Calendar, + Check, + Clock, + Info, + LayoutGrid, + List, + MapPin, + QrCode, + ScanLine, + Search, + Ticket, + User, + X, +} from "lucide-react"; +import { + type ChangeEvent, + type ComponentProps, + type MouseEvent, + type ReactNode, + useCallback, +} from "react"; + +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Separator } from "@/components/ui/separator"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { + type DashboardEvent, + type EventType, + type EventView, + type FullEvent, + EVENT_TYPE_CLASSES, + EVENT_TYPE_META, + EVENT_TYPES, + determineCheckIn, + fmtClock, + fmtDay, + isPastEvent, + monthDay, +} from "@/lib/dashboard-events"; +import { cn } from "@/lib/utils"; + +/// Types & interfaces + +export interface EventCallbacks { + onOpen?: (event: DashboardEvent) => void; + onRsvp?: (event: DashboardEvent, planned: boolean) => void; + onCheckin?: (event: DashboardEvent) => void; +} + +interface StateMeta { + label: string; + icon: LucideIcon; + className: string; +} + +/// Constants + +const STATUS_GREEN = "text-[#15a66e] bg-[#15a66e]/15 dark:text-[#3fd68c] dark:bg-[#3fd68c]/15"; +const STATUS_RED = "text-[#e13737] bg-[#e13737]/12 dark:text-[#ff6b6b] dark:bg-[#ff6b6b]/15"; +const STATUS_MUTED = "text-muted-foreground bg-muted"; +const STATUS_TEAL = "text-[#078c79] bg-brand-teal/15 dark:text-[#2fead0] dark:bg-brand-teal/15"; + +const STATE_ATTENDED: StateMeta = { label: "Attended", icon: Check, className: STATUS_GREEN }; +const STATE_MISSED: StateMeta = { label: "Missed", icon: X, className: STATUS_RED }; +const STATE_ENDED: StateMeta = { label: "Ended", icon: Clock, className: STATUS_MUTED }; +const STATE_GOING: StateMeta = { label: "Going", icon: Check, className: STATUS_GREEN }; +const STATE_OPEN: StateMeta = { label: "Open", icon: Ticket, className: STATUS_TEAL }; + +export const PILL_CLASS = + "h-auto gap-1.5 rounded-full px-2.5 py-1 text-[11.5px] font-bold [&>svg]:size-3.5!"; + +const VIEW_META: Record = { + calendar: { icon: Calendar, label: "Calendar" }, + grid: { icon: LayoutGrid, label: "Gallery" }, + list: { icon: List, label: "List" }, +}; + +const LONG_DATE_OPTIONS: Intl.DateTimeFormatOptions = { + weekday: "long", + month: "long", + day: "numeric", +}; + +/// Helpers + +function eventStateMeta(event: DashboardEvent, now: Date): StateMeta { + if (event.attended) return STATE_ATTENDED; + if (isPastEvent(event, now)) return event.planned ? STATE_MISSED : STATE_ENDED; + return event.planned ? STATE_GOING : STATE_OPEN; +} + +/// EventTypeChip + +interface EventTypeChipProps { + type: EventType; +} + +function EventTypeChip({ type }: Readonly) { + return ( + + + {EVENT_TYPE_META[type].label} + + ); +} + +/// TagPill + +interface TagPillProps { + children: ReactNode; +} + +function TagPill({ children }: Readonly) { + return ( + + {children} + + ); +} + +/// StatusBadge + +interface StatusBadgeProps { + event: DashboardEvent; + now: Date; +} + +function StatusBadge({ event, now }: Readonly) { + const meta = eventStateMeta(event, now); + const Icon = meta.icon; + return ( + + + {meta.label} + + ); +} + +/// EmptyState + +interface EmptyStateProps { + icon: LucideIcon; + title: string; + sub: string; + className?: string; +} + +export function EmptyState({ icon: Icon, title, sub, className }: Readonly) { + return ( +
+
+ +
+
{title}
+
{sub}
+
+ ); +} + +/// EventMeta + +interface EventMetaProps { + icon: LucideIcon; + children: ReactNode; +} + +function EventMeta({ icon: Icon, children }: Readonly) { + return ( + + + {children} + + ); +} + +/// DateBlock + +function DateBlock({ event }: Readonly<{ event: FullEvent }>) { + const { mon, day } = monthDay(event.start_at, event.timezone); + return ( +
+
+ {mon} +
+
+ {day} +
+
+ ); +} + +/// EventThumbnail + +interface EventThumbnailProps { + event: FullEvent; + className?: string; +} + +// At some point the svg will be replaced with the proper image stuff +function EventThumbnail({ event, className }: Readonly) { + const meta = EVENT_TYPE_META[event.type]; + const gradId = `evg-${event.id}`; + const dotId = `evd-${event.id}`; + return event.thumbnail ? ( +
+ +
+ ) : ( +
+ + + + + + + + + + + + + + + + {meta.label.toUpperCase()} + + +
+ + {meta.label} + +
+
+ ); +} + +/// EventActions + +interface EventActionsProps extends EventCallbacks { + event: DashboardEvent; + now: Date; + size?: ComponentProps["size"]; +} + +function EventActions({ event, now, onRsvp, onCheckin, size = "sm" }: Readonly) { + const state = determineCheckIn(event, now); + const past = isPastEvent(event, now); + + const handleCheckin = useCallback( + (e: MouseEvent) => { + e.stopPropagation(); + onCheckin?.(event); + }, + [onCheckin, event], + ); + const handleRsvp = useCallback( + (e: MouseEvent) => { + e.stopPropagation(); + onRsvp?.(event, true); + }, + [onRsvp, event], + ); + + return ( +
+ {state === "open" && !event.attended && ( + + )} + {!past && !event.attended && !event.planned && ( + + )} +
+ ); +} + +/// CancelRsvpButton + +interface CancelRsvpButtonProps { + event: DashboardEvent; + now: Date; + onRsvp?: (event: DashboardEvent, planned: boolean) => void; +} + +// Corner cancel control for the grid card thumbnail. Rows use GoingCancelPill. +function CancelRsvpButton({ event, now, onRsvp }: Readonly) { + const handleCancel = useCallback( + (e: MouseEvent) => { + e.stopPropagation(); + onRsvp?.(event, false); + }, + [onRsvp, event], + ); + + return isPastEvent(event, now) || event.attended || !event.planned ? undefined : ( + + ); +} + +/// GoingCancelPill + +function GoingCancelPill({ + event, + onRsvp, +}: Readonly<{ + event: DashboardEvent; + onRsvp?: (event: DashboardEvent, planned: boolean) => void; +}>) { + const handleCancel = useCallback( + (e: MouseEvent) => { + e.stopPropagation(); + onRsvp?.(event, false); + }, + [onRsvp, event], + ); + + return ( + + ); +} + +/// Clickable + +interface ClickableProps { + event: DashboardEvent; + onOpen?: (event: DashboardEvent) => void; + className: string; + children: ReactNode; +} + +function Clickable({ event, onOpen, className, children }: Readonly) { + const handleOpen = useCallback(() => { + onOpen?.(event); + }, [onOpen, event]); + + return ( +
+
+ ); +} + +/// EventCard & EventRow + +interface EventItemProps extends EventCallbacks { + event: DashboardEvent; + now: Date; +} + +export function EventCard({ event, now, onOpen, onRsvp, onCheckin }: Readonly) { + return ( + +
+ +
+ +
+
+ +
+
+
+ + {event.tags?.slice(0, 2).map((tag) => ( + {tag} + ))} +
+

{event.name}

+
+

{event.description}

+
+ + {fmtClock(event.start_at, event.timezone)}–{fmtClock(event.end_at, event.timezone)} + + {event.location} +
+
+ + +
+
+
+ ); +} + +function EventRow({ event, now, onOpen, onRsvp, onCheckin }: Readonly) { + const past = isPastEvent(event, now); + const showStatus = past || event.attended; + const showGoing = + !past && !event.attended && event.planned && determineCheckIn(event, now) !== "open"; + + return ( + + +
+
+ +

{event.name}

+
+
+ {fmtDay(event.start_at, event.timezone)} + {fmtClock(event.start_at, event.timezone)} + {event.location} +
+
+
+ + {showStatus && } + {showGoing && } +
+
+ ); +} + +/// StatTile + +interface StatTileProps { + icon: LucideIcon; + value: number | string; + label: string; + accentClassName?: string; +} + +export function StatTile({ icon: Icon, value, label, accentClassName }: Readonly) { + return ( +
+
+ +
+
+ {value} +
+
{label}
+
+ ); +} + +/// EventToolbar + +interface EventToolbarProps { + query: string; + onQueryChange: (value: string) => void; + type: "all" | EventType; + onTypeChange: (value: "all" | EventType) => void; + view: EventView; + onViewChange: (value: EventView) => void; + views: EventView[]; + searchPlaceholder?: string; +} + +export function EventToolbar({ + query, + onQueryChange, + type, + onTypeChange, + view, + onViewChange, + views, + searchPlaceholder = "Search events by name, location, or tag…", +}: Readonly) { + const handleQueryChange = useCallback( + (e: ChangeEvent) => { + onQueryChange(e.target.value); + }, + [onQueryChange], + ); + const handleTypeChange = useCallback( + (value: "all" | EventType | null) => { + if (value) onTypeChange(value); + }, + [onTypeChange], + ); + + return ( +
+
+
+ + +
+ + + + {views.map((key) => { + const ViewIcon = VIEW_META[key].icon; + return ( + + + {VIEW_META[key].label} + + ); + })} + + +
+
+ ); +} + +/// EventResults + +interface EventResultsProps { + events: DashboardEvent[]; + view: EventView; + now: Date; + onOpen: (event: DashboardEvent) => void; + onRsvp: (event: DashboardEvent, planned: boolean) => void; + onCheckin: (event: DashboardEvent) => void; + emptyTitle?: string; + emptySub?: string; +} + +export function EventResults({ + events, + view, + now, + onOpen, + onRsvp, + onCheckin, + emptyTitle = "No upcoming events match", + emptySub = "Try a different type or clear the search.", +}: Readonly) { + if (events.length === 0) { + return ( + + ); + } + + if (view === "grid") { + return ( +
+ {events.map((event) => ( + + ))} +
+ ); + } + + return ( +
+
+ {events.map((event) => ( + + ))} +
+
+ ); +} + +/// DetailTile + +interface DetailTileProps { + icon: LucideIcon; + label: string; + children: ReactNode; +} + +function DetailTile({ icon: Icon, label, children }: Readonly) { + return ( +
+ +
+
+ {label} +
+
{children}
+
+
+ ); +} + +/// EventDetailDialog + +interface EventDetailDialogProps { + event: DashboardEvent; + now: Date; + open: boolean; + onOpenChange: (open: boolean) => void; + canManage: boolean; + organizerName?: string; + onRsvp: (event: DashboardEvent, planned: boolean) => void; + onCheckin: (event: DashboardEvent) => void; + onManageAttendance?: (event: DashboardEvent) => void; +} + +export function EventDetailDialog({ + event, + now, + open, + onOpenChange, + canManage, + organizerName, + onRsvp, + onCheckin, + onManageAttendance, +}: Readonly) { + const handleManage = useCallback(() => { + onManageAttendance?.(event); + }, [onManageAttendance, event]); + const handleCheckin = useCallback(() => { + onCheckin(event); + }, [onCheckin, event]); + const handleRsvpYes = useCallback(() => { + onRsvp(event, true); + onOpenChange(false); + }, [onRsvp, event, onOpenChange]); + const handleRsvpNo = useCallback(() => { + onRsvp(event, false); + onOpenChange(false); + }, [onRsvp, event, onOpenChange]); + + const meta = EVENT_TYPE_META[event.type]; + const state = determineCheckIn(event, now); + const past = isPastEvent(event, now); + const organizer = event.creator_id ? (organizerName ?? "…") : "Unknown organizer"; + + return ( + + + + {event.name} + + {meta.label} · organized by {organizer} + + + +
+ +
+ +
+ + + {event.tags?.map((tag) => ( + {tag} + ))} +
+ +
+ + {fmtDay(event.start_at, event.timezone, LONG_DATE_OPTIONS)} + + + {fmtClock(event.start_at, event.timezone)} - {fmtClock(event.end_at, event.timezone)} + + + {event.location} + + + {organizer} + +
+ + {!event.creator_id && ( +
+ + + This event's creator was removed — organizer is unknown. + +
+ )} + + + +

{event.description}

+ + + {!past && !event.attended && event.planned ? ( + + ) : ( + + )} +
+ {canManage && ( + + )} + {state === "open" && !event.attended && ( + + )} + {!past && !event.attended && !event.planned && ( + + )} +
+
+
+
+ ); +} diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx new file mode 100644 index 00000000..b20959dd --- /dev/null +++ b/src/components/ui/badge.tsx @@ -0,0 +1,52 @@ +import { mergeProps } from "@base-ui/react/merge-props" +import { useRender } from "@base-ui/react/use-render" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", + secondary: + "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80", + destructive: + "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20", + outline: + "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground", + ghost: + "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50", + link: "text-primary underline-offset-4 hover:underline", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +function Badge({ + className, + variant = "default", + render, + ...props +}: useRender.ComponentProps<"span"> & VariantProps) { + return useRender({ + defaultTagName: "span", + props: mergeProps<"span">( + { + className: cn(badgeVariants({ variant }), className), + }, + props + ), + render, + state: { + slot: "badge", + variant, + }, + }) +} + +export { Badge, badgeVariants } diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx index 5dea05e8..60bb92b7 100644 --- a/src/components/ui/button.tsx +++ b/src/components/ui/button.tsx @@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" const buttonVariants = cva( - "group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 hover:not-aria-[haspopup]:-translate-y-px active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { variants: { variant: { diff --git a/src/components/ui/carousel.tsx b/src/components/ui/carousel.tsx index cf22cd28..6eeca44d 100644 --- a/src/components/ui/carousel.tsx +++ b/src/components/ui/carousel.tsx @@ -160,7 +160,11 @@ function CarouselContent({ className, ...props }: React.ComponentProps<"div">) { const { carouselRef, orientation } = useCarouselApi() return ( -
+
+} + +function DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) { + return +} + +function DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) { + return +} + +function DropdownMenuContent({ + align = "start", + alignOffset = 0, + side = "bottom", + sideOffset = 4, + className, + ...props +}: MenuPrimitive.Popup.Props & + Pick< + MenuPrimitive.Positioner.Props, + "align" | "alignOffset" | "side" | "sideOffset" + >) { + return ( + + + + + + ) +} + +function DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) { + return +} + +function DropdownMenuLabel({ + className, + inset, + ...props +}: MenuPrimitive.GroupLabel.Props & { + inset?: boolean +}) { + return ( + + ) +} + +function DropdownMenuItem({ + className, + inset, + variant = "default", + ...props +}: MenuPrimitive.Item.Props & { + inset?: boolean + variant?: "default" | "destructive" +}) { + return ( + + ) +} + +function DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) { + return +} + +function DropdownMenuSubTrigger({ + className, + inset, + children, + ...props +}: MenuPrimitive.SubmenuTrigger.Props & { + inset?: boolean +}) { + return ( + + {children} + + + ) +} + +function DropdownMenuSubContent({ + align = "start", + alignOffset = -3, + side = "right", + sideOffset = 0, + className, + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function DropdownMenuCheckboxItem({ + className, + children, + checked, + inset, + ...props +}: MenuPrimitive.CheckboxItem.Props & { + inset?: boolean +}) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) { + return ( + + ) +} + +function DropdownMenuRadioItem({ + className, + children, + inset, + ...props +}: MenuPrimitive.RadioItem.Props & { + inset?: boolean +}) { + return ( + + + + + + + {children} + + ) +} + +function DropdownMenuSeparator({ + className, + ...props +}: MenuPrimitive.Separator.Props) { + return ( + + ) +} + +function DropdownMenuShortcut({ + className, + ...props +}: React.ComponentProps<"span">) { + return ( + + ) +} + +export { + DropdownMenu, + DropdownMenuPortal, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuLabel, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuSub, + DropdownMenuSubTrigger, + DropdownMenuSubContent, +} diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 00000000..4f65961b --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,23 @@ +import { Separator as SeparatorPrimitive } from "@base-ui/react/separator" + +import { cn } from "@/lib/utils" + +function Separator({ + className, + orientation = "horizontal", + ...props +}: SeparatorPrimitive.Props) { + return ( + + ) +} + +export { Separator } diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx new file mode 100644 index 00000000..cfeb33d9 --- /dev/null +++ b/src/components/ui/sidebar.tsx @@ -0,0 +1,721 @@ +"use client" + +import * as React from "react" +import { mergeProps } from "@base-ui/react/merge-props" +import { useRender } from "@base-ui/react/use-render" +import { cva, type VariantProps } from "class-variance-authority" + +import { useIsMobile } from "@/hooks/use-mobile" +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Separator } from "@/components/ui/separator" +import { + Sheet, + SheetContent, + SheetDescription, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import { Skeleton } from "@/components/ui/skeleton" +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { PanelLeftIcon } from "lucide-react" + +const SIDEBAR_COOKIE_NAME = "sidebar_state" +const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 +const SIDEBAR_WIDTH = "16rem" +const SIDEBAR_WIDTH_MOBILE = "18rem" +const SIDEBAR_WIDTH_ICON = "3rem" +const SIDEBAR_KEYBOARD_SHORTCUT = "b" + +type SidebarContextProps = { + state: "expanded" | "collapsed" + open: boolean + setOpen: (open: boolean) => void + openMobile: boolean + setOpenMobile: (open: boolean) => void + isMobile: boolean + toggleSidebar: () => void +} + +const SidebarContext = React.createContext(null) + +function useSidebar() { + const context = React.useContext(SidebarContext) + if (!context) { + throw new Error("useSidebar must be used within a SidebarProvider.") + } + + return context +} + +function SidebarProvider({ + defaultOpen = true, + open: openProp, + onOpenChange: setOpenProp, + className, + style, + children, + ...props +}: React.ComponentProps<"div"> & { + defaultOpen?: boolean + open?: boolean + onOpenChange?: (open: boolean) => void +}) { + const isMobile = useIsMobile() + const [openMobile, setOpenMobile] = React.useState(false) + + // This is the internal state of the sidebar. + // We use openProp and setOpenProp for control from outside the component. + const [_open, _setOpen] = React.useState(defaultOpen) + const open = openProp ?? _open + const setOpen = React.useCallback( + (value: boolean | ((value: boolean) => boolean)) => { + const openState = typeof value === "function" ? value(open) : value + if (setOpenProp) { + setOpenProp(openState) + } else { + _setOpen(openState) + } + + // This sets the cookie to keep the sidebar state. + document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}` + }, + [setOpenProp, open] + ) + + // Helper to toggle the sidebar. + const toggleSidebar = React.useCallback(() => { + return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open) + }, [isMobile, setOpen, setOpenMobile]) + + // Adds a keyboard shortcut to toggle the sidebar. + React.useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if ( + event.key === SIDEBAR_KEYBOARD_SHORTCUT && + (event.metaKey || event.ctrlKey) + ) { + event.preventDefault() + toggleSidebar() + } + } + + globalThis.addEventListener("keydown", handleKeyDown) + return () => globalThis.removeEventListener("keydown", handleKeyDown) + }, [toggleSidebar]) + + // We add a state so that we can do data-state="expanded" or "collapsed". + // This makes it easier to style the sidebar with Tailwind classes. + const state = open ? "expanded" : "collapsed" + + const contextValue = React.useMemo( + () => ({ + state, + open, + setOpen, + isMobile, + openMobile, + setOpenMobile, + toggleSidebar, + }), + [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar] + ) + + return ( + +
+ {children} +
+
+ ) +} + +function Sidebar({ + side = "left", + variant = "sidebar", + collapsible = "offcanvas", + className, + children, + dir, + ...props +}: React.ComponentProps<"div"> & { + side?: "left" | "right" + variant?: "sidebar" | "floating" | "inset" + collapsible?: "offcanvas" | "icon" | "none" +}) { + const { isMobile, state, openMobile, setOpenMobile } = useSidebar() + + if (collapsible === "none") { + return ( +
+ {children} +
+ ) + } + + if (isMobile) { + return ( + + + + Sidebar + Displays the mobile sidebar. + +
{children}
+
+
+ ) + } + + return ( +
+
+ +
+ ) +} + +function SidebarTrigger({ + className, + onClick, + ...props +}: React.ComponentProps) { + const { toggleSidebar } = useSidebar() + + return ( + + ) +} + +function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { + const { toggleSidebar } = useSidebar() + + return ( + + +
+
+ +
+
+ ); +} + +function getRosterStatus(member: AttendanceMember): RosterStatus { + if (member.attended) return member.planned ? "checked_in" : "walk_in"; + return member.planned ? "expected" : "no_show"; +} + +function RosterRow({ + disabled, + member, + onUndo, +}: Readonly<{ + disabled: boolean; + member: AttendanceMember; + onUndo: (memberId: string) => void; +}>) { + const handleUndo = useCallback(() => { + onUndo(member.id); + }, [member.id, onUndo]); + + const status = ROSTER_STATUS[getRosterStatus(member)]; + const initials = + member.name + .match(/\S+/g) + ?.slice(0, 2) + .map((part) => part[0]) + .join("") + .toUpperCase() ?? "··"; + + const StatusIcon = status.icon; + + return ( +
+
+ {initials} +
+
+
{member.name}
+
+ + + {status.label} + + {member.attended && ( + + } + title="Member actions" + aria-label="Member actions" + > + + + + + + Undo check-in + + + + )} +
+ ); +} + +function DashboardEvents() { + const queryClient = useQueryClient(); + + const [now] = useState(() => new Date()); + const [query, setQuery] = useState(""); + const [type, setType] = useState<"all" | EventType>("all"); + const [view, setView] = useState("calendar"); + const [detail, setDetail] = useState(); + const [checkin, setCheckin] = useState(); + const [roster, setRoster] = useState(); + const [rosterTab, setRosterTab] = useState<"qr" | "roster">("qr"); + const [copied, setCopied] = useState(false); + + const { data: events } = useQuery(eventsListQueryOptions); + const { data: me } = useQuery(meQueryOptions); + const { data: plannedEvents } = useQuery(plannedEventsQueryOptions); + const { data: attendedEvents } = useQuery(attendedEventsQueryOptions); + const creatorQuery = useQuery({ + ...memberQueryOptions(detail?.creator_id ?? ""), + enabled: !!detail?.creator_id, + }); + const codeQuery = useQuery({ + ...eventAttendanceCodeQueryOptions(roster?.id ?? ""), + enabled: !!roster && rosterTab === "qr", + }); + const rosterQuery = useQuery({ + ...eventAttendanceQueryOptions(roster?.id ?? ""), + enabled: !!roster && rosterTab === "roster", + }); + + const { mutate: joinMutate } = useMutation({ + mutationFn: async (eventId: string) => { + await axios.post<{ message: string }>(`${API_BASE_URL}/events/${eventId}/join`); + }, + onSuccess: () => { + toast.success("You're on the list! We'll see you there."); + return queryClient.invalidateQueries({ queryKey: plannedEventsQueryOptions.queryKey }); + }, + onError: () => toast.error("Couldn't RSVP. Please try again."), + }); + const { mutate: removeMutate, isPending: isRemoving } = useMutation({ + mutationFn: async (memberId: string) => { + await axios.delete(`${API_BASE_URL}/events/${roster?.id ?? ""}/attendance/${memberId}`); + }, + onSuccess: () => { + toast.success("Check-in undone."); + return queryClient.invalidateQueries({ + queryKey: eventAttendanceQueryOptions(roster?.id ?? "").queryKey, + }); + }, + }); + + const handleRsvp = useCallback( + (event: DashboardEvent, planned: boolean) => { + if (planned) { + joinMutate(event.id); + return; + } + queryClient.setQueryData(plannedEventsQueryOptions.queryKey, (old) => + (old ?? []).filter((item) => item.id !== event.id), + ); + toast.success("RSVP cancelled."); + }, + [joinMutate, queryClient], + ); + const invalidateAttended = useCallback( + () => queryClient.invalidateQueries({ queryKey: attendedEventsQueryOptions.queryKey }), + [queryClient], + ); + + const openCheckinFromDetail = useCallback((event: DashboardEvent) => { + setDetail(undefined); + setCheckin(event); + }, []); + const openRosterFromDetail = useCallback((event: DashboardEvent) => { + setDetail(undefined); + setRosterTab("qr"); + setCopied(false); + setRoster(event); + }, []); + const closeDetail = useCallback((open: boolean) => { + if (!open) setDetail(undefined); + }, []); + const closeCheckin = useCallback((open: boolean) => { + if (!open) setCheckin(undefined); + }, []); + const closeRoster = useCallback((open: boolean) => { + if (!open) setRoster(undefined); + }, []); + + const code = (codeQuery.data?.code ?? "").slice(0, 8); + const copyCode = useCallback(() => { + void navigator.clipboard.writeText(code); + setCopied(true); + setTimeout(() => { + setCopied(false); + }, 1800); + }, [code]); + + const dashboardEvents = useMemo( + () => + (events ?? []).map((event) => + mergeDashboardEvent( + event, + plannedEvents?.has(event.id) ?? false, + attendedEvents?.has(event.id) ?? false, + ), + ), + [events, plannedEvents, attendedEvents], + ); + const upcoming = useMemo( + () => filterEvents(dashboardEvents, type, query).filter((event) => !isPastEvent(event, now)), + [dashboardEvents, type, query, now], + ); + const checkInOpen = useMemo( + () => + dashboardEvents + .filter((event) => determineCheckIn(event, now) === "open" && !event.attended) + .toSorted((a, b) => a.start_at.localeCompare(b.start_at)), + [dashboardEvents, now], + ); + + const nextCheckIn = checkInOpen.at(0); + const handleStripCheckin = useCallback(() => { + if (nextCheckIn) setCheckin(nextCheckIn); + }, [nextCheckIn]); + const handleStripMore = useCallback(() => { + const second = checkInOpen.at(1); + if (second) setDetail(second); + }, [checkInOpen]); + + const organizerName = detail?.creator_id ? creatorQuery.data?.name : undefined; + const canManageDetail = + !!detail && + !!me && + (me.roles.includes("admin") || me.roles.includes("leads") || detail.creator_id === me.id); + + const rosterMembers = rosterQuery.data?.data ?? []; + const plannedCount = rosterMembers.filter((member) => member.planned).length; + const attendedCount = rosterMembers.filter((member) => member.attended).length; + const checkIn = roster ? determineCheckIn(roster, now) : "ended"; + const windowLabel = CHECK_IN_WINDOW_LABEL[checkIn]; + + const WindowIcon = checkIn === "open" ? LockOpen : Lock; + + return ( +
+ {nextCheckIn && ( +
+ +
+
+ + + + + + Check-in open + +
+
+
+ +

{nextCheckIn.name}

+
+
+ + + {nextCheckIn.location} + + + + Closes at {fmtClock(nextCheckIn.end_at, nextCheckIn.timezone)} + +
+
+
+ {checkInOpen.length > 1 && ( + + )} + +
+
+
+ )} + + + + {view === "calendar" ? ( + + ) : ( + <> +
+

+ Upcoming events +

+ +

+ {String(upcoming.length)} event{upcoming.length === 1 ? "" : "s"} scheduled +

+
+ + + )} + + {detail && ( + + )} + + {checkin && ( + + )} + + {roster && ( + + + + Attendance + {roster.name} + + + + + + Check-in QR + + + Roster · {String(rosterMembers.length)} + + + + + + + {windowLabel} + + +
+ + + QR preview unavailable + +
+ +
+
+ {code ? `${code.slice(0, 4)} · ${code.slice(4)}` : "—— · ——"} +
+
+ Attendees submit these 8 characters +
+
+ +
+ +

+ Project this code at the door. The window opens 1 hour before start and closes + at {fmtClock(roster.end_at, roster.timezone)}. +

+
+
+ + +
+
+
+ {String(plannedCount)} +
+
+ Planned (RSVP'd) +
+
+
+
+ {String(attendedCount)} +
+
Attended
+
+
+
+ {rosterQuery.isPending && ( +

+ Loading roster… +

+ )} + {!rosterQuery.isPending && rosterMembers.length === 0 && ( +

+ No attendees yet. +

+ )} + {rosterMembers.map((member) => ( + + ))} +
+

+ Undo clears a member's attended flag but keeps their RSVP — for correcting a + mistaken check-in. +

+
+
+
+
+ )} +
+ ); +} diff --git a/src/routes/dashboard/events_.past.tsx b/src/routes/dashboard/events_.past.tsx new file mode 100644 index 00000000..17a57935 --- /dev/null +++ b/src/routes/dashboard/events_.past.tsx @@ -0,0 +1,218 @@ +import { + attendedEventsQueryOptions, + eventsListQueryOptions, + plannedEventsQueryOptions, +} from "./index"; + +import { queryOptions, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { createFileRoute } from "@tanstack/react-router"; +import axios from "axios"; +import { Check, Clock } from "lucide-react"; +import { useCallback, useMemo, useState } from "react"; +import { toast } from "sonner"; + +import { CheckInDialog } from "@/components/app/check-in-dialog"; +import { + EventDetailDialog, + EventResults, + EventToolbar, + StatTile, +} from "@/components/app/dashboard-events"; +import { + type DashboardEvent, + type EventType, + type EventView, + type FullEvent, + filterEvents, + isPastEvent, + mergeDashboardEvent, +} from "@/lib/dashboard-events"; + +export const Route = createFileRoute("/dashboard/events_/past")({ + component: DashboardPastEvents, + staticData: { area: "Member", title: "Past events", sub: "Your attendance history" }, + loader: async ({ context: { queryClient } }) => { + await queryClient.prefetchQuery(eventsListQueryOptions); + await queryClient.prefetchQuery(plannedEventsQueryOptions); + await queryClient.prefetchQuery(attendedEventsQueryOptions); + }, +}); + +/// Constants + +const API_BASE_URL = + (import.meta.env.VITE_API_URL as string | undefined) || "http://localhost:8000"; +const PAST_VIEWS: EventView[] = ["list", "grid"]; + +const SHARED_QUERY_OPTIONS = { + staleTime: 60_000, + retry: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, +} as const; + +/// Tanstack Query options + +const memberQueryOptions = (memberId: string) => + queryOptions({ + queryKey: ["members", memberId], + queryFn: async () => { + const { data } = await axios.get<{ id: string; name: string }>( + `${API_BASE_URL}/members/${memberId}`, + ); + return data; + }, + ...SHARED_QUERY_OPTIONS, + }); + +function DashboardPastEvents() { + const queryClient = useQueryClient(); + + const [now] = useState(() => new Date()); + const [query, setQuery] = useState(""); + const [type, setType] = useState<"all" | EventType>("all"); + const [view, setView] = useState("list"); + const [detail, setDetail] = useState(); + const [checkin, setCheckin] = useState(); + + const { data: events } = useQuery(eventsListQueryOptions); + const { data: plannedEvents } = useQuery(plannedEventsQueryOptions); + const { data: attendedEvents } = useQuery(attendedEventsQueryOptions); + const creatorQuery = useQuery({ + ...memberQueryOptions(detail?.creator_id ?? ""), + enabled: !!detail?.creator_id, + }); + + const { mutate: joinMutate } = useMutation({ + mutationFn: async (eventId: string) => { + await axios.post<{ message: string }>(`${API_BASE_URL}/events/${eventId}/join`); + }, + onSuccess: () => { + toast.success("You're on the list! We'll see you there."); + return queryClient.invalidateQueries({ queryKey: plannedEventsQueryOptions.queryKey }); + }, + onError: () => toast.error("Couldn't RSVP. Please try again."), + }); + + const dashboardEvents = useMemo( + () => + (events ?? []).map((event) => + mergeDashboardEvent( + event, + plannedEvents?.has(event.id) ?? false, + attendedEvents?.has(event.id) ?? false, + ), + ), + [events, plannedEvents, attendedEvents], + ); + const past = useMemo( + () => + filterEvents(dashboardEvents, type, query) + .filter((event) => isPastEvent(event, now)) + .toReversed(), + [dashboardEvents, type, query, now], + ); + + const handleRsvp = useCallback( + (event: DashboardEvent, planned: boolean) => { + if (planned) { + joinMutate(event.id); + return; + } + queryClient.setQueryData(plannedEventsQueryOptions.queryKey, (old) => + (old ?? []).filter((item) => item.id !== event.id), + ); + toast.success("RSVP cancelled."); + }, + [joinMutate, queryClient], + ); + const invalidateAttended = useCallback( + () => queryClient.invalidateQueries({ queryKey: attendedEventsQueryOptions.queryKey }), + [queryClient], + ); + const closeDetail = useCallback((open: boolean) => { + if (!open) setDetail(undefined); + }, []); + const closeCheckin = useCallback((open: boolean) => { + if (!open) setCheckin(undefined); + }, []); + const openCheckinFromDetail = useCallback((event: DashboardEvent) => { + setDetail(undefined); + setCheckin(event); + }, []); + + const attendedCount = past.filter((event) => event.attended).length; + const organizerName = detail?.creator_id ? creatorQuery.data?.name : undefined; + + return ( +
+
+ + +
+ + + +
+

Past events

+ +

+ {String(past.length)} event{past.length === 1 ? "" : "s"} · attendance history +

+
+ + + {detail && ( + + )} + + {checkin && ( + + )} +
+ ); +} diff --git a/src/routes/dashboard/index.tsx b/src/routes/dashboard/index.tsx new file mode 100644 index 00000000..3700ff42 --- /dev/null +++ b/src/routes/dashboard/index.tsx @@ -0,0 +1,478 @@ +import { type ClientMember, ROLE_META, ROLES_BY_RANK } from "./route"; + +import { queryOptions, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; +import { createFileRoute, Link, useNavigate } from "@tanstack/react-router"; +import axios from "axios"; +import { + ArrowRight, + Calendar, + Check, + Clock, + Folder, + MapPin, + ScanLine, + Shield, + Ticket, +} from "lucide-react"; +import { useCallback, useMemo, useState } from "react"; +import { toast } from "sonner"; + +import { CheckInDialog } from "@/components/app/check-in-dialog"; +import { EventCard, StatTile } from "@/components/app/dashboard-events"; +import { Button } from "@/components/ui/button"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel"; +import { Skeleton } from "@/components/ui/skeleton"; +import { + type DashboardEvent, + type FullEvent, + type KanaePage, + EVENT_TYPE_CLASSES, + EVENT_TYPE_META, + determineCheckIn, + fmtClock, + fmtDay, + isPastEvent, + mergeDashboardEvent, + monthDay, +} from "@/lib/dashboard-events"; +import { cn } from "@/lib/utils"; + +export const Route = createFileRoute("/dashboard/")({ + component: DashboardHome, + staticData: { area: "Member", title: "Dashboard", home: true }, + loader: async ({ context: { queryClient } }) => { + await queryClient.prefetchQuery(eventsListQueryOptions); + await queryClient.prefetchQuery(meQueryOptions); + await queryClient.prefetchQuery(plannedEventsQueryOptions); + await queryClient.prefetchQuery(attendedEventsQueryOptions); + }, +}); + +/// Constants + +const API_BASE_URL = + (import.meta.env.VITE_API_URL as string | undefined) ?? "http://localhost:8000"; +const EVENTS_PAGE_SIZE = 50; +const SKELETON_TILES = ["a", "b", "c", "d"]; +const CAROUSEL_OPTS = { align: "start", dragFree: true } as const; +const CAROUSEL_NAV_CLASS = "static size-9 translate-0"; +const HERO_STYLE = { background: "linear-gradient(135deg, #084778 0%, #0a5a6e 60%, #078c79 130%)" }; +const HERO_META_CLASS = + "inline-flex items-center gap-1.5 text-[13.5px] font-semibold text-[#eaf6ff]/90"; +const PILL_CLASS = + "inline-flex items-center justify-center gap-1.75 rounded-full border border-white/25 bg-white/15 px-5.5 py-3 text-sm font-bold"; +const TEAL_BUTTON_CLASS = + "rounded-full bg-brand-teal font-bold text-primary hover:bg-brand-teal/85"; +const RAIL_CLASS = + "rounded-[20px] border border-border bg-card p-4 shadow-[0px_4px_14px_rgba(112,144,176,0.14)] dark:shadow-[0px_4px_14px_rgba(0,0,0,0.4)]"; + +const SHARED_QUERY_OPTIONS = { + staleTime: 60_000, + retry: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, +} as const; + +/// Tanstack Query options + +export const memberEventsQueryOptions = (filter: "attended" | "planned") => + queryOptions({ + queryKey: ["members", "me", "events", filter], + queryFn: async () => { + const { data } = await axios.get(`${API_BASE_URL}/members/me/events`, { + params: { [filter]: true }, + }); + return data; + }, + select: (events: FullEvent[]) => new Set(events.map((event) => event.id)), + ...SHARED_QUERY_OPTIONS, + }); + +export const eventsListQueryOptions = queryOptions({ + queryKey: ["events", "list", {}], + queryFn: async () => { + const fetchPage = (page: number) => + axios.get>(`${API_BASE_URL}/events`, { + params: { page, size: EVENTS_PAGE_SIZE }, + }); + const first = await fetchPage(1); + const events = [...first.data.data]; + const pending = Array.from( + { length: Math.ceil(first.data.total / EVENTS_PAGE_SIZE) - 1 }, + (_, index) => fetchPage(index + 2), + ); + for (const request of pending) { + const page = await request; + events.push(...page.data.data); + } + return events; + }, + ...SHARED_QUERY_OPTIONS, +}); + +export const meQueryOptions = queryOptions({ + queryKey: ["members", "me"], + queryFn: async () => { + const { data } = await axios.get(`${API_BASE_URL}/members/me`); + return data; + }, + ...SHARED_QUERY_OPTIONS, +}); + +export const plannedEventsQueryOptions = memberEventsQueryOptions("planned"); +export const attendedEventsQueryOptions = memberEventsQueryOptions("attended"); + +/// Helper functions + +function heroEyebrowText(live: boolean, planned: boolean) { + if (live) return "Happening now"; + if (planned) return "Your next event"; + return "Next up"; +} + +/// Route + +function DashboardHome() { + const navigate = useNavigate(); + const queryClient = useQueryClient(); + + const { data: events, isPending } = useQuery(eventsListQueryOptions); + const { data: me } = useQuery(meQueryOptions); + const { data: plannedEvents } = useQuery(plannedEventsQueryOptions); + const { data: attendedEvents } = useQuery(attendedEventsQueryOptions); + + const [now] = useState(() => new Date()); + const [checkinEvent, setCheckinEvent] = useState(); + + const { mutate: joinMutate } = useMutation({ + mutationFn: async (eventId: string) => { + await axios.post<{ message: string }>(`${API_BASE_URL}/events/${eventId}/join`); + }, + onSuccess: () => { + toast.success("You're on the list! We'll see you there."); + return queryClient.invalidateQueries({ queryKey: plannedEventsQueryOptions.queryKey }); + }, + onError: () => toast.error("Couldn't RSVP. Please try again."), + }); + + const handleRsvp = useCallback( + (event: DashboardEvent, planned: boolean) => { + if (planned) { + joinMutate(event.id); + return; + } + queryClient.setQueryData(plannedEventsQueryOptions.queryKey, (old) => + (old ?? []).filter((item) => item.id !== event.id), + ); + toast.success("RSVP cancelled."); + }, + [joinMutate, queryClient], + ); + const goToEvents = useCallback(() => { + navigate({ to: "/dashboard/events" }).catch(() => {}); + }, [navigate]); + const closeCheckin = useCallback((open: boolean) => { + if (!open) setCheckinEvent(undefined); + }, []); + const invalidateAttended = useCallback( + () => queryClient.invalidateQueries({ queryKey: attendedEventsQueryOptions.queryKey }), + [queryClient], + ); + + const { hero, heroDate, heroLive, heroEyebrow, myUpcoming, myRsvpsSub, rail, attendedCount } = + useMemo(() => { + const merged: DashboardEvent[] = (events ?? []).map((event) => + mergeDashboardEvent( + event, + plannedEvents?.has(event.id) ?? false, + attendedEvents?.has(event.id) ?? false, + ), + ); + const upcoming = merged + .toSorted((a, b) => a.start_at.localeCompare(b.start_at)) + .filter((event) => !isPastEvent(event, now)); + const live = upcoming.find( + (event) => determineCheckIn(event, now) === "open" && !event.attended, + ); + const heroEvent = live ?? upcoming.find((event) => event.planned) ?? upcoming.at(0); + const heroLive = heroEvent ? determineCheckIn(heroEvent, now) === "open" : false; + const planned = upcoming.filter((event) => event.planned); + const plural = planned.length === 1 ? "" : "s"; + return { + hero: heroEvent, + heroDate: heroEvent ? monthDay(heroEvent.start_at, heroEvent.timezone) : undefined, + heroLive, + heroEyebrow: heroEyebrowText(heroLive, heroEvent?.planned ?? false), + myUpcoming: planned, + myRsvpsSub: + planned.length > 0 + ? `${String(planned.length)} event${plural} you're going to` + : "Events you RSVP to land here", + rail: upcoming.filter((event) => event.id !== heroEvent?.id), + attendedCount: merged.filter((event) => event.attended).length, + }; + }, [events, plannedEvents, attendedEvents, now]); + + const handleHeroCheckin = useCallback(() => { + if (hero) setCheckinEvent(hero); + }, [hero]); + const handleHeroRsvp = useCallback(() => { + if (hero) handleRsvp(hero, true); + }, [hero, handleRsvp]); + + const role = ROLES_BY_RANK.find((item) => me?.roles.includes(item)); + + return isPending ? ( +
+ +
+ {SKELETON_TILES.map((id) => ( + + ))} +
+ +
+ ) : ( +
+ {hero ? ( +
+
+
+
+
+ {heroDate?.mon} +
+
+ {heroDate?.day} +
+
+ +
+
+ + {heroEyebrow} + + + + {EVENT_TYPE_META[hero.type].label} + +
+

{hero.name}

+
+ + + {fmtDay(hero.start_at, hero.timezone)} + + + + {fmtClock(hero.start_at, hero.timezone)}-{fmtClock(hero.end_at, hero.timezone)} + + + + {hero.location} + +
+
+ +
+ {heroLive && !hero.attended && ( + + )} + {hero.attended && ( +
+ + Attended +
+ )} + {hero.planned && !heroLive && !hero.attended && ( +
+ + You're going +
+ )} + {!hero.planned && !heroLive && !hero.attended && ( + + )} + + View details + + +
+
+
+ ) : ( +
+ +
No upcoming events
+

New events will appear here soon.

+
+ )} + +
+ + + + +
+ + +
+
+

My RSVPs

+ +

{myRsvpsSub}

+
+ {myUpcoming.length > 1 && ( +
+ + +
+ )} +
+ {myUpcoming.length === 0 ? ( +
+
+ +
+
No RSVPs yet
+
+ RSVP to an event below and it will show up here. +
+
+ ) : ( + + {myUpcoming.map((event) => ( + + + + ))} + + )} +
+ + +
+
+

+ Upcoming events +

+ +

Open across all SIGs

+
+
+
+
+ {rail.length === 0 ? ( +
+
+ +
+
Nothing scheduled
+
+ New events will appear here. +
+
+ ) : ( + + {rail.map((event) => ( + + + + ))} + + )} + +
+
+
+ + {checkinEvent && ( + + )} +
+ ); +} diff --git a/src/routes/dashboard/projects.tsx b/src/routes/dashboard/projects.tsx new file mode 100644 index 00000000..b734dc48 --- /dev/null +++ b/src/routes/dashboard/projects.tsx @@ -0,0 +1,25 @@ +import { createFileRoute } from "@tanstack/react-router"; +import { Folder } from "lucide-react"; + +export const Route = createFileRoute("/dashboard/projects")({ + component: ProjectsPage, + staticData: { + area: "Member", + title: "Projects", + sub: "Browse, join, and manage chapter projects", + }, +}); + +function ProjectsPage() { + return ( +
+
+ +
+

Projects are coming soon

+

+ The chapter projects experience for the member portal is still being built. +

+
+ ); +} diff --git a/src/routes/dashboard/route.tsx b/src/routes/dashboard/route.tsx new file mode 100644 index 00000000..92a13431 --- /dev/null +++ b/src/routes/dashboard/route.tsx @@ -0,0 +1,283 @@ +import { queryOptions, useQuery } from "@tanstack/react-query"; +import { createFileRoute, Link, Outlet, useLocation, useMatches } from "@tanstack/react-router"; +import axios from "axios"; +import { + type LucideIcon, + Calendar, + ChevronRight, + Folder, + History, + Home, + Settings, +} from "lucide-react"; +import { type CSSProperties, useCallback, useState } from "react"; + +import { Footer } from "@/components/app/footer"; +import { Avatar, AvatarFallback } from "@/components/ui/avatar"; +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarGroup, + SidebarGroupContent, + SidebarGroupLabel, + SidebarHeader, + SidebarInset, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarProvider, + SidebarTrigger, + useSidebar, +} from "@/components/ui/sidebar"; +import { cn } from "@/lib/utils"; + +export const Route = createFileRoute("/dashboard")({ + component: DashboardLayout, + loader: ({ context: { queryClient } }) => queryClient.prefetchQuery(meQueryOptions), +}); + +/// Types and Interfaces + +export type Role = "admin" | "leads" | "manager" | "root"; + +export interface ClientSession { + aal: "aal1" | "aal2"; + active: boolean; + authenticated_at: string; + issued_at: string; + expires_at: string; +} + +export interface ClientMember { + id: string; + name: string; + email: string; + display_name?: string | null; + created_at: string; + projects: unknown[]; + events: unknown[]; + roles: Role[]; + session: ClientSession; +} + +interface NavItem { + to: "/dashboard" | "/dashboard/events" | "/dashboard/events/past" | "/dashboard/projects"; + label: string; + icon: LucideIcon; + sub?: boolean; +} + +interface DashboardStaticData { + area?: string; + title?: string; + sub?: string; + home?: boolean; +} + +/// Constants + +const EMPTY_STATIC: DashboardStaticData = {}; +const GRID_GLYPH = ( + + + + + + +); +export const ROLE_META: Record = { + root: { label: "Root", rank: 4 }, + admin: { label: "Admin", rank: 3 }, + manager: { label: "Manager", rank: 2 }, + leads: { label: "Leads", rank: 1 }, +}; + +const NAV_ITEMS: NavItem[] = [ + { to: "/dashboard", label: "Dashboard", icon: Home }, + { to: "/dashboard/events", label: "Events", icon: Calendar }, + { to: "/dashboard/events/past", label: "Past events", icon: History, sub: true }, + { to: "/dashboard/projects", label: "Projects", icon: Folder }, +]; + +export const ROLES_BY_RANK: Role[] = ["root", "admin", "manager", "leads"]; + +const API_BASE_URL = + (import.meta.env.VITE_API_URL as string | undefined) || "http://localhost:8000"; + +const SIDEBAR_STYLE = { + "--sidebar-width": "16.5rem", + "--sidebar-width-icon": "3.5rem", +} as CSSProperties; + +/// Tanstack Query options + +const meQueryOptions = queryOptions({ + queryKey: ["members", "me"], + queryFn: async () => { + const { data } = await axios.get(`${API_BASE_URL}/members/me`); + return data; + }, + staleTime: 60_000, + retry: false, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + refetchOnMount: false, +}); + +/// Route-based components + +function SidebarNav({ pathname }: Readonly<{ pathname: string }>) { + const { setOpenMobile } = useSidebar(); + const closeMobile = useCallback(() => { + setOpenMobile(false); + }, [setOpenMobile]); + + return ( + + {NAV_ITEMS.map((item) => ( + + + + {item.label} + + } + /> + + ))} + + ); +} + +/// Route + +function DashboardLayout() { + const { data: me } = useQuery(meQueryOptions); + const { pathname } = useLocation(); + const meta = useMatches({ select: (matches) => matches.at(-1)?.staticData ?? EMPTY_STATIC }); + + const [collapsed, setCollapsed] = useState(false); + + const handleOpenChange = useCallback((open: boolean) => { + setCollapsed(!open); + }, []); + const toggleSidebar = useCallback(() => { + setCollapsed((value) => !value); + }, []); + + const access = ROLES_BY_RANK.find((role) => me?.roles.includes(role)); + const accessLabel = access ? ROLE_META[access].label : "Member"; + const initials = + me?.name + .match(/\S+/g) + ?.slice(0, 2) + .map((part) => part[0]) + .join("") + .toUpperCase() ?? "··"; + + const firstName = me?.name.match(/\S+/)?.[0]; + const welcome = firstName ? `Welcome back, ${firstName}!` : "Welcome back!"; + const heading = meta.home ? welcome : (meta.title ?? "Dashboard"); + const sub = meta.home ? `${accessLabel} · Computer Science & Engineering · UC Merced` : meta.sub; + + return ( + + + +
+ + + Member Portal + +
+
+ + + + + Member + + + + + + + + + + + + + + {initials} + + +
+ + {me?.name ?? "Member"} + + + {accessLabel} + {me?.display_name ? ` · ${me.display_name}` : ""} + +
+ +
+ } + /> + + + + + + +
+
+
+ + + {meta.area ?? "Member"} + + + + {meta.title ?? "Dashboard"} + +
+

+ {heading} +

+ + {sub &&

{sub}

} +
+ + +
+